Reloading breaks plugin

Discussion in 'Plugin Development' started by SaltyPotato, Jul 14, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    SaltyPotato

    Title explains it, by simply reloading the plugin breaks (Restarting the server doesn't work).

    I hope someone help:

    Code:
    package me.Endervines.PvP2;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.stream.Collectors;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.entity.EntityDamageByEntityEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.plugin.Plugin;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Main extends JavaPlugin implements Listener {
      
        File configFile;
        File whitelistFile;
        File worldsFile;
        FileConfiguration config;
        FileConfiguration whitelist;
        FileConfiguration worlds;
      
        @SuppressWarnings("unused")
        @Override
        public void onEnable() {
            if(!getDataFolder().exists())
            {
              getDataFolder().mkdir();
            }
            Bukkit.getServer().getPluginManager().registerEvents((Listener)this, (Plugin)this);
            configFile = new File(getDataFolder(), "config.yml");
            whitelistFile = new File(getDataFolder(), "whitelist.yml");
            worldsFile = new File(getDataFolder(), "worlds.yml");
           
            try {
                firstRun();
            } catch (Exception e) {
                e.printStackTrace();
            }
            List<String> stringList = whitelist.getStringList("Whitelist");
            List<String> stringList1 = worlds.getStringList("Worlds");
        }
        private void firstRun() throws Exception {
            if(!configFile.exists()){
                configFile.getParentFile().mkdirs();
                copy(getResource("config.yml"), configFile);
            }
            if(!whitelistFile.exists()){
                whitelistFile.getParentFile().mkdirs();
                copy(getResource("whitelist.yml"), whitelistFile);
            }
            if(!worldsFile.exists()){
                worldsFile.getParentFile().mkdirs();
                copy(getResource("worlds.yml"), worldsFile);
            }
        }
        private void copy(InputStream in, File file) {
            try {
                OutputStream out = new FileOutputStream(file);
                byte[] buf = new byte[1024];
                int len;
                while((len=in.read(buf))>0){
                    out.write(buf,0,len);
                }
                out.close();
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            config = new YamlConfiguration();
            whitelist = new YamlConfiguration();
            worlds = new YamlConfiguration();
            loadYamls();
        }
        public void saveYamls() {
            try {
                config.save(configFile);
                whitelist.save(whitelistFile);
                worlds.save(worldsFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
      
        public void loadYamls() {
            try {
                config.load(configFile);
                whitelist.load(whitelistFile);
                worlds.load(worldsFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
      
        @Override
        public void onDisable() {
        }
      
        @SuppressWarnings({ "unused", "rawtypes" })
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            Player player = (Player)sender;
            if (cmd.getName().equalsIgnoreCase("pvpwl")) {
                if (sender instanceof Player) {
                    List<?> Whitelist;
                    Iterator iterator;
                    if (args.length == 0) {
                        player.sendMessage("§e§m=========§cPvPWhitelist§e§m=========");
                        player.sendMessage("\u00a7c/pvpwl add: \u00a77Add an item to the list");
                        player.sendMessage("\u00a7c/pvpwl remove: \u00a77Remove an item from the list");
                        player.sendMessage("\u00a7c/pvpwl reload: \u00a77Reload the config");
                        player.sendMessage("\u00a7c/pvpwl info: \u00a77Displays plugin information");
                        player.sendMessage("§c/pvpwl list: §7Displays the item whitelist");
                        player.sendMessage("§c/pvpwl perms: §7Displays the permissions");
                        player.sendMessage("§e§m=========§cPvPWhitelist§e§m=========");
                        return true;
                    }
                    if (args[0].equalsIgnoreCase("add")) {
                        if (player.hasPermission("pvpwl.admin") || player.isOp()) {
                            Material mat = player.getItemInHand().getType();
                            List<String> stringList = whitelist.getStringList("Whitelist");
                            String material = mat.toString();
                          
                            if(stringList.contains(material)) {
                                player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("on-list").replaceAll("&", "\u00a7").replace("{item}", mat.toString()));
                            }
                            else {
                                stringList.add(material);
                                player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("added").replaceAll("&", "\u00a7").replace("{item}", mat.toString()));
                            }
                          
                            stringList.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
                            whitelist.set("Whitelist", (Object)stringList);
                            saveYamls();
                            return true;
                        }
                        player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("noperm").replaceAll("&", "\u00a7"));
                    }
                    if (args[0].equalsIgnoreCase("remove")) {
                        if (player.hasPermission("pvpwl.admin") || player.isOp()) {
                            Material mat = player.getItemInHand().getType();
                             if (whitelist.getStringList("Whitelist").contains(mat.toString())) {
                                List<?> stringList = whitelist.getStringList("Whitelist");
                                stringList.remove(mat.toString());
                                whitelist.set("Whitelist", (Object)stringList);
                                saveYamls();
                                player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("removed").replaceAll("&", "\u00a7").replace("{item}", mat.toString()));
                                return true;
                            }
                            player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("not-contain").replaceAll("&", "\u00a7"));
                            return true;
                        }
                        player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("noperm").replaceAll("&", "\u00a7"));
                        return true;
                    }
                    if (args[0].equalsIgnoreCase("reload") && (sender.hasPermission("pvpwl.admin") || player.isOp())) {
                        loadYamls();
                        player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("reloaded").replaceAll("&", "\u00a7"));
                        return true;
                    }
                    if (args[0].equalsIgnoreCase("info")) {
                        player.sendMessage("§e§m=========§cPvPWhitelist§e§m=========");
                        player.sendMessage("§cAuthor: §7Endervines");
                        player.sendMessage("§cVersion: §73.1 BETA");
                        player.sendMessage("§cPlugin Thread: §7https://www.spigotmc.org/resources/pvpwhitelist-item-whitelist.22779/");
                        player.sendMessage("§e§m=========§cPvPWhitelist§e§m=========");
                        return true;
                    }
                        if (args[0].equalsIgnoreCase("perms")) {
                            if (player.hasPermission("pvpwl.admin") || player.isOp()) {
                                player.sendMessage("§e§m=========§cPvPWhitelist§e§m=========");
                                player.sendMessage("§cpvpwl.admin: §7Access to the commands");
                                player.sendMessage("§cpvpwl.bypass: §7Bypasses the whitelist");
                                player.sendMessage("§e§m=========§cPvPWhitelist§e§m=========");
                            }
                            player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("noperm").replaceAll("&", "\u00a7"));
                            return true;
                        }
                        if (args[0].equalsIgnoreCase("list")) {
                            if (player.hasPermission("pvpwl.admin") || player.isOp()) {
                                player.sendMessage("§e§m=========§cPvPWhitelist§e§m=========");
                                for(String msg : whitelist.getStringList("Whitelist")) {
                                    player.sendMessage(ChatColor.translateAlternateColorCodes('&', msg));
                            }
                            player.sendMessage("§e§m=========§cPvPWhitelist§e§m=========");
                            return true;
                        }
                    }
                } else {
                    sender.sendMessage("Only players can do this!");
                    return true;
                }
            }
            return false;
        }
          
        @EventHandler
        public void hitEvent(EntityDamageByEntityEvent event) {
        Player player;
        if (event.getDamager() instanceof Player && (!(player = (Player)event.getDamager()).hasPermission("pvpwl.bypass") || player.isOp()) && player.getItemInHand().getType() != null) {
            Material mat = player.getItemInHand().getType();
            String m = mat.toString();
        if (!config.getBoolean("whitelist-couaants-as-blacklist")) {
         if (!whitelist.getStringList("Whitelist").contains(m)) {
            event.setCancelled(true);
            player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("hit").replaceAll("&", "\u00a7"));
        }
        } else {
            if (whitelist.getStringList("Whitelist").contains(m)) {
                event.setCancelled(true);
                player.sendMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("hit").replaceAll("&", "\u00a7"));
        }
        }
        }
        }
       
           
       
      
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent event) {
            @SuppressWarnings("unused")
            Player player = event.getPlayer();
            event.setJoinMessage(config.getString("prefix").replaceAll("&", "\u00a7") + config.getString("join").replaceAll("&", "\u00a7"));
        }
    }
    
    
     
  2. Offline

    shades161

    /reload will almost always break plugins. Its much safer to just stop and then start the server rather than actually reloading the server.
     
  3. Offline

    mine-care

    @shades161 it won't break them, it just disables them and re enables them after reloading their classes. Yes it has issues but that isn't so bad and does not cause problems in all plugins always.
    @SaltyPotato
    Could you please tell us what 'doesn't work' and 'breaks' mean?
     
    I Al Istannen likes this.
  4. Offline

    EmeraldRailsMC

    I believe there's a free plugin called PlugMan which can reload a single plugin, and some plugins have a command that reloads only that plugin.
     
  5. Offline

    shades161

    Yes, there is a plugin that does that, and some have commands to do it for that plugin only. However for plugins that are not designed to handle such an event can break. For example if players are online when the plugin or server is reloaded (when not designed to handle it) it may not register those players being online properly and functions can break.

    While yes it does just disable and then enable them, if can have issues if the plugin is not designed to handle it. Most plugins can deal with this, but certain plugins will not any they will "break", or in other terms, spam errors and interrupt certain operations or not register other things happening when they should.


    The safest way to deal with this is either stop the server, do whatever is needed, and then restart the server. It may cause players to lose playtime and be an annoyance but it prevents strange errors when reloading. Or you could get a plugin (like PluginManagerReloaded) that will completely disable and enable a plugin, not just reload it. This will help reduce errors and other weird issues.
     
  6. Offline

    mine-care

    Can you give me an example of that? Other than sockets left open as static fields and database connections I can't think of anything, and also I have not experienced this in my years of development which As you said, happends "almost always" :/ But at the end of the day, you should not avoid reloads because the plugin errors, but you should find a way to fix the problem. Errors are there to be fixed not to be hiden away or ignored because they serve the purpose of letting you know that something went horribly wrong which effectively affects the function of your plugin.
     
    bwfcwalshy likes this.
  7. Offline

    mythbusterma

    @mine-care

    They don't have to be static, anything that's left open can be an issue.
     
    mine-care and shades161 like this.
Thread Status:
Not open for further replies.

Share This Page