mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-11-04 03:03:43 +01:00 
			
		
		
		
	simplify config / multiple expiry tasks / block cache fix
This commit is contained in:
		@@ -71,6 +71,12 @@ import com.plotsquared.bukkit.uuid.LowerOfflineUUIDWrapper;
 | 
			
		||||
import com.plotsquared.bukkit.uuid.OfflineUUIDWrapper;
 | 
			
		||||
import com.plotsquared.bukkit.uuid.SQLUUIDHandler;
 | 
			
		||||
import com.sk89q.worldedit.WorldEdit;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.Chunk;
 | 
			
		||||
@@ -87,13 +93,6 @@ import org.bukkit.metadata.MetadataValue;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
import org.bukkit.plugin.java.JavaPlugin;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
 | 
			
		||||
 | 
			
		||||
    public static WorldEdit worldEdit;
 | 
			
		||||
@@ -136,7 +135,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
 | 
			
		||||
    public void log(String message) {
 | 
			
		||||
        try {
 | 
			
		||||
            message = C.color(message);
 | 
			
		||||
            if (!Settings.CONSOLE_COLOR) {
 | 
			
		||||
            if (!Settings.CHAT.CONSOLE_COLOR) {
 | 
			
		||||
                message = ChatColor.stripColor(message);
 | 
			
		||||
            }
 | 
			
		||||
            this.getServer().getConsoleSender().sendMessage(message);
 | 
			
		||||
@@ -242,7 +241,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
 | 
			
		||||
                                    case MINECART_MOB_SPAWNER:
 | 
			
		||||
                                    case MINECART_TNT:
 | 
			
		||||
                                    case BOAT: {
 | 
			
		||||
                                        if (!Settings.KILL_ROAD_VEHICLES) {
 | 
			
		||||
                                        if (!Settings.ENABLED_COMPONENTS.KILL_ROAD_VEHICLES) {
 | 
			
		||||
                                            continue;
 | 
			
		||||
                                        }
 | 
			
		||||
                                        com.intellectualcrafters.plot.object.Location location = BukkitUtil.getLocation(entity.getLocation());
 | 
			
		||||
@@ -309,7 +308,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
 | 
			
		||||
                                    case ZOMBIE:
 | 
			
		||||
                                    case SHULKER:
 | 
			
		||||
                                    default:
 | 
			
		||||
                                        if (!Settings.KILL_ROAD_MOBS) {
 | 
			
		||||
                                        if (!Settings.ENABLED_COMPONENTS.KILL_ROAD_MOBS) {
 | 
			
		||||
                                            continue;
 | 
			
		||||
                                        }
 | 
			
		||||
                                        Location location = entity.getLocation();
 | 
			
		||||
@@ -506,23 +505,23 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
 | 
			
		||||
    public UUIDHandlerImplementation initUUIDHandler() {
 | 
			
		||||
        boolean checkVersion = PS.get().checkVersion(getServerVersion(), 1, 7, 6);
 | 
			
		||||
        UUIDWrapper wrapper;
 | 
			
		||||
        if (Settings.OFFLINE_MODE) {
 | 
			
		||||
            if (Settings.UUID_LOWERCASE) {
 | 
			
		||||
        if (Settings.UUID.OFFLINE) {
 | 
			
		||||
            if (Settings.UUID.FORCE_LOWERCASE) {
 | 
			
		||||
                wrapper = new LowerOfflineUUIDWrapper();
 | 
			
		||||
            } else {
 | 
			
		||||
                wrapper = new OfflineUUIDWrapper();
 | 
			
		||||
            }
 | 
			
		||||
            Settings.OFFLINE_MODE = true;
 | 
			
		||||
            Settings.UUID.OFFLINE = true;
 | 
			
		||||
        } else if (checkVersion) {
 | 
			
		||||
            wrapper = new DefaultUUIDWrapper();
 | 
			
		||||
            Settings.OFFLINE_MODE = false;
 | 
			
		||||
            Settings.UUID.OFFLINE = false;
 | 
			
		||||
        } else {
 | 
			
		||||
            if (Settings.UUID_LOWERCASE) {
 | 
			
		||||
            if (Settings.UUID.FORCE_LOWERCASE) {
 | 
			
		||||
                wrapper = new LowerOfflineUUIDWrapper();
 | 
			
		||||
            } else {
 | 
			
		||||
                wrapper = new OfflineUUIDWrapper();
 | 
			
		||||
            }
 | 
			
		||||
            Settings.OFFLINE_MODE = true;
 | 
			
		||||
            Settings.UUID.OFFLINE = true;
 | 
			
		||||
        }
 | 
			
		||||
        if (!checkVersion) {
 | 
			
		||||
            PS.log(C.PREFIX + " &c[WARN] Titles are disabled - please update your version of Bukkit to support this feature.");
 | 
			
		||||
@@ -530,17 +529,17 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
 | 
			
		||||
        } else {
 | 
			
		||||
            AbstractTitle.TITLE_CLASS = new DefaultTitle_19();
 | 
			
		||||
            if (wrapper instanceof DefaultUUIDWrapper || wrapper.getClass() == OfflineUUIDWrapper.class && !Bukkit.getOnlineMode()) {
 | 
			
		||||
                Settings.TWIN_MODE_UUID = true;
 | 
			
		||||
                Settings.UUID.NATIVE_UUID_PROVIDER = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.OFFLINE_MODE) {
 | 
			
		||||
        if (Settings.UUID.OFFLINE) {
 | 
			
		||||
            PS.log(C.PREFIX
 | 
			
		||||
                    + " &6PlotSquared is using Offline Mode UUIDs either because of user preference, or because you are using an old version of "
 | 
			
		||||
                    + "Bukkit");
 | 
			
		||||
        } else {
 | 
			
		||||
            PS.log(C.PREFIX + " &6PlotSquared is using online UUIDs");
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.USE_SQLUUIDHANDLER) {
 | 
			
		||||
        if (Settings.UUID.USE_SQLUUIDHANDLER) {
 | 
			
		||||
            return new SQLUUIDHandler(wrapper);
 | 
			
		||||
        } else {
 | 
			
		||||
            return new FileUUIDHandler(wrapper);
 | 
			
		||||
@@ -594,7 +593,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
 | 
			
		||||
        World world = BukkitUtil.getWorld(worldName);
 | 
			
		||||
        if (world == null) {
 | 
			
		||||
            // create world
 | 
			
		||||
            ConfigurationSection worldConfig = PS.get().config.getConfigurationSection("worlds." + worldName);
 | 
			
		||||
            ConfigurationSection worldConfig = PS.get().worlds.getConfigurationSection("worlds." + worldName);
 | 
			
		||||
            String manager = worldConfig.getString("generator.plugin", "PlotSquared");
 | 
			
		||||
            SetupObject setup = new SetupObject();
 | 
			
		||||
            setup.plotManager = manager;
 | 
			
		||||
@@ -620,7 +619,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
 | 
			
		||||
            PS.get().loadWorld(worldName, (BukkitPlotGenerator) gen);
 | 
			
		||||
        } else if (gen != null) {
 | 
			
		||||
            PS.get().loadWorld(worldName, new BukkitPlotGenerator(worldName, gen));
 | 
			
		||||
        } else if (PS.get().config.contains("worlds." + worldName)) {
 | 
			
		||||
        } else if (PS.get().worlds.contains("worlds." + worldName)) {
 | 
			
		||||
            PS.get().loadWorld(worldName, null);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -661,7 +660,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ChatManager<?> initChatManager() {
 | 
			
		||||
        if (Settings.FANCY_CHAT) {
 | 
			
		||||
        if (Settings.CHAT.INTERACTIVE) {
 | 
			
		||||
            return new BukkitChatManager();
 | 
			
		||||
        } else {
 | 
			
		||||
            return new BukkitPlainChatManager();
 | 
			
		||||
 
 | 
			
		||||
@@ -266,14 +266,14 @@ public class DebugUUID extends SubCommand {
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (newWrapper instanceof OfflineUUIDWrapper) {
 | 
			
		||||
                    PS.get().config.set("UUID.force-lowercase", false);
 | 
			
		||||
                    PS.get().config.set("UUID.offline", true);
 | 
			
		||||
                    PS.get().worlds.set("UUID.force-lowercase", false);
 | 
			
		||||
                    PS.get().worlds.set("UUID.offline", true);
 | 
			
		||||
                } else if (newWrapper instanceof DefaultUUIDWrapper) {
 | 
			
		||||
                    PS.get().config.set("UUID.force-lowercase", false);
 | 
			
		||||
                    PS.get().config.set("UUID.offline", false);
 | 
			
		||||
                    PS.get().worlds.set("UUID.force-lowercase", false);
 | 
			
		||||
                    PS.get().worlds.set("UUID.offline", false);
 | 
			
		||||
                }
 | 
			
		||||
                try {
 | 
			
		||||
                    PS.get().config.save(PS.get().configFile);
 | 
			
		||||
                    PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
                } catch (IOException ignored) {
 | 
			
		||||
                    MainUtil.sendMessage(player, "Could not save configuration. It will need to be manual set!");
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -25,21 +25,21 @@ public abstract class APlotMeConnector {
 | 
			
		||||
 | 
			
		||||
    public void copyConfig(FileConfiguration plotConfig, String world, String actualWorldName) {
 | 
			
		||||
        int pathWidth = plotConfig.getInt("worlds." + world + ".PathWidth"); //
 | 
			
		||||
        PS.get().config.set("worlds." + actualWorldName + ".road.width", pathWidth);
 | 
			
		||||
        PS.get().worlds.set("worlds." + actualWorldName + ".road.width", pathWidth);
 | 
			
		||||
        int plotSize = plotConfig.getInt("worlds." + world + ".PlotSize"); //
 | 
			
		||||
        PS.get().config.set("worlds." + actualWorldName + ".plot.size", plotSize);
 | 
			
		||||
        PS.get().worlds.set("worlds." + actualWorldName + ".plot.size", plotSize);
 | 
			
		||||
        String wallBlock = plotConfig.getString("worlds." + world + ".WallBlockId"); //
 | 
			
		||||
        PS.get().config.set("worlds." + actualWorldName + ".wall.block", wallBlock);
 | 
			
		||||
        PS.get().worlds.set("worlds." + actualWorldName + ".wall.block", wallBlock);
 | 
			
		||||
        String floor = plotConfig.getString("worlds." + world + ".PlotFloorBlockId"); //
 | 
			
		||||
        PS.get().config.set("worlds." + actualWorldName + ".plot.floor", Collections.singletonList(floor));
 | 
			
		||||
        PS.get().worlds.set("worlds." + actualWorldName + ".plot.floor", Collections.singletonList(floor));
 | 
			
		||||
        String filling = plotConfig.getString("worlds." + world + ".PlotFillingBlockId"); //
 | 
			
		||||
        PS.get().config.set("worlds." + actualWorldName + ".plot.filling", Collections.singletonList(filling));
 | 
			
		||||
        PS.get().worlds.set("worlds." + actualWorldName + ".plot.filling", Collections.singletonList(filling));
 | 
			
		||||
        String road = plotConfig.getString("worlds." + world + ".RoadMainBlockId");
 | 
			
		||||
        PS.get().config.set("worlds." + actualWorldName + ".road.block", road);
 | 
			
		||||
        PS.get().worlds.set("worlds." + actualWorldName + ".road.block", road);
 | 
			
		||||
        int height = plotConfig.getInt("worlds." + world + ".RoadHeight"); //
 | 
			
		||||
        PS.get().config.set("worlds." + actualWorldName + ".road.height", height);
 | 
			
		||||
        PS.get().config.set("worlds." + actualWorldName + ".plot.height", height);
 | 
			
		||||
        PS.get().config.set("worlds." + actualWorldName + ".wall.height", height);
 | 
			
		||||
        PS.get().worlds.set("worlds." + actualWorldName + ".road.height", height);
 | 
			
		||||
        PS.get().worlds.set("worlds." + actualWorldName + ".plot.height", height);
 | 
			
		||||
        PS.get().worlds.set("worlds." + actualWorldName + ".wall.height", height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Location getPlotTopLocAbs(int path, int plot, PlotId plotId) {
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ public class ClassicPlotMeConnector extends APlotMeConnector {
 | 
			
		||||
                String con = plotConfig.getString("mySQLconn");
 | 
			
		||||
                return DriverManager.getConnection(con, user, password);
 | 
			
		||||
            } else {
 | 
			
		||||
                return new SQLite(dataFolder + File.separator + "plots.db").openConnection();
 | 
			
		||||
                return new SQLite(new File(dataFolder + File.separator + "plots.db")).openConnection();
 | 
			
		||||
            }
 | 
			
		||||
        } catch (SQLException | ClassNotFoundException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
@@ -64,7 +64,7 @@ public class ClassicPlotMeConnector extends APlotMeConnector {
 | 
			
		||||
        } else if (checkUUID2) {
 | 
			
		||||
            column = "ownerId";
 | 
			
		||||
        }
 | 
			
		||||
        boolean merge = !"plotme".equalsIgnoreCase(this.plugin) && Settings.CONVERT_PLOTME;
 | 
			
		||||
        boolean merge = !"plotme".equalsIgnoreCase(this.plugin) && Settings.ENABLED_COMPONENTS.PLOTME_CONVERTER;
 | 
			
		||||
        int missing = 0;
 | 
			
		||||
        while (resultSet.next()) {
 | 
			
		||||
            PlotId id = new PlotId(resultSet.getInt("idX"), resultSet.getInt("idZ"));
 | 
			
		||||
@@ -73,8 +73,8 @@ public class ClassicPlotMeConnector extends APlotMeConnector {
 | 
			
		||||
            if (!plots.containsKey(world)) {
 | 
			
		||||
                plots.put(world, new HashMap<PlotId, Plot>());
 | 
			
		||||
                if (merge) {
 | 
			
		||||
                    int plot = PS.get().config.getInt("worlds." + world + ".plot.size");
 | 
			
		||||
                    int path = PS.get().config.getInt("worlds." + world + ".road.width");
 | 
			
		||||
                    int plot = PS.get().worlds.getInt("worlds." + world + ".plot.size");
 | 
			
		||||
                    int path = PS.get().worlds.getInt("worlds." + world + ".road.width");
 | 
			
		||||
                    plotWidth.put(world, plot);
 | 
			
		||||
                    roadWidth.put(world, path);
 | 
			
		||||
                    merges.put(world, new HashMap<PlotId, boolean[]>());
 | 
			
		||||
 
 | 
			
		||||
@@ -144,7 +144,7 @@ public class LikePlotMeConverter {
 | 
			
		||||
            sendMessage(" - " + dbPrefix + "Plots");
 | 
			
		||||
            final Set<String> worlds = getPlotMeWorlds(plotConfig);
 | 
			
		||||
 | 
			
		||||
            if (Settings.CONVERT_PLOTME) {
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.PLOTME_CONVERTER) {
 | 
			
		||||
                sendMessage("Updating bukkit.yml");
 | 
			
		||||
                updateWorldYml("bukkit.yml");
 | 
			
		||||
                updateWorldYml("plugins/Multiverse-Core/worlds.yml");
 | 
			
		||||
@@ -153,7 +153,7 @@ public class LikePlotMeConverter {
 | 
			
		||||
                    try {
 | 
			
		||||
                        String actualWorldName = getWorld(world);
 | 
			
		||||
                        connector.copyConfig(plotConfig, world, actualWorldName);
 | 
			
		||||
                        PS.get().config.save(PS.get().configFile);
 | 
			
		||||
                        PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
                    } catch (IOException e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                        sendMessage("&c-- &lFailed to save configuration for world '" + world
 | 
			
		||||
@@ -166,7 +166,7 @@ public class LikePlotMeConverter {
 | 
			
		||||
            for (Entry<String, HashMap<PlotId, Plot>> entry : plots.entrySet()) {
 | 
			
		||||
                plotCount += entry.getValue().size();
 | 
			
		||||
            }
 | 
			
		||||
            if (!Settings.CONVERT_PLOTME) {
 | 
			
		||||
            if (!Settings.ENABLED_COMPONENTS.PLOTME_CONVERTER) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -181,30 +181,30 @@ public class LikePlotMeConverter {
 | 
			
		||||
                        String actualWorldName = getWorld(world);
 | 
			
		||||
                        String plotMeWorldName = world.toLowerCase();
 | 
			
		||||
                        Integer pathWidth = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".PathWidth"); //
 | 
			
		||||
                        PS.get().config.set("worlds." + world + ".road.width", pathWidth);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + world + ".road.width", pathWidth);
 | 
			
		||||
 | 
			
		||||
                        int pathHeight = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".RoadHeight", 64); //
 | 
			
		||||
                        PS.get().config.set("worlds." + world + ".road.height", pathHeight);
 | 
			
		||||
                        PS.get().config.set("worlds." + world + ".wall.height", pathHeight);
 | 
			
		||||
                        PS.get().config.set("worlds." + world + ".plot.height", pathHeight);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + world + ".road.height", pathHeight);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + world + ".wall.height", pathHeight);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + world + ".plot.height", pathHeight);
 | 
			
		||||
                        int plotSize = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".PlotSize", 32); //
 | 
			
		||||
                        PS.get().config.set("worlds." + world + ".plot.size", plotSize);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + world + ".plot.size", plotSize);
 | 
			
		||||
                        String wallblock = plotmeDgYml.getString("worlds." + plotMeWorldName + ".WallBlock", "44"); //
 | 
			
		||||
                        PS.get().config.set("worlds." + world + ".wall.block", wallblock);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + world + ".wall.block", wallblock);
 | 
			
		||||
                        String floor = plotmeDgYml.getString("worlds." + plotMeWorldName + ".PlotFloorBlock", "2"); //
 | 
			
		||||
                        PS.get().config.set("worlds." + world + ".plot.floor", Collections.singletonList(floor));
 | 
			
		||||
                        PS.get().worlds.set("worlds." + world + ".plot.floor", Collections.singletonList(floor));
 | 
			
		||||
                        String filling = plotmeDgYml.getString("worlds." + plotMeWorldName + ".FillBlock", "3"); //
 | 
			
		||||
                        PS.get().config.set("worlds." + world + ".plot.filling", Collections.singletonList(filling));
 | 
			
		||||
                        PS.get().worlds.set("worlds." + world + ".plot.filling", Collections.singletonList(filling));
 | 
			
		||||
                        String road = plotmeDgYml.getString("worlds." + plotMeWorldName + ".RoadMainBlock", "5");
 | 
			
		||||
                        PS.get().config.set("worlds." + world + ".road.block", road);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + world + ".road.block", road);
 | 
			
		||||
                        int height = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".RoadHeight"); //
 | 
			
		||||
                        if (height == 0) {
 | 
			
		||||
                            height = plotmeDgYml.getInt("worlds." + plotMeWorldName + ".GroundHeight", 64); //
 | 
			
		||||
                        }
 | 
			
		||||
                        PS.get().config.set("worlds." + actualWorldName + ".road.height", height);
 | 
			
		||||
                        PS.get().config.set("worlds." + actualWorldName + ".plot.height", height);
 | 
			
		||||
                        PS.get().config.set("worlds." + actualWorldName + ".wall.height", height);
 | 
			
		||||
                        PS.get().config.save(PS.get().configFile);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + actualWorldName + ".road.height", height);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + actualWorldName + ".plot.height", height);
 | 
			
		||||
                        PS.get().worlds.set("worlds." + actualWorldName + ".wall.height", height);
 | 
			
		||||
                        PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (IOException ignored) {}
 | 
			
		||||
            }
 | 
			
		||||
@@ -267,7 +267,7 @@ public class LikePlotMeConverter {
 | 
			
		||||
            });
 | 
			
		||||
            sendMessage("Saving configuration...");
 | 
			
		||||
            try {
 | 
			
		||||
                PS.get().config.save(PS.get().configFile);
 | 
			
		||||
                PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
            } catch (IOException ignored) {
 | 
			
		||||
                sendMessage(" - &cFailed to save configuration.");
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -37,9 +37,9 @@ public class PlotMeConnector_017 extends APlotMeConnector {
 | 
			
		||||
            } else {
 | 
			
		||||
                File file = new File(dataFolder + File.separator + "plotmecore.db");
 | 
			
		||||
                if (file.exists()) {
 | 
			
		||||
                    return new SQLite(dataFolder + File.separator + "plotmecore.db").openConnection();
 | 
			
		||||
                    return new SQLite(file).openConnection();
 | 
			
		||||
                }
 | 
			
		||||
                return new SQLite(dataFolder + File.separator + "plots.db").openConnection();
 | 
			
		||||
                return new SQLite(new File(dataFolder + File.separator + "plots.db")).openConnection();
 | 
			
		||||
            }
 | 
			
		||||
        } catch (SQLException | ClassNotFoundException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
@@ -67,15 +67,15 @@ public class PlotMeConnector_017 extends APlotMeConnector {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        boolean checkUUID = DBFunc.hasColumn(resultSet, "ownerID");
 | 
			
		||||
        boolean merge = !this.plugin.equals("plotme") && Settings.CONVERT_PLOTME;
 | 
			
		||||
        boolean merge = !this.plugin.equals("plotme") && Settings.ENABLED_COMPONENTS.PLOTME_CONVERTER;
 | 
			
		||||
        while (resultSet.next()) {
 | 
			
		||||
            int key = resultSet.getInt("plot_id");
 | 
			
		||||
            PlotId id = new PlotId(resultSet.getInt("plotX"), resultSet.getInt("plotZ"));
 | 
			
		||||
            String name = resultSet.getString("owner");
 | 
			
		||||
            String world = LikePlotMeConverter.getWorld(resultSet.getString("world"));
 | 
			
		||||
            if (!plots.containsKey(world) && merge) {
 | 
			
		||||
                int plot = PS.get().config.getInt("worlds." + world + ".plot.size");
 | 
			
		||||
                int path = PS.get().config.getInt("worlds." + world + ".road.width");
 | 
			
		||||
                int plot = PS.get().worlds.getInt("worlds." + world + ".plot.size");
 | 
			
		||||
                int path = PS.get().worlds.getInt("worlds." + world + ".road.width");
 | 
			
		||||
                plotWidth.put(world, plot);
 | 
			
		||||
                roadWidth.put(world, path);
 | 
			
		||||
                merges.put(world, new HashMap<PlotId, boolean[]>());
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
package com.plotsquared.bukkit.listeners;
 | 
			
		||||
 | 
			
		||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
@@ -10,6 +8,8 @@ import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ReflectionUtils.RefField;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Chunk;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
@@ -28,8 +28,8 @@ import org.bukkit.event.entity.ItemSpawnEvent;
 | 
			
		||||
import org.bukkit.event.world.ChunkLoadEvent;
 | 
			
		||||
import org.bukkit.event.world.ChunkUnloadEvent;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
 | 
			
		||||
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
 | 
			
		||||
 | 
			
		||||
public class ChunkListener implements Listener {
 | 
			
		||||
 | 
			
		||||
@@ -39,7 +39,7 @@ public class ChunkListener implements Listener {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    public ChunkListener() {
 | 
			
		||||
        if (Settings.CHUNK_PROCESSOR_GC) {
 | 
			
		||||
        if (Settings.CHUNK_PROCESSOR.AUTO_TRIM) {
 | 
			
		||||
            try {
 | 
			
		||||
                RefClass classChunk = getRefClass("{nms}.Chunk");
 | 
			
		||||
                RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
 | 
			
		||||
@@ -47,10 +47,10 @@ public class ChunkListener implements Listener {
 | 
			
		||||
                this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
 | 
			
		||||
            } catch (Throwable ignored) {
 | 
			
		||||
                PS.debug("PlotSquared/Server not compatible for chunk processor trim/gc");
 | 
			
		||||
                Settings.CHUNK_PROCESSOR_GC = false;
 | 
			
		||||
                Settings.CHUNK_PROCESSOR.AUTO_TRIM = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!Settings.CHUNK_PROCESSOR_GC) {
 | 
			
		||||
        if (!Settings.CHUNK_PROCESSOR.AUTO_TRIM) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        for (World world : Bukkit.getWorlds()) {
 | 
			
		||||
@@ -139,7 +139,7 @@ public class ChunkListener implements Listener {
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void onChunkUnload(ChunkUnloadEvent event) {
 | 
			
		||||
        if (Settings.CHUNK_PROCESSOR_GC) {
 | 
			
		||||
        if (Settings.CHUNK_PROCESSOR.AUTO_TRIM) {
 | 
			
		||||
            Chunk chunk = event.getChunk();
 | 
			
		||||
            String world = chunk.getWorld().getName();
 | 
			
		||||
            if (PS.get().hasPlotArea(world)) {
 | 
			
		||||
@@ -171,7 +171,7 @@ public class ChunkListener implements Listener {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        Entity[] entities = chunk.getEntities();
 | 
			
		||||
        if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
 | 
			
		||||
        if (entities.length > Settings.CHUNK_PROCESSOR.MAX_ENTITIES) {
 | 
			
		||||
            event.getEntity().remove();
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
            this.lastChunk = chunk;
 | 
			
		||||
@@ -182,7 +182,7 @@ public class ChunkListener implements Listener {
 | 
			
		||||
    
 | 
			
		||||
    @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
 | 
			
		||||
    public void onBlockPhysics(BlockPhysicsEvent event) {
 | 
			
		||||
        if (Settings.CHUNK_PROCESSOR_DISABLE_PHYSICS) {
 | 
			
		||||
        if (Settings.CHUNK_PROCESSOR.DISABLE_PHYSICS) {
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -200,7 +200,7 @@ public class ChunkListener implements Listener {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        Entity[] entities = chunk.getEntities();
 | 
			
		||||
        if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
 | 
			
		||||
        if (entities.length > Settings.CHUNK_PROCESSOR.MAX_ENTITIES) {
 | 
			
		||||
            event.getEntity().remove();
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
            this.lastChunk = chunk;
 | 
			
		||||
@@ -254,7 +254,7 @@ public class ChunkListener implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
        Entity[] entities = chunk.getEntities();
 | 
			
		||||
        BlockState[] tiles = chunk.getTileEntities();
 | 
			
		||||
        if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
 | 
			
		||||
        if (entities.length > Settings.CHUNK_PROCESSOR.MAX_ENTITIES) {
 | 
			
		||||
            for (Entity ent : entities) {
 | 
			
		||||
                if (!(ent instanceof Player)) {
 | 
			
		||||
                    ent.remove();
 | 
			
		||||
@@ -262,7 +262,7 @@ public class ChunkListener implements Listener {
 | 
			
		||||
            }
 | 
			
		||||
            PS.debug("[PlotSquared] &a detected unsafe chunk and processed: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
 | 
			
		||||
        }
 | 
			
		||||
        if (tiles.length > Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES) {
 | 
			
		||||
        if (tiles.length > Settings.CHUNK_PROCESSOR.MAX_TILES) {
 | 
			
		||||
            if (unload) {
 | 
			
		||||
                PS.debug("[PlotSquared] &c detected unsafe chunk: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
 | 
			
		||||
                cleanChunk(chunk);
 | 
			
		||||
 
 | 
			
		||||
@@ -200,7 +200,7 @@ public class PlayerEvents extends PlotListener implements Listener {
 | 
			
		||||
                    event.setNewCurrent(0);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (Settings.REDSTONE_DISABLER) {
 | 
			
		||||
                if (Settings.REDSTONE.DISABLE_OFFLINE) {
 | 
			
		||||
                    if (UUIDHandler.getPlayer(plot.owner) == null) {
 | 
			
		||||
                        boolean disable = true;
 | 
			
		||||
                        for (UUID trusted : plot.getTrusted()) {
 | 
			
		||||
@@ -215,7 +215,7 @@ public class PlayerEvents extends PlotListener implements Listener {
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (Settings.REDSTONE_DISABLER_UNOCCUPIED) {
 | 
			
		||||
                if (Settings.REDSTONE.DISABLE_UNOCCUPIED) {
 | 
			
		||||
                    for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
 | 
			
		||||
                        if (plot.equals(entry.getValue().getCurrentPlot())) {
 | 
			
		||||
                            return;
 | 
			
		||||
@@ -350,7 +350,7 @@ public class PlayerEvents extends PlotListener implements Listener {
 | 
			
		||||
        if (cmd == null) {
 | 
			
		||||
            if (split[0].equals("plotme") || split[0].equals("ap")) {
 | 
			
		||||
                Player player = event.getPlayer();
 | 
			
		||||
                if (Settings.USE_PLOTME_ALIAS) {
 | 
			
		||||
                if (Settings.PLOTME.ALIAS) {
 | 
			
		||||
                    player.performCommand("plots " + StringMan.join(Arrays.copyOfRange(split, 1, split.length), " "));
 | 
			
		||||
                } else {
 | 
			
		||||
                    MainUtil.sendMessage(BukkitUtil.getPlayer(player), C.NOT_USING_PLOTME);
 | 
			
		||||
@@ -647,7 +647,7 @@ public class PlayerEvents extends PlotListener implements Listener {
 | 
			
		||||
                }
 | 
			
		||||
                MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_DESTROY_OTHER);
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getFlags().containsKey(Flags.DONE)) {
 | 
			
		||||
            } else if (Settings.DONE.RESTRICT_BUILDING && plot.getFlags().containsKey(Flags.DONE)) {
 | 
			
		||||
                if (!Permissions.hasPermission(plotPlayer, C.PERMISSION_ADMIN_BUILD_OTHER)) {
 | 
			
		||||
                    MainUtil.sendMessage(plotPlayer, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_OTHER);
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
@@ -741,7 +741,7 @@ public class PlayerEvents extends PlotListener implements Listener {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.PERMISSION_CACHING) {
 | 
			
		||||
        if (Settings.ENABLED_COMPONENTS.PERMISSION_CACHE) {
 | 
			
		||||
            pp.deleteMeta("perm");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1883,7 +1883,7 @@ public class PlayerEvents extends PlotListener implements Listener {
 | 
			
		||||
            entity.remove();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.KILL_ROAD_VEHICLES) {
 | 
			
		||||
        if (Settings.ENABLED_COMPONENTS.KILL_ROAD_VEHICLES) {
 | 
			
		||||
            entity.setMetadata("plot", new FixedMetadataValue((Plugin) PS.get().IMP, plot));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -2302,7 +2302,7 @@ public class PlayerEvents extends PlotListener implements Listener {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getFlags().containsKey(Flags.DONE)) {
 | 
			
		||||
            } else if (Settings.DONE.RESTRICT_BUILDING && plot.getFlags().containsKey(Flags.DONE)) {
 | 
			
		||||
                if (!Permissions.hasPermission(pp, C.PERMISSION_ADMIN_BUILD_OTHER)) {
 | 
			
		||||
                    MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_BUILD_OTHER);
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package com.plotsquared.bukkit.util;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotBlock;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RegionWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
 
 | 
			
		||||
@@ -55,10 +55,10 @@ public class BukkitSetupUtils extends SetupUtils {
 | 
			
		||||
        String world = object.world;
 | 
			
		||||
        int type = object.type;
 | 
			
		||||
        String worldPath = "worlds." + object.world;
 | 
			
		||||
        if (!PS.get().config.contains(worldPath)) {
 | 
			
		||||
            PS.get().config.createSection(worldPath);
 | 
			
		||||
        if (!PS.get().worlds.contains(worldPath)) {
 | 
			
		||||
            PS.get().worlds.createSection(worldPath);
 | 
			
		||||
        }
 | 
			
		||||
        ConfigurationSection worldSection = PS.get().config.getConfigurationSection(worldPath);
 | 
			
		||||
        ConfigurationSection worldSection = PS.get().worlds.getConfigurationSection(worldPath);
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case 2: {
 | 
			
		||||
                if (object.id != null) {
 | 
			
		||||
@@ -101,11 +101,11 @@ public class BukkitSetupUtils extends SetupUtils {
 | 
			
		||||
                for (ConfigurationNode step : steps) {
 | 
			
		||||
                    worldSection.set(step.getConstant(), step.getValue());
 | 
			
		||||
                }
 | 
			
		||||
                PS.get().config.set("worlds." + world + ".generator.type", object.type);
 | 
			
		||||
                PS.get().config.set("worlds." + world + ".generator.terrain", object.terrain);
 | 
			
		||||
                PS.get().config.set("worlds." + world + ".generator.plugin", object.plotManager);
 | 
			
		||||
                PS.get().worlds.set("worlds." + world + ".generator.type", object.type);
 | 
			
		||||
                PS.get().worlds.set("worlds." + world + ".generator.terrain", object.terrain);
 | 
			
		||||
                PS.get().worlds.set("worlds." + world + ".generator.plugin", object.plotManager);
 | 
			
		||||
                if (object.setupGenerator != null && !object.setupGenerator.equals(object.plotManager)) {
 | 
			
		||||
                    PS.get().config.set("worlds." + world + ".generator.init", object.setupGenerator);
 | 
			
		||||
                    PS.get().worlds.set("worlds." + world + ".generator.init", object.setupGenerator);
 | 
			
		||||
                }
 | 
			
		||||
                GeneratorWrapper<?> gen = SetupUtils.generators.get(object.setupGenerator);
 | 
			
		||||
                if (gen != null && gen.isFull()) {
 | 
			
		||||
@@ -119,7 +119,7 @@ public class BukkitSetupUtils extends SetupUtils {
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            PS.get().config.save(PS.get().configFile);
 | 
			
		||||
            PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
import com.intellectualcrafters.plot.object.StringWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.StringMan;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.UUIDHandler;
 | 
			
		||||
@@ -82,7 +82,7 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (Settings.TWIN_MODE_UUID) {
 | 
			
		||||
                if (Settings.UUID.NATIVE_UUID_PROVIDER) {
 | 
			
		||||
                    HashBiMap<StringWrapper, UUID> toAdd = HashBiMap.create(new HashMap<StringWrapper, UUID>());
 | 
			
		||||
                    toAdd.put(new StringWrapper("*"), DBFunc.everyone);
 | 
			
		||||
                    HashSet<UUID> all = UUIDHandler.getAllUUIDS();
 | 
			
		||||
@@ -173,8 +173,8 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
 | 
			
		||||
                            NbtFactory.NbtCompound bukkit = (NbtFactory.NbtCompound) compound.get("bukkit");
 | 
			
		||||
                            String name = (String) bukkit.get("lastKnownName");
 | 
			
		||||
                            long last = (long) bukkit.get("lastPlayed");
 | 
			
		||||
                            if (Settings.OFFLINE_MODE) {
 | 
			
		||||
                                if (Settings.UUID_LOWERCASE && !name.toLowerCase().equals(name)) {
 | 
			
		||||
                            if (Settings.UUID.OFFLINE) {
 | 
			
		||||
                                if (Settings.UUID.FORCE_LOWERCASE && !name.toLowerCase().equals(name)) {
 | 
			
		||||
                                    uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    long most = (long) compound.get("UUIDMost");
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.database.SQLite;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
import com.intellectualcrafters.plot.object.StringWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.UUIDHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation;
 | 
			
		||||
@@ -41,7 +42,7 @@ public class SQLUUIDHandler extends UUIDHandlerImplementation {
 | 
			
		||||
 | 
			
		||||
    public SQLUUIDHandler(UUIDWrapper wrapper) {
 | 
			
		||||
        super(wrapper);
 | 
			
		||||
        this.sqlite = new SQLite("./plugins/PlotSquared/usercache.db");
 | 
			
		||||
        this.sqlite = new SQLite(MainUtil.getFile(PS.get().IMP.getDirectory(), "usercache.db"));
 | 
			
		||||
        try {
 | 
			
		||||
            this.sqlite.openConnection();
 | 
			
		||||
        } catch (ClassNotFoundException | SQLException e) {
 | 
			
		||||
@@ -104,7 +105,7 @@ public class SQLUUIDHandler extends UUIDHandlerImplementation {
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            // If the file based UUID handler didn't cache it, then we can't cache offline mode
 | 
			
		||||
                            // Also, trying to cache based on files again, is useless as that's what the file based uuid cacher does
 | 
			
		||||
                            if (Settings.OFFLINE_MODE) {
 | 
			
		||||
                            if (Settings.UUID.OFFLINE) {
 | 
			
		||||
                                if (whenDone != null) {
 | 
			
		||||
                                    whenDone.run();
 | 
			
		||||
                                }
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import com.intellectualcrafters.plot.commands.WE_Anywhere;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Configuration;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Storage;
 | 
			
		||||
import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.database.Database;
 | 
			
		||||
import com.intellectualcrafters.plot.database.MySQL;
 | 
			
		||||
@@ -20,7 +21,6 @@ import com.intellectualcrafters.plot.logger.DelegateLogger;
 | 
			
		||||
import com.intellectualcrafters.plot.logger.ILogger;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotArea;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotCluster;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotFilter;
 | 
			
		||||
@@ -35,7 +35,6 @@ import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.CommentManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.InventoryUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MathMan;
 | 
			
		||||
@@ -48,9 +47,9 @@ import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.UUIDHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.WorldUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.area.QuadMap;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
 | 
			
		||||
import com.plotsquared.listener.WESubscriber;
 | 
			
		||||
import com.sk89q.worldedit.WorldEdit;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
@@ -104,10 +103,12 @@ public class PS {
 | 
			
		||||
    public HashMap<String, HashMap<PlotId, Plot>> plots_tmp;
 | 
			
		||||
    public File styleFile;
 | 
			
		||||
    public File configFile;
 | 
			
		||||
    public File worldsFile;
 | 
			
		||||
    public File commandsFile;
 | 
			
		||||
    public File translationFile;
 | 
			
		||||
    public YamlConfiguration style;
 | 
			
		||||
    public YamlConfiguration config;
 | 
			
		||||
    public YamlConfiguration worlds;
 | 
			
		||||
    public YamlConfiguration storage;
 | 
			
		||||
    public YamlConfiguration commands;
 | 
			
		||||
    public TaskManager TASK;
 | 
			
		||||
@@ -152,47 +153,62 @@ public class PS {
 | 
			
		||||
                PS.log(C.CONSOLE_JAVA_OUTDATED_1_8);
 | 
			
		||||
            }
 | 
			
		||||
            this.TASK = this.IMP.getTaskManager();
 | 
			
		||||
            if (!C.ENABLED.s().isEmpty()) {
 | 
			
		||||
                PS.log(C.ENABLED);
 | 
			
		||||
            }
 | 
			
		||||
            setupConfigs();
 | 
			
		||||
            this.translationFile = new File(this.IMP.getDirectory() + File.separator + "translations" + File.separator + "PlotSquared.use_THIS.yml");
 | 
			
		||||
            this.translationFile = MainUtil.getFile(this.IMP.getDirectory(), Settings.PATHS.TRANSLATIONS + File.separator + "PlotSquared.use_THIS.yml");
 | 
			
		||||
            C.load(this.translationFile);
 | 
			
		||||
            setupDatabase();
 | 
			
		||||
 | 
			
		||||
            // Database
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.DATABASE) {
 | 
			
		||||
                setupDatabase();
 | 
			
		||||
            }
 | 
			
		||||
            // Comments
 | 
			
		||||
            CommentManager.registerDefaultInboxes();
 | 
			
		||||
            // Tasks
 | 
			
		||||
            if (Settings.KILL_ROAD_MOBS || Settings.KILL_ROAD_VEHICLES) {
 | 
			
		||||
            // Kill entities
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.KILL_ROAD_MOBS || Settings.ENABLED_COMPONENTS.KILL_ROAD_VEHICLES) {
 | 
			
		||||
                this.IMP.runEntityTask();
 | 
			
		||||
            }
 | 
			
		||||
            try {
 | 
			
		||||
                if (this.IMP.initWorldEdit()) {
 | 
			
		||||
                    this.worldedit = WorldEdit.getInstance();
 | 
			
		||||
                    WorldEdit.getInstance().getEventBus().register(new WESubscriber());
 | 
			
		||||
                    new WE_Anywhere();
 | 
			
		||||
            // WorldEdit
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.WORLDEDIT_RESTRICTIONS) {
 | 
			
		||||
                try {
 | 
			
		||||
                    if (this.IMP.initWorldEdit()) {
 | 
			
		||||
                        this.worldedit = WorldEdit.getInstance();
 | 
			
		||||
                        WorldEdit.getInstance().getEventBus().register(new WESubscriber());
 | 
			
		||||
                        new WE_Anywhere();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (Throwable e) {
 | 
			
		||||
                    PS.debug("Incompatible version of WorldEdit, please upgrade: http://builds.enginehub.org/job/worldedit?branch=master");
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                PS.debug("Incompatible version of WorldEdit, please upgrade: http://builds.enginehub.org/job/worldedit?branch=master");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Events
 | 
			
		||||
            this.IMP.registerCommands();
 | 
			
		||||
            this.IMP.registerPlayerEvents();
 | 
			
		||||
            this.IMP.registerInventoryEvents();
 | 
			
		||||
            this.IMP.registerPlotPlusEvents();
 | 
			
		||||
            this.IMP.registerForceFieldEvents();
 | 
			
		||||
            // Commands
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.COMMANDS) {
 | 
			
		||||
                this.IMP.registerCommands();
 | 
			
		||||
            }
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.EVENTS) {
 | 
			
		||||
                this.IMP.registerPlayerEvents();
 | 
			
		||||
                this.IMP.registerInventoryEvents();
 | 
			
		||||
                this.IMP.registerPlotPlusEvents();
 | 
			
		||||
                this.IMP.registerForceFieldEvents();
 | 
			
		||||
            }
 | 
			
		||||
            // Required
 | 
			
		||||
            this.IMP.registerWorldEvents();
 | 
			
		||||
            if (Settings.METRICS) {
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.METRICS) {
 | 
			
		||||
                this.IMP.startMetrics();
 | 
			
		||||
            } else {
 | 
			
		||||
                PS.log(C.CONSOLE_PLEASE_ENABLE_METRICS);
 | 
			
		||||
            }
 | 
			
		||||
            if (Settings.CHUNK_PROCESSOR) {
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.CHUNK_PROCESSOR) {
 | 
			
		||||
                this.IMP.registerChunkProcessor();
 | 
			
		||||
            }
 | 
			
		||||
            // create UUIDWrapper
 | 
			
		||||
            UUIDHandler.implementation = this.IMP.initUUIDHandler();
 | 
			
		||||
            startUuidCatching();
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.UUID_CACHE) {
 | 
			
		||||
                startUuidCatching();
 | 
			
		||||
            } else {
 | 
			
		||||
                // Start these separately
 | 
			
		||||
                startExpiryTasks();
 | 
			
		||||
                startPlotMeConversion();
 | 
			
		||||
            }
 | 
			
		||||
            // create event util class
 | 
			
		||||
            EventUtil.manager = this.IMP.initEventUtil();
 | 
			
		||||
            // create Hybrid utility class
 | 
			
		||||
@@ -214,32 +230,36 @@ public class PS {
 | 
			
		||||
            // Chat
 | 
			
		||||
            ChatManager.manager = this.IMP.initChatManager();
 | 
			
		||||
            // Economy
 | 
			
		||||
            TaskManager.runTask(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    EconHandler.manager = PS.this.IMP.getEconomyHandler();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.ECONOMY) {
 | 
			
		||||
                TaskManager.runTask(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        EconHandler.manager = PS.this.IMP.getEconomyHandler();
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Check for updates
 | 
			
		||||
            TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    URL url = Updater.getUpdate();
 | 
			
		||||
                    if (url != null) {
 | 
			
		||||
                        PS.this.update = url;
 | 
			
		||||
                    } else if (PS.this.lastVersion == null) {
 | 
			
		||||
                        PS.log("&aThanks for installing PlotSquared!");
 | 
			
		||||
                    } else if (!get().checkVersion(PS.this.lastVersion, PS.this.version)) {
 | 
			
		||||
                        PS.log("&aThanks for updating from " + StringMan.join(PS.this.lastVersion, ".") + " to " + StringMan
 | 
			
		||||
                                .join(PS.this.version, ".") + "!");
 | 
			
		||||
                        DBFunc.dbManager.updateTables(PS.this.lastVersion);
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.UPDATER) {
 | 
			
		||||
                TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        URL url = Updater.getUpdate();
 | 
			
		||||
                        if (url != null) {
 | 
			
		||||
                            PS.this.update = url;
 | 
			
		||||
                        } else if (PS.this.lastVersion == null) {
 | 
			
		||||
                            PS.log("&aThanks for installing PlotSquared!");
 | 
			
		||||
                        } else if (!get().checkVersion(PS.this.lastVersion, PS.this.version)) {
 | 
			
		||||
                            PS.log("&aThanks for updating from " + StringMan.join(PS.this.lastVersion, ".") + " to " + StringMan
 | 
			
		||||
                                    .join(PS.this.version, ".") + "!");
 | 
			
		||||
                            DBFunc.dbManager.updateTables(PS.this.lastVersion);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // World generators:
 | 
			
		||||
            final ConfigurationSection section = this.config.getConfigurationSection("worlds");
 | 
			
		||||
            final ConfigurationSection section = this.worlds.getConfigurationSection("worlds");
 | 
			
		||||
            if (section != null) {
 | 
			
		||||
                for (String world : section.getKeys(false)) {
 | 
			
		||||
                    if (world.equals("CheckingPlotSquaredGenerator")) {
 | 
			
		||||
@@ -270,17 +290,20 @@ public class PS {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Copy files
 | 
			
		||||
            copyFile("automerge.js", "scripts");
 | 
			
		||||
            copyFile("town.template", "templates");
 | 
			
		||||
            copyFile("skyblock.template", "templates");
 | 
			
		||||
            copyFile("german.yml", "translations");
 | 
			
		||||
            copyFile("s_chinese_unescaped.yml", "translations");
 | 
			
		||||
            copyFile("s_chinese.yml", "translations");
 | 
			
		||||
            copyFile("italian.yml", "translations");
 | 
			
		||||
            copyFile("automerge.js", Settings.PATHS.SCRIPTS);
 | 
			
		||||
            copyFile("town.template", Settings.PATHS.TEMPLATES);
 | 
			
		||||
            copyFile("skyblock.template", Settings.PATHS.TEMPLATES);
 | 
			
		||||
            copyFile("german.yml", Settings.PATHS.TRANSLATIONS);
 | 
			
		||||
            copyFile("s_chinese_unescaped.yml", Settings.PATHS.TRANSLATIONS);
 | 
			
		||||
            copyFile("s_chinese.yml", Settings.PATHS.TRANSLATIONS);
 | 
			
		||||
            copyFile("italian.yml", Settings.PATHS.TRANSLATIONS);
 | 
			
		||||
            showDebug();
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        if (!C.ENABLED.s().isEmpty()) {
 | 
			
		||||
            PS.log(C.ENABLED);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -348,38 +371,39 @@ public class PS {
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        // Auto clearing
 | 
			
		||||
                        if (Settings.AUTO_CLEAR) {
 | 
			
		||||
                            ExpireManager.IMP = new ExpireManager();
 | 
			
		||||
                            if (Settings.AUTO_CLEAR_CONFIRMATION) {
 | 
			
		||||
                                ExpireManager.IMP.runConfirmedTask();
 | 
			
		||||
                            } else {
 | 
			
		||||
                                ExpireManager.IMP.runAutomatedTask();
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        // PlotMe
 | 
			
		||||
                        if (Settings.CONVERT_PLOTME || Settings.CACHE_PLOTME) {
 | 
			
		||||
                            TaskManager.runTaskLater(new Runnable() {
 | 
			
		||||
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void run() {
 | 
			
		||||
                                    if (PS.this.IMP.initPlotMeConverter()) {
 | 
			
		||||
                                        PS.log("&c=== IMPORTANT ===");
 | 
			
		||||
                                        PS.log("&cTHIS MESSAGE MAY BE EXTREMELY HELPFUL IF YOU HAVE TROUBLE CONVERTING PLOTME!");
 | 
			
		||||
                                        PS.log("&c - Make sure 'UUID.read-from-disk' is disabled (false)!");
 | 
			
		||||
                                        PS.log("&c - Sometimes the database can be locked, deleting PlotMe.jar beforehand will fix the issue!");
 | 
			
		||||
                                        PS.log("&c - After the conversion is finished, please set 'plotme-convert.enabled' to false in the "
 | 
			
		||||
                                                + "'settings.yml'");
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }, 20);
 | 
			
		||||
                        }
 | 
			
		||||
                        startExpiryTasks();
 | 
			
		||||
                        startPlotMeConversion();
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }, 20);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void startExpiryTasks() {
 | 
			
		||||
        if (Settings.ENABLED_COMPONENTS.PLOT_EXPIRY) {
 | 
			
		||||
            ExpireManager.IMP = new ExpireManager();
 | 
			
		||||
            ExpireManager.IMP.runAutomatedTask();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void startPlotMeConversion() {
 | 
			
		||||
        if (Settings.ENABLED_COMPONENTS.PLOTME_CONVERTER || Settings.PLOTME.CACHE_UUDS) {
 | 
			
		||||
            TaskManager.runTaskLater(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    if (PS.this.IMP.initPlotMeConverter()) {
 | 
			
		||||
                        PS.log("&c=== IMPORTANT ===");
 | 
			
		||||
                        PS.log("&cTHIS MESSAGE MAY BE EXTREMELY HELPFUL IF YOU HAVE TROUBLE CONVERTING PLOTME!");
 | 
			
		||||
                        PS.log("&c - Make sure 'UUID.read-from-disk' is disabled (false)!");
 | 
			
		||||
                        PS.log("&c - Sometimes the database can be locked, deleting PlotMe.jar beforehand will fix the issue!");
 | 
			
		||||
                        PS.log("&c - After the conversion is finished, please set 'plotme-convert.enabled' to false in the "
 | 
			
		||||
                                + "'settings.yml'");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }, 20);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isMainThread(Thread thread) {
 | 
			
		||||
        return this.thread == thread;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1352,13 +1376,13 @@ public class PS {
 | 
			
		||||
            this.plotAreaHasCollision = true;
 | 
			
		||||
        }
 | 
			
		||||
        Set<String> worlds;
 | 
			
		||||
        if (this.config.contains("worlds")) {
 | 
			
		||||
            worlds = this.config.getConfigurationSection("worlds").getKeys(false);
 | 
			
		||||
        if (this.worlds.contains("worlds")) {
 | 
			
		||||
            worlds = this.worlds.getConfigurationSection("worlds").getKeys(false);
 | 
			
		||||
        } else {
 | 
			
		||||
            worlds = new HashSet<>();
 | 
			
		||||
        }
 | 
			
		||||
        String path = "worlds." + world;
 | 
			
		||||
        ConfigurationSection worldSection = this.config.getConfigurationSection(path);
 | 
			
		||||
        ConfigurationSection worldSection = this.worlds.getConfigurationSection(path);
 | 
			
		||||
        int type;
 | 
			
		||||
        if (worldSection != null) {
 | 
			
		||||
            type = worldSection.getInt("generator.type", 0);
 | 
			
		||||
@@ -1397,14 +1421,14 @@ public class PS {
 | 
			
		||||
            PS.log(C.PREFIX + "&3 - generator: &7" + baseGenerator + ">" + plotGenerator);
 | 
			
		||||
            PS.log(C.PREFIX + "&3 - plotworld: &7" + plotArea.getClass().getName());
 | 
			
		||||
            PS.log(C.PREFIX + "&3 - manager: &7" + plotManager.getClass().getName());
 | 
			
		||||
            if (!this.config.contains(path)) {
 | 
			
		||||
                this.config.createSection(path);
 | 
			
		||||
                worldSection = this.config.getConfigurationSection(path);
 | 
			
		||||
            if (!this.worlds.contains(path)) {
 | 
			
		||||
                this.worlds.createSection(path);
 | 
			
		||||
                worldSection = this.worlds.getConfigurationSection(path);
 | 
			
		||||
            }
 | 
			
		||||
            plotArea.saveConfiguration(worldSection);
 | 
			
		||||
            plotArea.loadDefaultConfiguration(worldSection);
 | 
			
		||||
            try {
 | 
			
		||||
                this.config.save(this.configFile);
 | 
			
		||||
                this.worlds.save(this.worldsFile);
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
@@ -1447,7 +1471,7 @@ public class PS {
 | 
			
		||||
                        pa.saveConfiguration(worldSection);
 | 
			
		||||
                        pa.loadDefaultConfiguration(worldSection);
 | 
			
		||||
                        try {
 | 
			
		||||
                            this.config.save(this.configFile);
 | 
			
		||||
                            this.worlds.save(this.worldsFile);
 | 
			
		||||
                        } catch (IOException e) {
 | 
			
		||||
                            e.printStackTrace();
 | 
			
		||||
                        }
 | 
			
		||||
@@ -1472,7 +1496,7 @@ public class PS {
 | 
			
		||||
                pa.saveConfiguration(worldSection);
 | 
			
		||||
                pa.loadDefaultConfiguration(worldSection);
 | 
			
		||||
                try {
 | 
			
		||||
                    this.config.save(this.configFile);
 | 
			
		||||
                    this.worlds.save(this.worldsFile);
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
@@ -1546,7 +1570,7 @@ public class PS {
 | 
			
		||||
                }
 | 
			
		||||
                pa.loadDefaultConfiguration(clone);
 | 
			
		||||
                try {
 | 
			
		||||
                    this.config.save(this.configFile);
 | 
			
		||||
                    this.worlds.save(this.worldsFile);
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
@@ -1588,35 +1612,35 @@ public class PS {
 | 
			
		||||
                    switch (key) {
 | 
			
		||||
                        case "s":
 | 
			
		||||
                        case "size":
 | 
			
		||||
                            this.config.set(base + "plot.size", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            this.worlds.set(base + "plot.size", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "g":
 | 
			
		||||
                        case "gap":
 | 
			
		||||
                            this.config.set(base + "road.width", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            this.worlds.set(base + "road.width", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "h":
 | 
			
		||||
                        case "height":
 | 
			
		||||
                            this.config.set(base + "road.height", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            this.config.set(base + "plot.height", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            this.config.set(base + "wall.height", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            this.worlds.set(base + "road.height", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            this.worlds.set(base + "plot.height", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            this.worlds.set(base + "wall.height", Configuration.INTEGER.parseString(value).shortValue());
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "f":
 | 
			
		||||
                        case "floor":
 | 
			
		||||
                            this.config.set(base + "plot.floor",
 | 
			
		||||
                            this.worlds.set(base + "plot.floor",
 | 
			
		||||
                                    new ArrayList<>(Arrays.asList(StringMan.join(Configuration.BLOCKLIST.parseString(value), ",").split(","))));
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "m":
 | 
			
		||||
                        case "main":
 | 
			
		||||
                            this.config.set(base + "plot.filling",
 | 
			
		||||
                            this.worlds.set(base + "plot.filling",
 | 
			
		||||
                                    new ArrayList<>(Arrays.asList(StringMan.join(Configuration.BLOCKLIST.parseString(value), ",").split(","))));
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "w":
 | 
			
		||||
                        case "wall":
 | 
			
		||||
                            this.config.set(base + "wall.filling", Configuration.BLOCK.parseString(value).toString());
 | 
			
		||||
                            this.worlds.set(base + "wall.filling", Configuration.BLOCK.parseString(value).toString());
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "b":
 | 
			
		||||
                        case "border":
 | 
			
		||||
                            this.config.set(base + "wall.block", Configuration.BLOCK.parseString(value).toString());
 | 
			
		||||
                            this.worlds.set(base + "wall.block", Configuration.BLOCK.parseString(value).toString());
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            PS.log("&cKey not found: &7" + element);
 | 
			
		||||
@@ -1629,10 +1653,10 @@ public class PS {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            try {
 | 
			
		||||
                ConfigurationSection section = this.config.getConfigurationSection("worlds." + world);
 | 
			
		||||
                ConfigurationSection section = this.worlds.getConfigurationSection("worlds." + world);
 | 
			
		||||
                plotworld.saveConfiguration(section);
 | 
			
		||||
                plotworld.loadConfiguration(section);
 | 
			
		||||
                this.config.save(this.configFile);
 | 
			
		||||
                this.worlds.save(this.worldsFile);
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
@@ -1783,33 +1807,26 @@ public class PS {
 | 
			
		||||
     */
 | 
			
		||||
    public void setupDatabase() {
 | 
			
		||||
        try {
 | 
			
		||||
            if (Settings.DB.USE_MONGO) {
 | 
			
		||||
                PS.log(C.PREFIX + "MongoDB is not yet implemented");
 | 
			
		||||
                PS.log(C.PREFIX + "&cNo storage type is set!");
 | 
			
		||||
                this.IMP.disable();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (DBFunc.dbManager == null) {
 | 
			
		||||
                if (Settings.DB.USE_MYSQL) {
 | 
			
		||||
                    this.database = new MySQL(Settings.DB.HOST_NAME, Settings.DB.PORT, Settings.DB.DATABASE, Settings.DB.USER, Settings.DB.PASSWORD);
 | 
			
		||||
                } else if (Settings.DB.USE_SQLITE) {
 | 
			
		||||
                    this.database = new SQLite(this.IMP.getDirectory() + File.separator + Settings.DB.SQLITE_DB + ".db");
 | 
			
		||||
                if (Storage.MYSQL.USE) {
 | 
			
		||||
                    this.database = new MySQL(Storage.MYSQL.HOST, Storage.MYSQL.PORT, Storage.MYSQL.DATABASE, Storage.MYSQL.USER, Storage.MYSQL.PASSWORD);
 | 
			
		||||
                } else if (Storage.SQLITE.USE) {
 | 
			
		||||
                    File file = MainUtil.getFile(IMP.getDirectory(), Storage.SQLITE.DB + ".db");
 | 
			
		||||
                    this.database = new SQLite(file);
 | 
			
		||||
                } else {
 | 
			
		||||
                    PS.log(C.PREFIX + "&cNo storage type is set!");
 | 
			
		||||
                    this.IMP.disable();
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            DBFunc.dbManager = new SQLManager(this.database, Settings.DB.PREFIX, false);
 | 
			
		||||
            DBFunc.dbManager = new SQLManager(this.database, Storage.PREFIX, false);
 | 
			
		||||
            this.plots_tmp = DBFunc.getPlots();
 | 
			
		||||
            this.clusters_tmp = DBFunc.getClusters();
 | 
			
		||||
        } catch (ClassNotFoundException | SQLException e) {
 | 
			
		||||
            PS.log(C.PREFIX + "&cFailed to open DATABASE connection. The plugin will disable itself.");
 | 
			
		||||
            if (Settings.DB.USE_MONGO) {
 | 
			
		||||
                PS.log("$4MONGO");
 | 
			
		||||
            } else if (Settings.DB.USE_MYSQL) {
 | 
			
		||||
            if (Storage.MYSQL.USE) {
 | 
			
		||||
                PS.log("$4MYSQL");
 | 
			
		||||
            } else if (Settings.DB.USE_SQLITE) {
 | 
			
		||||
            } else if (Storage.SQLITE.USE) {
 | 
			
		||||
                PS.log("$4SQLITE");
 | 
			
		||||
            }
 | 
			
		||||
            PS.log("&d==== Here is an ugly stacktrace, if you are interested in those things ===");
 | 
			
		||||
@@ -1829,239 +1846,25 @@ public class PS {
 | 
			
		||||
            String[] split = lastVersionString.split("\\.");
 | 
			
		||||
            this.lastVersion = new int[]{Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.config.set("version", StringMan.join(this.version, "."));
 | 
			
		||||
        this.config.set("platform", this.platform);
 | 
			
		||||
 | 
			
		||||
        Map<String, Object> options = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
        // Protection
 | 
			
		||||
        options.put("protection.redstone.disable-offline", Settings.REDSTONE_DISABLER);
 | 
			
		||||
        options.put("protection.redstone.disable-unoccupied", Settings.REDSTONE_DISABLER_UNOCCUPIED);
 | 
			
		||||
 | 
			
		||||
        // PlotMe
 | 
			
		||||
        options.put("plotme-alias", Settings.USE_PLOTME_ALIAS);
 | 
			
		||||
        options.put("plotme-convert.enabled", Settings.CONVERT_PLOTME);
 | 
			
		||||
        options.put("plotme-convert.cache-uuids", Settings.CACHE_PLOTME);
 | 
			
		||||
 | 
			
		||||
        // UUID
 | 
			
		||||
        options.put("uuid.use_sqluuidhandler", Settings.USE_SQLUUIDHANDLER);
 | 
			
		||||
        options.put("UUID.offline", Settings.OFFLINE_MODE);
 | 
			
		||||
        options.put("UUID.force-lowercase", Settings.UUID_LOWERCASE);
 | 
			
		||||
        options.put("uuid.read-from-disk", Settings.UUID_FROM_DISK);
 | 
			
		||||
 | 
			
		||||
        // Mob stuff
 | 
			
		||||
        options.put("kill_road_vehicles", Settings.KILL_ROAD_VEHICLES);
 | 
			
		||||
        options.put("kill_road_mobs", Settings.KILL_ROAD_MOBS);
 | 
			
		||||
 | 
			
		||||
        // Clearing + Expiry
 | 
			
		||||
        options.put("clear.fastmode", false);
 | 
			
		||||
        options.put("clear.on.ban", false);
 | 
			
		||||
        options.put("clear.auto.enabled", true);
 | 
			
		||||
        options.put("clear.auto.days", 7);
 | 
			
		||||
        options.put("clear.auto.clear-interval-seconds", Settings.CLEAR_INTERVAL);
 | 
			
		||||
        options.put("clear.auto.calibration.changes", 1);
 | 
			
		||||
        options.put("clear.auto.calibration.faces", 0);
 | 
			
		||||
        options.put("clear.auto.calibration.data", 0);
 | 
			
		||||
        options.put("clear.auto.calibration.air", 0);
 | 
			
		||||
        options.put("clear.auto.calibration.variety", 0);
 | 
			
		||||
        options.put("clear.auto.calibration.changes_sd", 1);
 | 
			
		||||
        options.put("clear.auto.calibration.faces_sd", 0);
 | 
			
		||||
        options.put("clear.auto.calibration.data_sd", 0);
 | 
			
		||||
        options.put("clear.auto.calibration.air_sd", 0);
 | 
			
		||||
        options.put("clear.auto.calibration.variety_sd", 0);
 | 
			
		||||
        options.put("clear.auto.confirmation", Settings.AUTO_CLEAR_CONFIRMATION); // TODO FIXME
 | 
			
		||||
 | 
			
		||||
        int keep = this.config.getInt("clear.keep-if-modified");
 | 
			
		||||
        int ignore = this.config.getInt("clear.ignore-if-modified");
 | 
			
		||||
        if (keep > 0 || ignore > 0) {
 | 
			
		||||
            options.put("clear.auto.threshold", 1);
 | 
			
		||||
            options.put("clear.auto.enabled", false);
 | 
			
		||||
            PS.log("&cIMPORTANT MESSAGE ABOUT THIS UPDATE!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
 | 
			
		||||
            PS.log("&cSorry for all the exclamation marks, but this could be important.");
 | 
			
		||||
            PS.log("&cPlot clearing has changed to a new system that requires calibration.");
 | 
			
		||||
            PS.log("&cThis is how it will work: ");
 | 
			
		||||
            PS.log("&c - Players will rate plots");
 | 
			
		||||
            PS.log("&c - When enough plots are rated, you can run /plot debugexec calibrate-analysis");
 | 
			
		||||
            PS.log("&c - You can decide the (rough) percentage of expired plots to clear");
 | 
			
		||||
            PS.log("&c - To just clear all expired plot, ignore this and set: &7threshold: -1");
 | 
			
		||||
            PS.log("&cMore information:&7 https://github.com/IntellectualSites/PlotSquared/wiki/Plot-analysis:");
 | 
			
		||||
        } else {
 | 
			
		||||
            options.put("clear.auto.threshold", Settings.CLEAR_THRESHOLD);
 | 
			
		||||
        }
 | 
			
		||||
        this.config.set("clear.keep-if-modified", null);
 | 
			
		||||
        this.config.set("clear.ignore-if-modified", null);
 | 
			
		||||
 | 
			
		||||
        // Done
 | 
			
		||||
        options.put("approval.ratings.check-done", Settings.REQUIRE_DONE);
 | 
			
		||||
        options.put("approval.done.counts-towards-limit", Settings.DONE_COUNTS_TOWARDS_LIMIT);
 | 
			
		||||
        options.put("approval.done.restrict-building", Settings.DONE_RESTRICTS_BUILDING);
 | 
			
		||||
        options.put("approval.done.required-for-download", Settings.DOWNLOAD_REQUIRES_DONE);
 | 
			
		||||
 | 
			
		||||
        // Schematics
 | 
			
		||||
        if (StringMan.isEqual(this.config.getString("schematic.save_path"), "plugins/PlotSquared/schematics")) {
 | 
			
		||||
            this.config.set("schematics.save_path", Settings.SCHEMATIC_SAVE_PATH);
 | 
			
		||||
        }
 | 
			
		||||
        options.put("schematics.save_path", Settings.SCHEMATIC_SAVE_PATH);
 | 
			
		||||
        options.put("bo3.save_path", Settings.BO3_SAVE_PATH);
 | 
			
		||||
 | 
			
		||||
        // Web
 | 
			
		||||
        options.put("web.url", Settings.WEB_URL);
 | 
			
		||||
        options.put("web.server-ip", Settings.WEB_IP);
 | 
			
		||||
 | 
			
		||||
        // Caching
 | 
			
		||||
        options.put("cache.permissions", Settings.PERMISSION_CACHING);
 | 
			
		||||
        options.put("cache.ratings", Settings.CACHE_RATINGS);
 | 
			
		||||
 | 
			
		||||
        // Titles
 | 
			
		||||
        options.put("titles", Settings.TITLES);
 | 
			
		||||
 | 
			
		||||
        // Teleportation
 | 
			
		||||
        options.put("teleport.on_login", Settings.TELEPORT_ON_LOGIN);
 | 
			
		||||
        options.put("teleport.on_death", Settings.TELEPORT_ON_DEATH);
 | 
			
		||||
        options.put("teleport.delay", Settings.TELEPORT_DELAY);
 | 
			
		||||
 | 
			
		||||
        // WorldEdit
 | 
			
		||||
        options.put("worldedit.enable-for-helpers", Settings.WE_ALLOW_HELPER);
 | 
			
		||||
        options.put("worldedit.blacklist", Arrays.asList("cs", ".s", "restore", "snapshot", "delchunks", "listchunks"));
 | 
			
		||||
 | 
			
		||||
        // Chunk processor
 | 
			
		||||
        options.put("chunk-processor.enabled", Settings.CHUNK_PROCESSOR);
 | 
			
		||||
        options.put("chunk-processor.auto-unload", Settings.CHUNK_PROCESSOR_GC);
 | 
			
		||||
        options.put("chunk-processor.experimental-fast-async-worldedit", Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT);
 | 
			
		||||
        options.put("chunk-processor.max-blockstates", Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES);
 | 
			
		||||
        options.put("chunk-processor.max-entities", Settings.CHUNK_PROCESSOR_MAX_ENTITIES);
 | 
			
		||||
        options.put("chunk-processor.disable-physics", Settings.CHUNK_PROCESSOR_DISABLE_PHYSICS);
 | 
			
		||||
 | 
			
		||||
        // Comments
 | 
			
		||||
        options.put("comments.notifications.enabled", Settings.COMMENT_NOTIFICATIONS);
 | 
			
		||||
 | 
			
		||||
        // Plot limits
 | 
			
		||||
        options.put("global_limit", Settings.GLOBAL_LIMIT);
 | 
			
		||||
        options.put("max_plots", Settings.MAX_PLOTS);
 | 
			
		||||
        options.put("claim.max-auto-area", Settings.MAX_AUTO_SIZE);
 | 
			
		||||
        options.put("merge.remove-terrain", Settings.MERGE_REMOVES_ROADS);
 | 
			
		||||
 | 
			
		||||
        // Misc
 | 
			
		||||
        options.put("console.color", Settings.CONSOLE_COLOR);
 | 
			
		||||
        options.put("chat.fancy", Settings.FANCY_CHAT);
 | 
			
		||||
        options.put("metrics", true);
 | 
			
		||||
        options.put("debug", true);
 | 
			
		||||
        options.put("update-notifications", Settings.UPDATE_NOTIFICATIONS);
 | 
			
		||||
 | 
			
		||||
        for (Entry<String, Object> node : options.entrySet()) {
 | 
			
		||||
            if (!this.config.contains(node.getKey())) {
 | 
			
		||||
                this.config.set(node.getKey(), node.getValue());
 | 
			
		||||
        if (checkVersion(new int[]{3,4,0}, version)) {
 | 
			
		||||
            Settings.convertLegacy(configFile);
 | 
			
		||||
            if (config.contains("worlds")) {
 | 
			
		||||
                ConfigurationSection worldSection = config.getConfigurationSection("worlds");
 | 
			
		||||
                worlds.set("worlds", worldSection);
 | 
			
		||||
                try {
 | 
			
		||||
                    worlds.save(worldsFile);
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
                    PS.debug("Failed to save PlotSquared worlds.yml");
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            Settings.load(configFile);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Protection
 | 
			
		||||
        Settings.REDSTONE_DISABLER = this.config.getBoolean("protection.redstone.disable-offline");
 | 
			
		||||
        Settings.REDSTONE_DISABLER_UNOCCUPIED = this.config.getBoolean("protection.redstone.disable-unoccupied");
 | 
			
		||||
 | 
			
		||||
        // PlotMe
 | 
			
		||||
        Settings.USE_PLOTME_ALIAS = this.config.getBoolean("plotme-alias");
 | 
			
		||||
        Settings.CONVERT_PLOTME = this.config.getBoolean("plotme-convert.enabled");
 | 
			
		||||
        Settings.CACHE_PLOTME = this.config.getBoolean("plotme-convert.cache-uuids");
 | 
			
		||||
 | 
			
		||||
        // UUID
 | 
			
		||||
        Settings.USE_SQLUUIDHANDLER = this.config.getBoolean("uuid.use_sqluuidhandler");
 | 
			
		||||
        Settings.OFFLINE_MODE = this.config.getBoolean("UUID.offline");
 | 
			
		||||
        Settings.UUID_LOWERCASE = Settings.OFFLINE_MODE && this.config.getBoolean("UUID.force-lowercase");
 | 
			
		||||
        Settings.UUID_FROM_DISK = this.config.getBoolean("uuid.read-from-disk");
 | 
			
		||||
 | 
			
		||||
        // Mob stuff
 | 
			
		||||
        Settings.KILL_ROAD_MOBS = this.config.getBoolean("kill_road_mobs");
 | 
			
		||||
        Settings.KILL_ROAD_VEHICLES = this.config.getBoolean("kill_road_vehicles");
 | 
			
		||||
 | 
			
		||||
        // Clearing + Expiry
 | 
			
		||||
        Settings.FAST_CLEAR = this.config.getBoolean("clear.fastmode");
 | 
			
		||||
        Settings.DELETE_PLOTS_ON_BAN = this.config.getBoolean("clear.on.ban");
 | 
			
		||||
        Settings.AUTO_CLEAR_DAYS = this.config.getInt("clear.auto.days");
 | 
			
		||||
        Settings.CLEAR_THRESHOLD = this.config.getInt("clear.auto.threshold");
 | 
			
		||||
        Settings.AUTO_CLEAR = this.config.getBoolean("clear.auto.enabled");
 | 
			
		||||
        Settings.CLEAR_INTERVAL = this.config.getInt("clear.auto.clear-interval-seconds");
 | 
			
		||||
 | 
			
		||||
        // Clearing modifiers
 | 
			
		||||
        PlotAnalysis.MODIFIERS.changes = this.config.getInt("clear.auto.calibration.changes");
 | 
			
		||||
        PlotAnalysis.MODIFIERS.faces = this.config.getInt("clear.auto.calibration.faces");
 | 
			
		||||
        PlotAnalysis.MODIFIERS.data = this.config.getInt("clear.auto.calibration.data");
 | 
			
		||||
        PlotAnalysis.MODIFIERS.air = this.config.getInt("clear.auto.calibration.air");
 | 
			
		||||
        PlotAnalysis.MODIFIERS.variety = this.config.getInt("clear.auto.calibration.variety");
 | 
			
		||||
        PlotAnalysis.MODIFIERS.changes_sd = this.config.getInt("clear.auto.calibration.changes_sd");
 | 
			
		||||
        PlotAnalysis.MODIFIERS.faces_sd = this.config.getInt("clear.auto.calibration.faces_sd");
 | 
			
		||||
        PlotAnalysis.MODIFIERS.data_sd = this.config.getInt("clear.auto.calibration.data_sd");
 | 
			
		||||
        PlotAnalysis.MODIFIERS.air_sd = this.config.getInt("clear.auto.calibration.air_sd");
 | 
			
		||||
        PlotAnalysis.MODIFIERS.variety_sd = this.config.getInt("clear.auto.calibration.variety_sd");
 | 
			
		||||
        Settings.AUTO_CLEAR_CONFIRMATION = this.config.getBoolean("clear.auto.confirmation"); // TODO FIXME
 | 
			
		||||
 | 
			
		||||
        // Done
 | 
			
		||||
        Settings.REQUIRE_DONE = this.config.getBoolean("approval.ratings.check-done");
 | 
			
		||||
        Settings.DONE_COUNTS_TOWARDS_LIMIT = this.config.getBoolean("approval.done.counts-towards-limit");
 | 
			
		||||
        Settings.DONE_RESTRICTS_BUILDING = this.config.getBoolean("approval.done.restrict-building");
 | 
			
		||||
        Settings.DOWNLOAD_REQUIRES_DONE = this.config.getBoolean("approval.done.required-for-download");
 | 
			
		||||
 | 
			
		||||
        // Schematics
 | 
			
		||||
        Settings.SCHEMATIC_SAVE_PATH = this.config.getString("schematics.save_path");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        Settings.BO3_SAVE_PATH = this.config.getString("bo3.save_path");
 | 
			
		||||
 | 
			
		||||
        // Web
 | 
			
		||||
        Settings.WEB_URL = this.config.getString("web.url");
 | 
			
		||||
        Settings.WEB_IP = this.config.getString("web.server-ip");
 | 
			
		||||
 | 
			
		||||
        // Caching
 | 
			
		||||
        Settings.PERMISSION_CACHING = this.config.getBoolean("cache.permissions");
 | 
			
		||||
        Settings.CACHE_RATINGS = this.config.getBoolean("cache.ratings");
 | 
			
		||||
 | 
			
		||||
        // Rating system
 | 
			
		||||
        Settings.RATING_CATEGORIES = this.config.getStringList("ratings.categories");
 | 
			
		||||
 | 
			
		||||
        // Titles
 | 
			
		||||
        Settings.TITLES = this.config.getBoolean("titles");
 | 
			
		||||
 | 
			
		||||
        // Teleportation
 | 
			
		||||
        Settings.TELEPORT_DELAY = this.config.getInt("teleport.delay");
 | 
			
		||||
        Settings.TELEPORT_ON_LOGIN = this.config.getBoolean("teleport.on_login");
 | 
			
		||||
        Settings.TELEPORT_ON_DEATH = this.config.getBoolean("teleport.on_death");
 | 
			
		||||
 | 
			
		||||
        // WorldEdit
 | 
			
		||||
        Settings.WE_ALLOW_HELPER = this.config.getBoolean("worldedit.enable-for-helpers");
 | 
			
		||||
 | 
			
		||||
        // Chunk processor
 | 
			
		||||
        Settings.CHUNK_PROCESSOR = this.config.getBoolean("chunk-processor.enabled");
 | 
			
		||||
        Settings.CHUNK_PROCESSOR_GC = this.config.getBoolean("chunk-processor.auto-unload");
 | 
			
		||||
        Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT = this.config.getBoolean("chunk-processor.experimental-fast-async-worldedit");
 | 
			
		||||
        Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES = this.config.getInt("chunk-processor.max-blockstates");
 | 
			
		||||
        Settings.CHUNK_PROCESSOR_MAX_ENTITIES = this.config.getInt("chunk-processor.max-entities");
 | 
			
		||||
        Settings.CHUNK_PROCESSOR_DISABLE_PHYSICS = this.config.getBoolean("chunk-processor.disable-physics");
 | 
			
		||||
 | 
			
		||||
        // Comments
 | 
			
		||||
        Settings.COMMENT_NOTIFICATIONS = this.config.getBoolean("comments.notifications.enabled");
 | 
			
		||||
 | 
			
		||||
        // Plot limits
 | 
			
		||||
        Settings.MAX_AUTO_SIZE = this.config.getInt("claim.max-auto-area");
 | 
			
		||||
        Settings.MAX_PLOTS = this.config.getInt("max_plots");
 | 
			
		||||
        if (Settings.MAX_PLOTS > 32767) {
 | 
			
		||||
            PS.log("&c`max_plots` Is set too high! This is a per player setting and does not need to be very large.");
 | 
			
		||||
            Settings.MAX_PLOTS = 32767;
 | 
			
		||||
        }
 | 
			
		||||
        Settings.GLOBAL_LIMIT = this.config.getBoolean("global_limit");
 | 
			
		||||
 | 
			
		||||
        // Misc
 | 
			
		||||
        Settings.DEBUG = this.config.getBoolean("debug");
 | 
			
		||||
        if (Settings.DEBUG) {
 | 
			
		||||
            PS.log(C.PREFIX + "&6Debug Mode Enabled (Default). Edit the config to turn this off.");
 | 
			
		||||
        }
 | 
			
		||||
        Settings.CONSOLE_COLOR = this.config.getBoolean("console.color");
 | 
			
		||||
        if (!this.config.getBoolean("chat.fancy") || !checkVersion(this.IMP.getServerVersion(), 1, 8, 0)) {
 | 
			
		||||
            Settings.FANCY_CHAT = false;
 | 
			
		||||
        }
 | 
			
		||||
        Settings.METRICS = this.config.getBoolean("metrics");
 | 
			
		||||
        Settings.UPDATE_NOTIFICATIONS = this.config.getBoolean("update-notifications");
 | 
			
		||||
        Settings.MERGE_REMOVES_ROADS = this.config.getBoolean("merge.remove-terrain");
 | 
			
		||||
        Settings.AUTO_PURGE = this.config.getBoolean("auto-purge", false);
 | 
			
		||||
        Settings.VERSION = StringMan.join(this.version, ".");
 | 
			
		||||
        Settings.PLATFORM = platform;
 | 
			
		||||
        Settings.save(configFile);
 | 
			
		||||
        config = YamlConfiguration.loadConfiguration(configFile);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -2076,7 +1879,17 @@ public class PS {
 | 
			
		||||
            PS.log(C.PREFIX + "&cFailed to create the /plugins/config folder. Please create it manually.");
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            this.styleFile = new File(this.IMP.getDirectory() + File.separator + "translations" + File.separator + "style.yml");
 | 
			
		||||
            this.configFile = new File(folder,"settings.yml");
 | 
			
		||||
            if (!this.configFile.exists() && !this.configFile.createNewFile()) {
 | 
			
		||||
                PS.log("Could not create the settings file, please create \"settings.yml\" manually.");
 | 
			
		||||
            }
 | 
			
		||||
            this.config = YamlConfiguration.loadConfiguration(this.configFile);
 | 
			
		||||
            setupConfig();
 | 
			
		||||
        } catch (IOException ignored) {
 | 
			
		||||
            PS.log("Failed to save settings.yml");
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            this.styleFile = MainUtil.getFile(IMP.getDirectory(), Settings.PATHS.TRANSLATIONS +File.separator + "style.yml" );
 | 
			
		||||
            if (!this.styleFile.exists()) {
 | 
			
		||||
                if (!this.styleFile.getParentFile().exists()) {
 | 
			
		||||
                    this.styleFile.getParentFile().mkdirs();
 | 
			
		||||
@@ -2092,12 +1905,11 @@ public class PS {
 | 
			
		||||
            PS.log("failed to save style.yml");
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            this.configFile = new File(folder,"settings.yml");
 | 
			
		||||
            if (!this.configFile.exists() && !this.configFile.createNewFile()) {
 | 
			
		||||
                PS.log("Could not create the settings file, please create \"settings.yml\" manually.");
 | 
			
		||||
            this.worldsFile = new File(folder,"worlds.yml");
 | 
			
		||||
            if (!this.worldsFile.exists() && !this.worldsFile.createNewFile()) {
 | 
			
		||||
                PS.log("Could not create the worlds file, please create \"worlds.yml\" manually.");
 | 
			
		||||
            }
 | 
			
		||||
            this.config = YamlConfiguration.loadConfiguration(this.configFile);
 | 
			
		||||
            setupConfig();
 | 
			
		||||
            this.worlds = YamlConfiguration.loadConfiguration(this.worldsFile);
 | 
			
		||||
        } catch (IOException ignored) {
 | 
			
		||||
            PS.log("Failed to save settings.yml");
 | 
			
		||||
        }
 | 
			
		||||
@@ -2117,14 +1929,11 @@ public class PS {
 | 
			
		||||
                PS.log("Could not the storage settings file, please create \"commands.yml\" manually.");
 | 
			
		||||
            }
 | 
			
		||||
            this.commands = YamlConfiguration.loadConfiguration(this.commandsFile);
 | 
			
		||||
            setupStorage();
 | 
			
		||||
        } catch (IOException ignored) {
 | 
			
		||||
            PS.log("Failed to save commands.yml");
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            this.style.save(this.styleFile);
 | 
			
		||||
            this.config.save(this.configFile);
 | 
			
		||||
            this.storage.save(this.storageFile);
 | 
			
		||||
            this.commands.save(this.commandsFile);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            PS.log("Configuration file saving failed");
 | 
			
		||||
@@ -2137,30 +1946,9 @@ public class PS {
 | 
			
		||||
     */
 | 
			
		||||
    private void setupStorage() {
 | 
			
		||||
        this.storage.set("version", StringMan.join(this.version, "."));
 | 
			
		||||
        Map<String, Object> options = new HashMap<>(9);
 | 
			
		||||
        options.put("mysql.use", false);
 | 
			
		||||
        options.put("sqlite.use", true);
 | 
			
		||||
        options.put("sqlite.db", "storage");
 | 
			
		||||
        options.put("mysql.host", "localhost");
 | 
			
		||||
        options.put("mysql.port", "3306");
 | 
			
		||||
        options.put("mysql.user", "root");
 | 
			
		||||
        options.put("mysql.password", "password");
 | 
			
		||||
        options.put("mysql.database", "plot_db");
 | 
			
		||||
        options.put("prefix", "");
 | 
			
		||||
        for (Entry<String, Object> node : options.entrySet()) {
 | 
			
		||||
            if (!this.storage.contains(node.getKey())) {
 | 
			
		||||
                this.storage.set(node.getKey(), node.getValue());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Settings.DB.USE_MYSQL = this.storage.getBoolean("mysql.use");
 | 
			
		||||
        Settings.DB.USER = this.storage.getString("mysql.user");
 | 
			
		||||
        Settings.DB.PASSWORD = this.storage.getString("mysql.password");
 | 
			
		||||
        Settings.DB.HOST_NAME = this.storage.getString("mysql.host");
 | 
			
		||||
        Settings.DB.PORT = this.storage.getString("mysql.port");
 | 
			
		||||
        Settings.DB.DATABASE = this.storage.getString("mysql.database");
 | 
			
		||||
        Settings.DB.USE_SQLITE = this.storage.getBoolean("sqlite.use");
 | 
			
		||||
        Settings.DB.SQLITE_DB = this.storage.getString("sqlite.db");
 | 
			
		||||
        Settings.DB.PREFIX = this.storage.getString("prefix");
 | 
			
		||||
        Storage.load(storageFile);
 | 
			
		||||
        Storage.save(storageFile);
 | 
			
		||||
        storage = YamlConfiguration.loadConfiguration(storageFile);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -2168,17 +1956,9 @@ public class PS {
 | 
			
		||||
     */
 | 
			
		||||
    private void showDebug() {
 | 
			
		||||
        if (Settings.DEBUG) {
 | 
			
		||||
            Map<String, String> settings = new HashMap<>(9);
 | 
			
		||||
            settings.put("Kill Road Mobs", "" + Settings.KILL_ROAD_MOBS);
 | 
			
		||||
            settings.put("Use Metrics", "" + Settings.METRICS);
 | 
			
		||||
            settings.put("Delete Plots On Ban", "" + Settings.DELETE_PLOTS_ON_BAN);
 | 
			
		||||
            settings.put("DB Mysql Enabled", "" + Settings.DB.USE_MYSQL);
 | 
			
		||||
            settings.put("DB SQLite Enabled", "" + Settings.DB.USE_SQLITE);
 | 
			
		||||
            settings.put("Auto Clear Enabled", "" + Settings.AUTO_CLEAR);
 | 
			
		||||
            settings.put("Auto Clear Days", "" + Settings.AUTO_CLEAR_DAYS);
 | 
			
		||||
            settings.put("Schematics Save Path", "" + Settings.SCHEMATIC_SAVE_PATH);
 | 
			
		||||
            for (Entry<String, String> setting : settings.entrySet()) {
 | 
			
		||||
                PS.log(C.PREFIX + String.format("&cKey: &6%s&c, Value: &6%s", setting.getKey(), setting.getValue()));
 | 
			
		||||
            Map<String, Object> components = Settings.getFields(Settings.ENABLED_COMPONENTS.class);
 | 
			
		||||
            for (Entry<String, Object> component : components.entrySet()) {
 | 
			
		||||
                PS.log(C.PREFIX + String.format("&cKey: &6%s&c, Value: &6%s", component.getKey(), component.getValue()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -117,10 +117,10 @@ public class Area extends SubCommand {
 | 
			
		||||
                                    @Override
 | 
			
		||||
                                    public void run() {
 | 
			
		||||
                                        if (offsetX != 0) {
 | 
			
		||||
                                            PS.get().config.set(path + ".road.offset.x", offsetX);
 | 
			
		||||
                                            PS.get().worlds.set(path + ".road.offset.x", offsetX);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        if (offsetZ != 0) {
 | 
			
		||||
                                            PS.get().config.set(path + ".road.offset.z", offsetZ);
 | 
			
		||||
                                            PS.get().worlds.set(path + ".road.offset.z", offsetZ);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        final String world = SetupUtils.manager.setupWorld(object);
 | 
			
		||||
                                        if (WorldUtil.IMP.isWorld(world)) {
 | 
			
		||||
@@ -231,10 +231,10 @@ public class Area extends SubCommand {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void run() {
 | 
			
		||||
                                    String path = "worlds." + pa.worldname;
 | 
			
		||||
                                    if (!PS.get().config.contains(path)) {
 | 
			
		||||
                                        PS.get().config.createSection(path);
 | 
			
		||||
                                    if (!PS.get().worlds.contains(path)) {
 | 
			
		||||
                                        PS.get().worlds.createSection(path);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    ConfigurationSection section = PS.get().config.getConfigurationSection(path);
 | 
			
		||||
                                    ConfigurationSection section = PS.get().worlds.getConfigurationSection(path);
 | 
			
		||||
                                    pa.saveConfiguration(section);
 | 
			
		||||
                                    pa.loadConfiguration(section);
 | 
			
		||||
                                    object.plotManager = "PlotSquared";
 | 
			
		||||
@@ -247,7 +247,7 @@ public class Area extends SubCommand {
 | 
			
		||||
                                        MainUtil.sendMessage(player, "An error occurred while creating the world: " + pa.worldname);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    try {
 | 
			
		||||
                                        PS.get().config.save(PS.get().configFile);
 | 
			
		||||
                                        PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
                                    } catch (IOException e) {
 | 
			
		||||
                                        e.printStackTrace();
 | 
			
		||||
                                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -86,11 +86,11 @@ public class Auto extends SubCommand {
 | 
			
		||||
                // return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (size_x * size_z > Settings.MAX_AUTO_SIZE) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.CANT_CLAIM_MORE_PLOTS_NUM, Settings.MAX_AUTO_SIZE + "");
 | 
			
		||||
        if (size_x * size_z > Settings.CLAIM.MAX_AUTO_AREA) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.CANT_CLAIM_MORE_PLOTS_NUM, Settings.CLAIM.MAX_AUTO_AREA + "");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        int currentPlots = Settings.GLOBAL_LIMIT ? player.getPlotCount() : player.getPlotCount(plotarea.worldname);
 | 
			
		||||
        int currentPlots = Settings.LIMIT.GLOBAL ? player.getPlotCount() : player.getPlotCount(plotarea.worldname);
 | 
			
		||||
        int diff = currentPlots - player.getAllowedPlots();
 | 
			
		||||
        if (diff + size_x * size_z > 0) {
 | 
			
		||||
            if (diff < 0) {
 | 
			
		||||
@@ -173,7 +173,7 @@ public class Auto extends SubCommand {
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (size_x != 1 || size_z != 1) {
 | 
			
		||||
                    if (!plotarea.mergePlots(MainUtil.getPlotSelectionIds(start, end), Settings.MERGE_REMOVES_ROADS, true)) {
 | 
			
		||||
                    if (!plotarea.mergePlots(MainUtil.getPlotSelectionIds(start, end), true, true)) {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ public class Claim extends SubCommand {
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            return sendMessage(player, C.NOT_IN_PLOT);
 | 
			
		||||
        }
 | 
			
		||||
        int currentPlots = Settings.GLOBAL_LIMIT ? player.getPlotCount() : player.getPlotCount(loc.getWorld());
 | 
			
		||||
        int currentPlots = Settings.LIMIT.GLOBAL ? player.getPlotCount() : player.getPlotCount(loc.getWorld());
 | 
			
		||||
        int grants = 0;
 | 
			
		||||
        if (currentPlots >= player.getAllowedPlots()) {
 | 
			
		||||
            if (player.hasPersistentMeta("grantedPlots")) {
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ public class Clear extends Command {
 | 
			
		||||
        final Plot plot = check(player.getCurrentPlot(), C.NOT_IN_PLOT);
 | 
			
		||||
        checkTrue(plot.isOwner(player.getUUID()) || Permissions.hasPermission(player, "plots.admin.command.clear"), C.NO_PLOT_PERMS);
 | 
			
		||||
        checkTrue(plot.getRunning() == 0, C.WAIT_FOR_TIMER);
 | 
			
		||||
        checkTrue((!Flags.DONE.isSet(plot) || Permissions.hasPermission(player, "plots.continue")) && (!Settings.DONE_COUNTS_TOWARDS_LIMIT || player.getAllowedPlots() >= player.getPlotCount() + plot.getConnectedPlots().size()), C.DONE_ALREADY_DONE);
 | 
			
		||||
        checkTrue((!Flags.DONE.isSet(plot) || Permissions.hasPermission(player, "plots.continue")) && (!Settings.DONE.COUNTS_TOWARDS_LIMIT || player.getAllowedPlots() >= player.getPlotCount() + plot.getConnectedPlots().size()), C.DONE_ALREADY_DONE);
 | 
			
		||||
        confirm.run(this, new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
 
 | 
			
		||||
@@ -127,12 +127,12 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                // Check allowed cluster size
 | 
			
		||||
                cluster = new PlotCluster(area, pos1, pos2, player.getUUID());
 | 
			
		||||
                int current;
 | 
			
		||||
                if (Settings.GLOBAL_LIMIT) {
 | 
			
		||||
                if (Settings.LIMIT.GLOBAL) {
 | 
			
		||||
                    current = player.getPlayerClusterCount();
 | 
			
		||||
                } else {
 | 
			
		||||
                    current = player.getPlayerClusterCount(player.getLocation().getWorld());
 | 
			
		||||
                }
 | 
			
		||||
                int allowed = Permissions.hasPermissionRange(player, "plots.cluster", Settings.MAX_PLOTS);
 | 
			
		||||
                int allowed = Permissions.hasPermissionRange(player, "plots.cluster", Settings.LIMIT.MAX_PLOTS);
 | 
			
		||||
                if (current + cluster.getArea() > allowed) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.cluster." + (current + cluster.getArea()));
 | 
			
		||||
                    return false;
 | 
			
		||||
@@ -257,13 +257,13 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                }
 | 
			
		||||
                // Check allowed cluster size
 | 
			
		||||
                int current;
 | 
			
		||||
                if (Settings.GLOBAL_LIMIT) {
 | 
			
		||||
                if (Settings.LIMIT.GLOBAL) {
 | 
			
		||||
                    current = player.getPlayerClusterCount();
 | 
			
		||||
                } else {
 | 
			
		||||
                    current = player.getPlayerClusterCount(player.getLocation().getWorld());
 | 
			
		||||
                }
 | 
			
		||||
                current -= cluster.getArea() + (1 + pos2.x - pos1.x) * (1 + pos2.y - pos1.y);
 | 
			
		||||
                int allowed = Permissions.hasPermissionRange(player, "plots.cluster", Settings.MAX_PLOTS);
 | 
			
		||||
                int allowed = Permissions.hasPermissionRange(player, "plots.cluster", Settings.LIMIT.MAX_PLOTS);
 | 
			
		||||
                if (current + cluster.getArea() > allowed) {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.cluster." + (current + cluster.getArea()));
 | 
			
		||||
                    return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ public class Continue extends SubCommand {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        int size = plot.getConnectedPlots().size();
 | 
			
		||||
        if (Settings.DONE_COUNTS_TOWARDS_LIMIT && (player.getAllowedPlots() < player.getPlotCount() + size)) {
 | 
			
		||||
        if (Settings.DONE.COUNTS_TOWARDS_LIMIT && (player.getAllowedPlots() < player.getPlotCount() + size)) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.admin.command.continue");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -90,7 +90,7 @@ public class Database extends SubCommand {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    MainUtil.sendMessage(player, "&6Starting...");
 | 
			
		||||
                    implementation = new SQLite(file.getPath());
 | 
			
		||||
                    implementation = new SQLite(file);
 | 
			
		||||
                    SQLManager manager = new SQLManager(implementation, args.length == 3 ? args[2] : "", true);
 | 
			
		||||
                    HashMap<String, HashMap<PlotId, Plot>> map = manager.getPlots();
 | 
			
		||||
                    plots = new ArrayList<>();
 | 
			
		||||
@@ -141,7 +141,8 @@ public class Database extends SubCommand {
 | 
			
		||||
                    if (args.length < 2) {
 | 
			
		||||
                        return MainUtil.sendMessage(player, "/plot database sqlite [file]");
 | 
			
		||||
                    }
 | 
			
		||||
                    implementation = new SQLite(PS.get().IMP.getDirectory() + File.separator + args[1] + ".db");
 | 
			
		||||
                    File sqliteFile = MainUtil.getFile(PS.get().IMP.getDirectory(), args[1] + ".db");
 | 
			
		||||
                    implementation = new SQLite(sqliteFile);
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    return MainUtil.sendMessage(player, "/plot database [sqlite/mysql]");
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ import com.intellectualcrafters.plot.object.ConsolePlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotArea;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotBlock;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
@@ -25,7 +25,7 @@ import com.intellectualcrafters.plot.util.AbstractTitle;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ChunkManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MathMan;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SchematicHandler;
 | 
			
		||||
@@ -68,11 +68,11 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
    public DebugExec() {
 | 
			
		||||
        try {
 | 
			
		||||
            if (PS.get() != null) {
 | 
			
		||||
                File file = new File(PS.get().IMP.getDirectory(), "scripts" + File.separator + "start.js");
 | 
			
		||||
                File file = new File(PS.get().IMP.getDirectory(), Settings.PATHS.SCRIPTS + File.separator + "start.js");
 | 
			
		||||
                if (file.exists()) {
 | 
			
		||||
                    init();
 | 
			
		||||
                    String script = StringMan.join(Files
 | 
			
		||||
                                    .readLines(new File(new File(PS.get().IMP.getDirectory() + File.separator + "scripts"), "start.js"),
 | 
			
		||||
                                    .readLines(new File(new File(PS.get().IMP.getDirectory() + File.separator + Settings.PATHS.SCRIPTS), "start.js"),
 | 
			
		||||
                                            StandardCharsets.UTF_8),
 | 
			
		||||
                            System.getProperty("line.separator"));
 | 
			
		||||
                    this.scope.put("THIS", this);
 | 
			
		||||
@@ -160,11 +160,9 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                        MainUtil.sendMessage(player, C.NOT_IN_PLOT);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    PlotAnalysis analysis = plot.getComplexity();
 | 
			
		||||
                    PlotAnalysis analysis = plot.getComplexity(null);
 | 
			
		||||
                    if (analysis != null) {
 | 
			
		||||
                        int complexity = analysis.getComplexity();
 | 
			
		||||
                        MainUtil.sendMessage(player, "Changes/column: " + analysis.changes / 1.0);
 | 
			
		||||
                        MainUtil.sendMessage(player, "Complexity: " + complexity);
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    MainUtil.sendMessage(player, "$1Starting task...");
 | 
			
		||||
@@ -251,13 +249,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                    if (ExpireManager.IMP == null) {
 | 
			
		||||
                        ExpireManager.IMP = new ExpireManager();
 | 
			
		||||
                    }
 | 
			
		||||
                    boolean result;
 | 
			
		||||
                    if (Settings.AUTO_CLEAR_CONFIRMATION) {
 | 
			
		||||
                        result = ExpireManager.IMP.runConfirmedTask();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        result = ExpireManager.IMP.runAutomatedTask();
 | 
			
		||||
                    }
 | 
			
		||||
                    if (result) {
 | 
			
		||||
                    if (ExpireManager.IMP.runAutomatedTask()) {
 | 
			
		||||
                        return MainUtil.sendMessage(player, "Started plot expiry task");
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return MainUtil.sendMessage(player, "Plot expiry task already started");
 | 
			
		||||
@@ -291,7 +283,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                case "addcmd":
 | 
			
		||||
                    try {
 | 
			
		||||
                        final String cmd = StringMan.join(Files
 | 
			
		||||
                                        .readLines(MainUtil.getFile(new File(PS.get().IMP.getDirectory() + File.separator + "scripts"), args[1]),
 | 
			
		||||
                                        .readLines(MainUtil.getFile(new File(PS.get().IMP.getDirectory() + File.separator + Settings.PATHS.SCRIPTS), args[1]),
 | 
			
		||||
                                                StandardCharsets.UTF_8),
 | 
			
		||||
                                System.getProperty("line.separator"));
 | 
			
		||||
                        new Command(MainCommand.getInstance(), true, args[1].split("\\.")[0], null, RequiredType.NONE, CommandCategory.DEBUG) {
 | 
			
		||||
@@ -318,7 +310,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                case "run":
 | 
			
		||||
                    try {
 | 
			
		||||
                        script = StringMan.join(Files
 | 
			
		||||
                                        .readLines(MainUtil.getFile(new File(PS.get().IMP.getDirectory() + File.separator + "scripts"), args[1]),
 | 
			
		||||
                                        .readLines(MainUtil.getFile(new File(PS.get().IMP.getDirectory() + File.separator + Settings.PATHS.SCRIPTS), args[1]),
 | 
			
		||||
                                                StandardCharsets.UTF_8),
 | 
			
		||||
                                System.getProperty("line.separator"));
 | 
			
		||||
                        if (args.length > 2) {
 | 
			
		||||
@@ -334,7 +326,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                case "list-scripts":
 | 
			
		||||
                    String path = PS.get().IMP.getDirectory() + File.separator + "scripts";
 | 
			
		||||
                    String path = PS.get().IMP.getDirectory() + File.separator + Settings.PATHS.SCRIPTS;
 | 
			
		||||
                    File folder = new File(path);
 | 
			
		||||
                    File[] filesArray = folder.listFiles();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ public class DebugPaste extends SubCommand {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                try {
 | 
			
		||||
                    String settingsYML = HastebinUtility.upload(PS.get().configFile);
 | 
			
		||||
                    String settingsYML = HastebinUtility.upload(PS.get().worldsFile);
 | 
			
		||||
                    String latestLOG;
 | 
			
		||||
                    try {
 | 
			
		||||
                        latestLOG = HastebinUtility.upload(new File(PS.get().IMP.getDirectory(), "../../logs/latest.log"));
 | 
			
		||||
@@ -43,7 +43,7 @@ public class DebugPaste extends SubCommand {
 | 
			
		||||
                    b.append("\n# Server Information\n");
 | 
			
		||||
                    int[] sVersion = PS.get().IMP.getServerVersion();
 | 
			
		||||
                    b.append("version.server: ").append(sVersion[0]).append('.').append(sVersion[1]).append('.').append(sVersion[2]).append('\n');
 | 
			
		||||
                    b.append("online_mode: ").append(UUIDHandler.getUUIDWrapper()).append(';').append(!Settings.OFFLINE_MODE).append('\n');
 | 
			
		||||
                    b.append("online_mode: ").append(UUIDHandler.getUUIDWrapper()).append(';').append(!Settings.UUID.OFFLINE).append('\n');
 | 
			
		||||
                    b.append("plugins:");
 | 
			
		||||
                    for (String id : PS.get().IMP.getPluginIds()) {
 | 
			
		||||
                        String[] split = id.split(":");
 | 
			
		||||
 
 | 
			
		||||
@@ -6,11 +6,12 @@ import com.intellectualcrafters.plot.flag.Flags;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
 | 
			
		||||
import com.plotsquared.general.commands.CommandDeclaration;
 | 
			
		||||
 | 
			
		||||
@CommandDeclaration(command = "done",
 | 
			
		||||
@@ -42,19 +43,30 @@ public class Done extends SubCommand {
 | 
			
		||||
        }
 | 
			
		||||
        plot.addRunning();
 | 
			
		||||
        MainUtil.sendMessage(player, C.GENERATING_LINK);
 | 
			
		||||
        HybridUtils.manager.analyzePlot(plot, new RunnableVal<PlotAnalysis>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run(PlotAnalysis value) {
 | 
			
		||||
                plot.removeRunning();
 | 
			
		||||
                if ((value == null) || (value.getComplexity() >= Settings.CLEAR_THRESHOLD)) {
 | 
			
		||||
                    long flagValue = System.currentTimeMillis() / 1000;
 | 
			
		||||
                    plot.setFlag(Flags.DONE,flagValue);
 | 
			
		||||
                    MainUtil.sendMessage(player, C.DONE_SUCCESS);
 | 
			
		||||
                } else {
 | 
			
		||||
                    MainUtil.sendMessage(player, C.DONE_INSUFFICIENT_COMPLEXITY);
 | 
			
		||||
        final Settings.AUTO_CLEAR doneRequirements = Settings.AUTO_CLEAR.get("done");
 | 
			
		||||
        if (ExpireManager.IMP == null || doneRequirements == null) {
 | 
			
		||||
            finish(plot, player, true);
 | 
			
		||||
            plot.removeRunning();
 | 
			
		||||
        } else {
 | 
			
		||||
            HybridUtils.manager.analyzePlot(plot, new RunnableVal<PlotAnalysis>() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run(PlotAnalysis value) {
 | 
			
		||||
                    plot.removeRunning();
 | 
			
		||||
                    boolean result = value.getComplexity(doneRequirements) <= doneRequirements.THRESHOLD;
 | 
			
		||||
                    finish(plot, player, result);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void finish(Plot plot, PlotPlayer pp, boolean success) {
 | 
			
		||||
        if (success) {
 | 
			
		||||
            long flagValue = System.currentTimeMillis() / 1000;
 | 
			
		||||
            plot.setFlag(Flags.DONE, flagValue);
 | 
			
		||||
            MainUtil.sendMessage(pp, C.DONE_SUCCESS);
 | 
			
		||||
        } else {
 | 
			
		||||
            MainUtil.sendMessage(pp, C.DONE_INSUFFICIENT_COMPLEXITY);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ public class Download extends SubCommand {
 | 
			
		||||
            MainUtil.sendMessage(player, C.PLOT_UNOWNED);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if ((Settings.DOWNLOAD_REQUIRES_DONE && (!plot.getFlag(Flags.DONE).isPresent())) && !Permissions
 | 
			
		||||
        if ((Settings.DONE.REQUIRED_FOR_DOWNLOAD && (!plot.getFlag(Flags.DONE).isPresent())) && !Permissions
 | 
			
		||||
                .hasPermission(player, "plots.admin.command.download")) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.DONE_NOT_DONE);
 | 
			
		||||
            return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Rating;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal3;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MathMan;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ public class Load extends SubCommand {
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCommand(final PlotPlayer player, String[] args) {
 | 
			
		||||
 | 
			
		||||
        if (!Settings.METRICS) {
 | 
			
		||||
        if (!Settings.ENABLED_COMPONENTS.METRICS) {
 | 
			
		||||
            MainUtil.sendMessage(player,
 | 
			
		||||
                    "&cPlease enable metrics in order to use this command.\n&7 - Or host it yourself if you don't like the free service");
 | 
			
		||||
            return false;
 | 
			
		||||
@@ -75,7 +75,7 @@ public class Load extends SubCommand {
 | 
			
		||||
                }
 | 
			
		||||
                final URL url;
 | 
			
		||||
                try {
 | 
			
		||||
                    url = new URL(Settings.WEB_URL + "saves/" + player.getUUID() + '/' + schematic + ".schematic");
 | 
			
		||||
                    url = new URL(Settings.WEB.URL + "saves/" + player.getUUID() + '/' + schematic + ".schematic");
 | 
			
		||||
                } catch (MalformedURLException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                    MainUtil.sendMessage(player, C.LOAD_FAILED);
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,7 @@ public class Merge extends SubCommand {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        final int size = plot.getConnectedPlots().size();
 | 
			
		||||
        final int maxSize = Permissions.hasPermissionRange(player, "plots.merge", Settings.MAX_PLOTS);
 | 
			
		||||
        final int maxSize = Permissions.hasPermissionRange(player, "plots.merge", Settings.LIMIT.MAX_PLOTS);
 | 
			
		||||
        if (size - 1 > maxSize) {
 | 
			
		||||
            MainUtil.sendMessage(player, C.NO_PERMISSION, "plots.merge." + (size + 1));
 | 
			
		||||
            return false;
 | 
			
		||||
@@ -100,7 +100,7 @@ public class Merge extends SubCommand {
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if ("all".equalsIgnoreCase(args[0]) || "auto".equalsIgnoreCase(args[0])) {
 | 
			
		||||
                boolean terrain = Settings.MERGE_REMOVES_ROADS;
 | 
			
		||||
                boolean terrain = true;
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    terrain = "true".equalsIgnoreCase(args[1]);
 | 
			
		||||
                }
 | 
			
		||||
@@ -132,7 +132,7 @@ public class Merge extends SubCommand {
 | 
			
		||||
        if (args.length == 2) {
 | 
			
		||||
            terrain = "true".equalsIgnoreCase(args[1]);
 | 
			
		||||
        } else {
 | 
			
		||||
            terrain = Settings.MERGE_REMOVES_ROADS;
 | 
			
		||||
            terrain = true;
 | 
			
		||||
        }
 | 
			
		||||
        if (plot.autoMerge(direction, maxSize - size, uuid, terrain)) {
 | 
			
		||||
            if (EconHandler.manager != null && plotArea.USE_ECONOMY && price > 0d) {
 | 
			
		||||
 
 | 
			
		||||
@@ -65,7 +65,7 @@ public class Owner extends SetCommand {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            int size = plots.size();
 | 
			
		||||
            int currentPlots = (Settings.GLOBAL_LIMIT ? other.getPlotCount() : other.getPlotCount(plot.getArea().worldname)) + size;
 | 
			
		||||
            int currentPlots = (Settings.LIMIT.GLOBAL ? other.getPlotCount() : other.getPlotCount(plot.getArea().worldname)) + size;
 | 
			
		||||
            if (currentPlots > other.getAllowedPlots()) {
 | 
			
		||||
                sendMessage(player, C.CANT_TRANSFER_MORE_PLOTS);
 | 
			
		||||
                return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ public class Rate extends SubCommand {
 | 
			
		||||
                });
 | 
			
		||||
                UUID uuid = player.getUUID();
 | 
			
		||||
                for (Plot p : plots) {
 | 
			
		||||
                    if ((!Settings.REQUIRE_DONE || p.hasFlag(Flags.DONE)) && p.isBasePlot() && (p.hasRatings() || !p.getRatings()
 | 
			
		||||
                    if ((!Settings.DONE.REQUIRED_FOR_RATINGS || p.hasFlag(Flags.DONE)) && p.isBasePlot() && (p.hasRatings() || !p.getRatings()
 | 
			
		||||
                            .containsKey(uuid)) && !p.isAdded(uuid)) {
 | 
			
		||||
                        p.teleportPlayer(player);
 | 
			
		||||
                        MainUtil.sendMessage(player, C.RATE_THIS);
 | 
			
		||||
@@ -85,11 +85,11 @@ public class Rate extends SubCommand {
 | 
			
		||||
            sendMessage(player, C.RATING_NOT_YOUR_OWN);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.REQUIRE_DONE && !plot.hasFlag(Flags.DONE)) {
 | 
			
		||||
        if (Settings.DONE.REQUIRED_FOR_RATINGS && !plot.hasFlag(Flags.DONE)) {
 | 
			
		||||
            sendMessage(player, C.RATING_NOT_DONE);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.RATING_CATEGORIES != null && !Settings.RATING_CATEGORIES.isEmpty()) {
 | 
			
		||||
        if (Settings.RATINGS.CATEGORIES != null && !Settings.RATINGS.CATEGORIES.isEmpty()) {
 | 
			
		||||
            final Runnable run = new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
@@ -99,13 +99,13 @@ public class Rate extends SubCommand {
 | 
			
		||||
                    }
 | 
			
		||||
                    final MutableInt index = new MutableInt(0);
 | 
			
		||||
                    final MutableInt rating = new MutableInt(0);
 | 
			
		||||
                    String title = Settings.RATING_CATEGORIES.get(0);
 | 
			
		||||
                    String title = Settings.RATINGS.CATEGORIES.get(0);
 | 
			
		||||
                    PlotInventory inventory = new PlotInventory(player, 1, title) {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public boolean onClick(int i) {
 | 
			
		||||
                            rating.add((i + 1) * Math.pow(10, index.getValue()));
 | 
			
		||||
                            index.increment();
 | 
			
		||||
                            if (index.getValue() >= Settings.RATING_CATEGORIES.size()) {
 | 
			
		||||
                            if (index.getValue() >= Settings.RATINGS.CATEGORIES.size()) {
 | 
			
		||||
                                int rV = rating.getValue();
 | 
			
		||||
                                Rating result = EventUtil.manager.callRating(this.player, plot, new Rating(rV));
 | 
			
		||||
                                plot.addRating(this.player.getUUID(), result);
 | 
			
		||||
@@ -118,7 +118,7 @@ public class Rate extends SubCommand {
 | 
			
		||||
                                }
 | 
			
		||||
                                return false;
 | 
			
		||||
                            }
 | 
			
		||||
                            setTitle(Settings.RATING_CATEGORIES.get(index.getValue()));
 | 
			
		||||
                            setTitle(Settings.RATINGS.CATEGORIES.get(index.getValue()));
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
@@ -135,7 +135,7 @@ public class Rate extends SubCommand {
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            if (plot.getSettings().ratings == null) {
 | 
			
		||||
                if (!Settings.CACHE_RATINGS) {
 | 
			
		||||
                if (!Settings.ENABLED_COMPONENTS.RATING_CACHE) {
 | 
			
		||||
                    TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
@@ -180,7 +180,7 @@ public class Rate extends SubCommand {
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        if (plot.getSettings().ratings == null) {
 | 
			
		||||
            if (!Settings.CACHE_RATINGS) {
 | 
			
		||||
            if (!Settings.ENABLED_COMPONENTS.RATING_CACHE) {
 | 
			
		||||
                TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
package com.intellectualcrafters.plot.commands;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.ConfigurationSection;
 | 
			
		||||
import com.intellectualcrafters.configuration.InvalidConfigurationException;
 | 
			
		||||
import com.intellectualcrafters.configuration.MemorySection;
 | 
			
		||||
import com.intellectualcrafters.configuration.file.YamlConfiguration;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
@@ -11,7 +10,6 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.plotsquared.general.commands.CommandDeclaration;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
@@ -27,14 +25,12 @@ public class Reload extends SubCommand {
 | 
			
		||||
        try {
 | 
			
		||||
            // The following won't affect world generation, as that has to be
 | 
			
		||||
            // loaded during startup unfortunately.
 | 
			
		||||
            PS.get().style.load(PS.get().styleFile);
 | 
			
		||||
            PS.get().config.load(PS.get().configFile);
 | 
			
		||||
            PS.get().setupConfig();
 | 
			
		||||
            PS.get().setupConfigs();
 | 
			
		||||
            C.load(PS.get().translationFile);
 | 
			
		||||
            PS.get().foreachPlotArea(new RunnableVal<PlotArea>() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run(PlotArea area) {
 | 
			
		||||
                    ConfigurationSection worldSection = PS.get().config.getConfigurationSection("worlds." + area.worldname);
 | 
			
		||||
                    ConfigurationSection worldSection = PS.get().worlds.getConfigurationSection("worlds." + area.worldname);
 | 
			
		||||
                    if (area.TYPE != 2 || !worldSection.contains("areas")) {
 | 
			
		||||
                        area.saveConfiguration(worldSection);
 | 
			
		||||
                        area.loadDefaultConfiguration(worldSection);
 | 
			
		||||
@@ -77,9 +73,9 @@ public class Reload extends SubCommand {
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            PS.get().config.save(PS.get().configFile);
 | 
			
		||||
            PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
            MainUtil.sendMessage(player, C.RELOADED_CONFIGS);
 | 
			
		||||
        } catch (InvalidConfigurationException | IOException e) {
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            MainUtil.sendMessage(player, C.RELOAD_FAILED);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ public class Save extends SubCommand {
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCommand(final PlotPlayer player, String[] args) {
 | 
			
		||||
 | 
			
		||||
        if (!Settings.METRICS) {
 | 
			
		||||
        if (!Settings.ENABLED_COMPONENTS.METRICS) {
 | 
			
		||||
            MainUtil.sendMessage(player,
 | 
			
		||||
                    "&cPlease enable metrics in order to use this command.\n&7 - Or host it yourself if you don't like the free service");
 | 
			
		||||
            return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ public class SchematicCmd extends SubCommand {
 | 
			
		||||
                        if (location.startsWith("url:")) {
 | 
			
		||||
                            try {
 | 
			
		||||
                                UUID uuid = UUID.fromString(location.substring(4));
 | 
			
		||||
                                URL base = new URL(Settings.WEB_URL);
 | 
			
		||||
                                URL base = new URL(Settings.WEB.URL);
 | 
			
		||||
                                URL url = new URL(base, "uploads/" + uuid + ".schematic");
 | 
			
		||||
                                schematic = SchematicHandler.manager.getSchematic(url);
 | 
			
		||||
                            } catch (Exception e) {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import com.intellectualcrafters.configuration.file.YamlConfiguration;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.C;
 | 
			
		||||
import com.intellectualcrafters.plot.config.ConfigurationNode;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.object.FileBytes;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotArea;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotManager;
 | 
			
		||||
@@ -38,7 +39,7 @@ public class Template extends SubCommand {
 | 
			
		||||
 | 
			
		||||
    public static boolean extractAllFiles(String world, String template) {
 | 
			
		||||
        try {
 | 
			
		||||
            File folder = new File(PS.get().IMP.getDirectory() + File.separator + "templates");
 | 
			
		||||
            File folder = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.PATHS.TEMPLATES);
 | 
			
		||||
            if (!folder.exists()) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
@@ -75,7 +76,7 @@ public class Template extends SubCommand {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static byte[] getBytes(PlotArea plotArea) {
 | 
			
		||||
        ConfigurationSection section = PS.get().config.getConfigurationSection("worlds." + plotArea.worldname);
 | 
			
		||||
        ConfigurationSection section = PS.get().worlds.getConfigurationSection("worlds." + plotArea.worldname);
 | 
			
		||||
        YamlConfiguration config = new YamlConfiguration();
 | 
			
		||||
        String generator = SetupUtils.manager.getGenerator(plotArea);
 | 
			
		||||
        if (generator != null) {
 | 
			
		||||
@@ -88,7 +89,7 @@ public class Template extends SubCommand {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void zipAll(String world, Set<FileBytes> files) throws IOException {
 | 
			
		||||
        File output = new File(PS.get().IMP.getDirectory() + File.separator + "templates");
 | 
			
		||||
        File output = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.PATHS.TEMPLATES);
 | 
			
		||||
        output.mkdirs();
 | 
			
		||||
        try (FileOutputStream fos = new FileOutputStream(output + File.separator + world + ".template");
 | 
			
		||||
                ZipOutputStream zos = new ZipOutputStream(fos)) {
 | 
			
		||||
@@ -133,12 +134,12 @@ public class Template extends SubCommand {
 | 
			
		||||
                    MainUtil.sendMessage(player, "&cInvalid template file: " + args[2] + ".template");
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                File worldFile = new File(PS.get().IMP.getDirectory() + File.separator + "templates" + File.separator + "tmp-data.yml");
 | 
			
		||||
                File worldFile = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.PATHS.TEMPLATES + File.separator + "tmp-data.yml");
 | 
			
		||||
                YamlConfiguration worldConfig = YamlConfiguration.loadConfiguration(worldFile);
 | 
			
		||||
                PS.get().config.set("worlds." + world, worldConfig.get(""));
 | 
			
		||||
                PS.get().worlds.set("worlds." + world, worldConfig.get(""));
 | 
			
		||||
                try {
 | 
			
		||||
                    PS.get().config.save(PS.get().configFile);
 | 
			
		||||
                    PS.get().config.load(PS.get().configFile);
 | 
			
		||||
                    PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
                    PS.get().worlds.load(PS.get().worldsFile);
 | 
			
		||||
                } catch (InvalidConfigurationException | IOException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,408 @@
 | 
			
		||||
package com.intellectualcrafters.plot.config;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.MemorySection;
 | 
			
		||||
import com.intellectualcrafters.configuration.file.YamlConfiguration;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.util.StringMan;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.PrintWriter;
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
import java.lang.invoke.MethodHandles;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public class Config {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the value for a node<br>
 | 
			
		||||
     *     Probably throws some error if you try to get a non existent key
 | 
			
		||||
     * @param key
 | 
			
		||||
     * @param <T>
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static <T> T get(String key, Class root) {
 | 
			
		||||
        String[] split = key.split("\\.");
 | 
			
		||||
        Object instance = getInstance(split, root);
 | 
			
		||||
        if (instance != null) {
 | 
			
		||||
            Field field = getField(split, instance);
 | 
			
		||||
            if (field != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    return (T) field.get(instance);
 | 
			
		||||
                } catch (IllegalAccessException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        PS.debug("Failed to get config option: " + key);
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the value of a specific node<br>
 | 
			
		||||
     *     Probably throws some error if you supply non existing keys or invalid values
 | 
			
		||||
     * @param key config node
 | 
			
		||||
     * @param value value
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    public static void set(String key, Object value, Class root) {
 | 
			
		||||
        String[] split = key.split("\\.");
 | 
			
		||||
        Object instance = getInstance(split, root);
 | 
			
		||||
        if (instance != null) {
 | 
			
		||||
            Field field = getField(split, instance);
 | 
			
		||||
            if (field != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    if (field.getAnnotation(Final.class) != null) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    field.set(instance, value);
 | 
			
		||||
                    return;
 | 
			
		||||
                } catch (IllegalAccessException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        PS.debug("Failed to set config option: " + key + ": " + value + " | " + instance);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean load(File file, Class root) {
 | 
			
		||||
        if (!file.exists()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
 | 
			
		||||
        for (String key : yml.getKeys(true)) {
 | 
			
		||||
            Object value = yml.get(key);
 | 
			
		||||
            if (value instanceof MemorySection) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            set(key, value, root);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set all values in the file (load first to avoid overwriting)
 | 
			
		||||
     * @param file
 | 
			
		||||
     */
 | 
			
		||||
    public static void save(File file, Class root) {
 | 
			
		||||
        try {
 | 
			
		||||
            if (!file.exists()) {
 | 
			
		||||
                file.getParentFile().mkdirs();
 | 
			
		||||
                file.createNewFile();
 | 
			
		||||
            }
 | 
			
		||||
            PrintWriter writer = new PrintWriter(file);
 | 
			
		||||
            Class clazz = root;
 | 
			
		||||
            Object instance = root.newInstance();
 | 
			
		||||
            save(writer, clazz, instance, 0);
 | 
			
		||||
            writer.close();
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Indicates that a field should be instantiated / created
 | 
			
		||||
     */
 | 
			
		||||
    @Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
    @Target({ElementType.FIELD})
 | 
			
		||||
    public  @interface Create {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Indicates that a field cannot be modified
 | 
			
		||||
     */
 | 
			
		||||
    @Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
    @Target({ElementType.FIELD})
 | 
			
		||||
    public @interface Final {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a comment
 | 
			
		||||
     */
 | 
			
		||||
    @Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
    @Target({ElementType.FIELD,ElementType.TYPE})
 | 
			
		||||
    public @interface Comment {
 | 
			
		||||
        String[] value();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The names of any default blocks
 | 
			
		||||
     */
 | 
			
		||||
    @Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
    @Target({ElementType.FIELD,ElementType.TYPE})
 | 
			
		||||
    public @interface BlockName {
 | 
			
		||||
        String[] value();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Any field or class with is not part of the config
 | 
			
		||||
     */
 | 
			
		||||
    @Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
    @Target({ElementType.FIELD,ElementType.TYPE})
 | 
			
		||||
    public @interface Ignore {}
 | 
			
		||||
 | 
			
		||||
    @Ignore // This is not part of the config
 | 
			
		||||
    public static class ConfigBlock<T> {
 | 
			
		||||
 | 
			
		||||
        private HashMap<String, T> INSTANCES = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
        public T get(String key) {
 | 
			
		||||
            return INSTANCES.get(key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void put(String key, T value) {
 | 
			
		||||
            INSTANCES.put(key, value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Map<String, T> getRaw() {
 | 
			
		||||
            return INSTANCES;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the static fields in a section
 | 
			
		||||
     * @param clazz
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static Map<String, Object> getFields(Class clazz) {
 | 
			
		||||
        HashMap<String, Object> map = new HashMap<>();
 | 
			
		||||
        for (Field field : clazz.getFields()) {
 | 
			
		||||
            if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
 | 
			
		||||
                try {
 | 
			
		||||
                    map.put(toNodeName(field.getName()), field.get(null));
 | 
			
		||||
                } catch (IllegalAccessException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return map;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static String toYamlString(Object value, String spacing) {
 | 
			
		||||
        if (value instanceof List) {
 | 
			
		||||
            Collection<?> listValue = (Collection<?>) value;
 | 
			
		||||
            if (listValue.isEmpty()) {
 | 
			
		||||
                return "[]";
 | 
			
		||||
            }
 | 
			
		||||
            StringBuilder m = new StringBuilder();
 | 
			
		||||
            for (Object obj : listValue) {
 | 
			
		||||
                m.append(System.lineSeparator() + spacing + "- " + toYamlString(obj, spacing));
 | 
			
		||||
            }
 | 
			
		||||
            return m.toString();
 | 
			
		||||
        }
 | 
			
		||||
        if (value instanceof String) {
 | 
			
		||||
            String stringValue = (String) value;
 | 
			
		||||
            if (stringValue.isEmpty()) {
 | 
			
		||||
                return "''";
 | 
			
		||||
            }
 | 
			
		||||
            return "\"" + stringValue + "\"";
 | 
			
		||||
        }
 | 
			
		||||
        return value != null ? value.toString() : "null";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void save(PrintWriter writer, Class clazz, Object instance, int indent) {
 | 
			
		||||
        try {
 | 
			
		||||
            String CTRF = System.lineSeparator();
 | 
			
		||||
            String spacing = StringMan.repeat(" ", indent);
 | 
			
		||||
            for (Field field : clazz.getFields()) {
 | 
			
		||||
                if (field.getAnnotation(Ignore.class) != null) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                Comment comment = field.getAnnotation(Comment.class);
 | 
			
		||||
                if (comment != null) {
 | 
			
		||||
                    for (String commentLine : comment.value()) {
 | 
			
		||||
                        writer.write(spacing + "# " + commentLine + CTRF);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Create create = field.getAnnotation(Create.class);
 | 
			
		||||
                if (create != null) {
 | 
			
		||||
                    Object value = field.get(instance);
 | 
			
		||||
                    if (value == null && field.getType() != ConfigBlock.class) {
 | 
			
		||||
                        setAccessible(field);
 | 
			
		||||
                        Class<?>[] classes = clazz.getDeclaredClasses();
 | 
			
		||||
                        for (Class current : classes) {
 | 
			
		||||
                            if (StringMan.isEqual(current.getSimpleName(), field.getName())) {
 | 
			
		||||
                                field.set(instance, current.newInstance());
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else {
 | 
			
		||||
                    writer.write(spacing + toNodeName(field.getName() + ": ") + toYamlString(field.get(instance), spacing) + CTRF);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (Class<?> current : clazz.getClasses()) {
 | 
			
		||||
                if (current.isInterface() || current.getAnnotation(Ignore.class) != null) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (indent == 0) {
 | 
			
		||||
                    writer.write(CTRF);
 | 
			
		||||
                }
 | 
			
		||||
                Comment comment = current.getAnnotation(Comment.class);
 | 
			
		||||
                if (comment != null) {
 | 
			
		||||
                    for (String commentLine : comment.value()) {
 | 
			
		||||
                        writer.write(spacing + "# " + commentLine + CTRF);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
 | 
			
		||||
                BlockName blockNames = current.getAnnotation(BlockName.class);
 | 
			
		||||
                if (blockNames != null) {
 | 
			
		||||
                    Field instanceField = clazz.getDeclaredField(toFieldName(current.getSimpleName()));
 | 
			
		||||
                    setAccessible(instanceField);
 | 
			
		||||
                    ConfigBlock value = (ConfigBlock) instanceField.get(instance);
 | 
			
		||||
                    if (value == null) {
 | 
			
		||||
                        value = new ConfigBlock();
 | 
			
		||||
                        instanceField.set(instance, value);
 | 
			
		||||
                        for (String blockName : blockNames.value()) {
 | 
			
		||||
                            value.put(blockName, current.newInstance());
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    // Save each instance
 | 
			
		||||
                    for (Map.Entry<String, Object> entry: ((Map<String, Object>) value.getRaw()).entrySet()) {
 | 
			
		||||
                        String key = entry.getKey();
 | 
			
		||||
                        writer.write(spacing + "  " + toNodeName(key) + ":" + CTRF);
 | 
			
		||||
                        save(writer, current, entry.getValue(), indent + 4);
 | 
			
		||||
                    }
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else {
 | 
			
		||||
                    save(writer, current, current.newInstance(), indent + 2);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the field for a specific config node
 | 
			
		||||
     * @param split the node (split by period)
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private static Field getField(String[] split, Class root) {
 | 
			
		||||
        Object instance = getInstance(split, root);
 | 
			
		||||
        if (instance == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return getField(split, instance);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the field for a specific config node and instance<br>
 | 
			
		||||
     *     Note: As expiry can have multiple blocks there will be multiple instances
 | 
			
		||||
     * @param split the node (split by period)
 | 
			
		||||
     * @param instance the instance
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private static Field getField(String[] split, Object instance) {
 | 
			
		||||
        try {
 | 
			
		||||
            Field field = instance.getClass().getField(toFieldName(split[split.length - 1]));
 | 
			
		||||
            setAccessible(field);
 | 
			
		||||
            return field;
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            PS.debug("Invalid config field: " + StringMan.join(split, ".") + " for " + toNodeName(instance.getClass().getSimpleName()));
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the instance for a specific config node
 | 
			
		||||
     * @param split the node (split by period)
 | 
			
		||||
     * @return The instance or null
 | 
			
		||||
     */
 | 
			
		||||
    private static Object getInstance(String[] split, Class root) {
 | 
			
		||||
        try {
 | 
			
		||||
            Class<?> clazz = root == null ? MethodHandles.lookup().lookupClass() : root;
 | 
			
		||||
            Object instance = clazz.newInstance();
 | 
			
		||||
            while (split.length > 0) {
 | 
			
		||||
                switch (split.length) {
 | 
			
		||||
                    case 1:
 | 
			
		||||
                        return instance;
 | 
			
		||||
                    default:
 | 
			
		||||
                        Class found = null;
 | 
			
		||||
                        Class<?>[] classes = clazz.getDeclaredClasses();
 | 
			
		||||
                        for (Class current : classes) {
 | 
			
		||||
                            if (StringMan.isEqual(current.getSimpleName(), toFieldName(split[0]))) {
 | 
			
		||||
                                found = current;
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        try {
 | 
			
		||||
                            Field instanceField = clazz.getDeclaredField(toFieldName(split[0]));
 | 
			
		||||
                            setAccessible(instanceField);
 | 
			
		||||
                            if (instanceField.getType() != ConfigBlock.class) {
 | 
			
		||||
                                Object value = instanceField.get(instance);
 | 
			
		||||
                                if (value == null) {
 | 
			
		||||
                                    value = found.newInstance();
 | 
			
		||||
                                    instanceField.set(instance, value);
 | 
			
		||||
                                }
 | 
			
		||||
                                clazz = found;
 | 
			
		||||
                                instance = value;
 | 
			
		||||
                                split = Arrays.copyOfRange(split, 1, split.length);
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                            ConfigBlock value = (ConfigBlock) instanceField.get(instance);
 | 
			
		||||
                            if (value == null) {
 | 
			
		||||
                                value = new ConfigBlock();
 | 
			
		||||
                                instanceField.set(instance, value);
 | 
			
		||||
                            }
 | 
			
		||||
                            instance = value.get(split[1]);
 | 
			
		||||
                            if (instance == null) {
 | 
			
		||||
                                instance = found.newInstance();
 | 
			
		||||
                                value.put(split[1], instance);
 | 
			
		||||
                            }
 | 
			
		||||
                            clazz = found;
 | 
			
		||||
                            split = Arrays.copyOfRange(split, 2, split.length);
 | 
			
		||||
                            continue;
 | 
			
		||||
                        } catch (NoSuchFieldException ignore) {}
 | 
			
		||||
                        if (found != null) {
 | 
			
		||||
                            split = Arrays.copyOfRange(split, 1, split.length);
 | 
			
		||||
                            clazz = found;
 | 
			
		||||
                            instance = clazz.newInstance();
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                        return null;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Translate a node to a java field name
 | 
			
		||||
     * @param node
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private static String toFieldName(String node) {
 | 
			
		||||
        return node.toUpperCase().replaceAll("-","_");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Translate a field to a config node
 | 
			
		||||
     * @param field
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private static String toNodeName(String field) {
 | 
			
		||||
        return field.toLowerCase().replace("_","-");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set some field to be accesible
 | 
			
		||||
     * @param field
 | 
			
		||||
     * @throws NoSuchFieldException
 | 
			
		||||
     * @throws IllegalAccessException
 | 
			
		||||
     */
 | 
			
		||||
    private static void setAccessible(Field field) throws NoSuchFieldException, IllegalAccessException {
 | 
			
		||||
        field.setAccessible(true);
 | 
			
		||||
        Field modifiersField = Field.class.getDeclaredField("modifiers");
 | 
			
		||||
        modifiersField.setAccessible(true);
 | 
			
		||||
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,193 +1,316 @@
 | 
			
		||||
package com.intellectualcrafters.plot.config;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.configuration.file.YamlConfiguration;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Updater and DB settings
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
public class Settings {
 | 
			
		||||
    public static boolean USE_SQLUUIDHANDLER = false;
 | 
			
		||||
public class Settings extends Config {
 | 
			
		||||
 | 
			
		||||
    public static boolean AUTO_PURGE = false;
 | 
			
		||||
    public static boolean UPDATE_NOTIFICATIONS = true;
 | 
			
		||||
    /*
 | 
			
		||||
    START OF CONFIGURATION SECTION:
 | 
			
		||||
    NOTE: Fields are saved in declaration order, classes in reverse order
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    public static boolean FAST_CLEAR = false;
 | 
			
		||||
    public static boolean MERGE_REMOVES_ROADS = true;
 | 
			
		||||
    /**`
 | 
			
		||||
     * Default UUID_FECTHING: false
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean PERMISSION_CACHING = true;
 | 
			
		||||
    public static boolean CACHE_RATINGS = true;
 | 
			
		||||
    public static boolean UUID_FROM_DISK = false;
 | 
			
		||||
    @Comment("These first 4 aren't configurable") // This is a comment
 | 
			
		||||
    @Final // Indicates that this value isn't configurable
 | 
			
		||||
    public static final String ISSUES = "https://github.com/IntellectualSites/PlotSquared/issues";
 | 
			
		||||
    @Final
 | 
			
		||||
    public static final String WIKI = "https://github.com/IntellectualSites/PlotSquared/wiki";
 | 
			
		||||
    @Final
 | 
			
		||||
    public static String VERSION = null; // These values are set from PS before loading
 | 
			
		||||
    @Final
 | 
			
		||||
    public static String PLATFORM = null; // These values are set from PS before loading
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Web
 | 
			
		||||
     */
 | 
			
		||||
    public static String WEB_URL = "http://empcraft.com/plots/";
 | 
			
		||||
    public static String WEB_IP = "your.ip.here";
 | 
			
		||||
    public static boolean DOWNLOAD_REQUIRES_DONE = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Ratings
 | 
			
		||||
     */
 | 
			
		||||
    public static List<String> RATING_CATEGORIES = null;
 | 
			
		||||
    public static boolean REQUIRE_DONE = false;
 | 
			
		||||
    public static boolean DONE_COUNTS_TOWARDS_LIMIT = false;
 | 
			
		||||
    public static boolean DONE_RESTRICTS_BUILDING = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * PlotMe settings
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean CONVERT_PLOTME = true;
 | 
			
		||||
    public static boolean CACHE_PLOTME = false;
 | 
			
		||||
    public static boolean USE_PLOTME_ALIAS = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Comment system
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean COMMENT_NOTIFICATIONS = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Chunk processor
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean CHUNK_PROCESSOR = false;
 | 
			
		||||
    public static boolean EXPERIMENTAL_FAST_ASYNC_WORLDEDIT = false;
 | 
			
		||||
    public static boolean CHUNK_PROCESSOR_GC = false;
 | 
			
		||||
    public static int CHUNK_PROCESSOR_MAX_BLOCKSTATES = 4096;
 | 
			
		||||
    public static int CHUNK_PROCESSOR_MAX_ENTITIES = 512;
 | 
			
		||||
    public static boolean CHUNK_PROCESSOR_DISABLE_PHYSICS = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Redstone disabler
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean REDSTONE_DISABLER = false;
 | 
			
		||||
    public static boolean REDSTONE_DISABLER_UNOCCUPIED = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Max auto claiming size
 | 
			
		||||
     */
 | 
			
		||||
    public static int MAX_AUTO_SIZE = 4;
 | 
			
		||||
    /**
 | 
			
		||||
     * Default worldedit-check-selection-in-mask: false
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean WE_ALLOW_HELPER = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Teleport to path on login
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean TELEPORT_ON_LOGIN = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Teleport to path on death
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean TELEPORT_ON_DEATH = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Display titles
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean TITLES = true;
 | 
			
		||||
    /**
 | 
			
		||||
     * Schematic Save Path
 | 
			
		||||
     */
 | 
			
		||||
    public static String SCHEMATIC_SAVE_PATH = "schematics";
 | 
			
		||||
    /**
 | 
			
		||||
     * BO3 Save Path
 | 
			
		||||
     */
 | 
			
		||||
    public static String BO3_SAVE_PATH = "BO3";
 | 
			
		||||
    /**
 | 
			
		||||
     * Max allowed plots
 | 
			
		||||
     */
 | 
			
		||||
    public static int MAX_PLOTS = 127;
 | 
			
		||||
    /**
 | 
			
		||||
     * metrics
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean METRICS = true;
 | 
			
		||||
    /**
 | 
			
		||||
     * Kill road mobs?
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean KILL_ROAD_MOBS = false;
 | 
			
		||||
    public static boolean KILL_ROAD_VEHICLES = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete plots on ban?
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean DELETE_PLOTS_ON_BAN = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Verbose?
 | 
			
		||||
     */
 | 
			
		||||
    @Comment("Show additional information in console")
 | 
			
		||||
    public static boolean DEBUG = true;
 | 
			
		||||
    /**
 | 
			
		||||
     * Have colored console messages?
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean CONSOLE_COLOR = true;
 | 
			
		||||
    /**
 | 
			
		||||
     * Fancy chat e.g. for /plot list
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean FANCY_CHAT = true;
 | 
			
		||||
    /**
 | 
			
		||||
     * The delay (in seconds) before teleportation commences
 | 
			
		||||
     */
 | 
			
		||||
    public static int TELEPORT_DELAY = 0;
 | 
			
		||||
    /**
 | 
			
		||||
     * Auto clear enabled
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean AUTO_CLEAR = false;
 | 
			
		||||
    public static boolean AUTO_CLEAR_CONFIRMATION = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Days until a plot gets cleared
 | 
			
		||||
     */
 | 
			
		||||
    public static int AUTO_CLEAR_DAYS = 360;
 | 
			
		||||
    public static int CLEAR_THRESHOLD = 1;
 | 
			
		||||
    public static int CLEAR_INTERVAL = 120;
 | 
			
		||||
    /**
 | 
			
		||||
     * Use the custom API
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean CUSTOM_API = true;
 | 
			
		||||
    /**
 | 
			
		||||
     * Use offline mode storage
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean TWIN_MODE_UUID = false;
 | 
			
		||||
    public static boolean OFFLINE_MODE = false;
 | 
			
		||||
    public static boolean UUID_LOWERCASE = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Use global plot limit?
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean GLOBAL_LIMIT = false;
 | 
			
		||||
    @Comment({"The big annoying text that appears when you enter a plot", "For a single plot: `/plot flag set titles false`", "For just you: `/plot toggle titles`"})
 | 
			
		||||
    public static boolean TITLES = true;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Database settings
 | 
			
		||||
    @Create // This value will be generated automatically
 | 
			
		||||
    public static final ConfigBlock<AUTO_CLEAR> AUTO_CLEAR = null; // A ConfigBlock is a section that can have multiple instances e.g. multiple expiry tasks
 | 
			
		||||
 | 
			
		||||
    @Comment("This is an auto clearing task called `task1`")
 | 
			
		||||
    @BlockName("task1") // The name for the default block
 | 
			
		||||
    public static final class AUTO_CLEAR extends ConfigBlock {
 | 
			
		||||
        @Create // This value has to be generated since an instance isn't static
 | 
			
		||||
        public CALIBRATION CALIBRATION = null;
 | 
			
		||||
 | 
			
		||||
        @Comment("See: https://github.com/IntellectualSites/PlotSquared/wiki/Plot-analysis")
 | 
			
		||||
        public static final class CALIBRATION {
 | 
			
		||||
            public int VARIETY = 0;
 | 
			
		||||
            public int VARIETY_SD = 0;
 | 
			
		||||
            public int CHANGES = 0;
 | 
			
		||||
            public int CHANGES_SD = 1;
 | 
			
		||||
            public int FACES = 0;
 | 
			
		||||
            public int FACES_SD = 0;
 | 
			
		||||
            public int DATA_SD = 0;
 | 
			
		||||
            public int AIR = 0;
 | 
			
		||||
            public int AIR_SD = 0;
 | 
			
		||||
            public int DATA = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int THRESHOLD = 1;
 | 
			
		||||
        public boolean CONFIRMATION = true;
 | 
			
		||||
        public int DAYS = 7;
 | 
			
		||||
        public List<String> WORLDS = new ArrayList<>(Arrays.asList("*"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class CHUNK_PROCESSOR {
 | 
			
		||||
        @Comment("Auto trim will not save chunks which aren't claimed")
 | 
			
		||||
        public static boolean AUTO_TRIM = false;
 | 
			
		||||
        @Comment("Max tile entities per chunk")
 | 
			
		||||
        public static int MAX_TILES = 4096;
 | 
			
		||||
        @Comment("Max entities per chunk")
 | 
			
		||||
        public static int MAX_ENTITIES = 512;
 | 
			
		||||
        @Comment("Disable block physics")
 | 
			
		||||
        public static boolean DISABLE_PHYSICS = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class UUID {
 | 
			
		||||
        @Comment("Force PlotSquared to use offline UUIDs (it usually detects the right mode)")
 | 
			
		||||
        public static boolean OFFLINE = false;
 | 
			
		||||
        @Comment("Force PlotSquared to use lowercase UUIDs")
 | 
			
		||||
        public static boolean FORCE_LOWERCASE = false;
 | 
			
		||||
        @Comment("Use a database to store UUID/name info")
 | 
			
		||||
        public static boolean USE_SQLUUIDHANDLER = false;
 | 
			
		||||
        @Ignore
 | 
			
		||||
        public static boolean NATIVE_UUID_PROVIDER = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Comment("Configure the paths PlotSquared will use")
 | 
			
		||||
    public static final class PATHS {
 | 
			
		||||
        public static String SCHEMATICS = "schematics";
 | 
			
		||||
        public static String BO3 = "bo3";
 | 
			
		||||
        public static String SCRIPTS = "scripts";
 | 
			
		||||
        public static String TEMPLATES = "templates";
 | 
			
		||||
        public static String TRANSLATIONS = "translations";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class WEB {
 | 
			
		||||
        @Comment("We are already hosting a web interface for you:")
 | 
			
		||||
        public static String URL = "http://empcraft.com/plots/";
 | 
			
		||||
        @Comment("The ip that will show up in the interface")
 | 
			
		||||
        public static String SERVER_IP = "your.ip.here";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class DONE {
 | 
			
		||||
        @Comment("Require a done plot to download")
 | 
			
		||||
        public static boolean REQUIRED_FOR_DOWNLOAD = false;
 | 
			
		||||
        @Comment("Only done plots can be rated")
 | 
			
		||||
        public static boolean REQUIRED_FOR_RATINGS = false;
 | 
			
		||||
        @Comment("Restrict building when a plot is done")
 | 
			
		||||
        public static boolean RESTRICT_BUILDING = false;
 | 
			
		||||
        @Comment("The limit being how many plots a player can claim")
 | 
			
		||||
        public static boolean COUNTS_TOWARDS_LIMIT = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class CHAT {
 | 
			
		||||
        @Comment("Sometimes console color doesn't work, you can disable it here")
 | 
			
		||||
        public static boolean CONSOLE_COLOR = true;
 | 
			
		||||
        @Comment("Should chat be interactive")
 | 
			
		||||
        public static boolean INTERACTIVE = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Comment("Relating to how many plots someone can claim  ")
 | 
			
		||||
    public static final class LIMIT {
 | 
			
		||||
        @Comment("Should the limit be global (over multiple worlds)")
 | 
			
		||||
        public static boolean GLOBAL = false;
 | 
			
		||||
        @Comment("The range of permissions to check e.g. plots.plot.127")
 | 
			
		||||
        public static int MAX_PLOTS = 127;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Comment("Switching from PlotMe?")
 | 
			
		||||
    public static final class PLOTME {
 | 
			
		||||
        @Comment("Cache the uuids from the PlotMe database")
 | 
			
		||||
        public static boolean CACHE_UUDS = false;
 | 
			
		||||
        @Comment("Have `/plotme` as a command alias")
 | 
			
		||||
        public static boolean ALIAS = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class TELEPORT {
 | 
			
		||||
        @Comment("Teleport to your plot on death")
 | 
			
		||||
        public static boolean ON_DEATH = false;
 | 
			
		||||
        @Comment("Teleport to your plot on login")
 | 
			
		||||
        public static boolean ON_LOGIN = false;
 | 
			
		||||
        @Comment("Add a teleportation delay to all commands")
 | 
			
		||||
        public static int DELAY = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class REDSTONE {
 | 
			
		||||
        @Comment("Disable redstone in unoccupied plots")
 | 
			
		||||
        public static boolean DISABLE_UNOCCUPIED = false;
 | 
			
		||||
        @Comment("Disable redstone when all owners/trusted/members are offline")
 | 
			
		||||
        public static boolean DISABLE_OFFLINE = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class CLAIM {
 | 
			
		||||
        @Comment("The max plots claimed in a single `/plot auto <size>` command")
 | 
			
		||||
        public static int MAX_AUTO_AREA = 4;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class RATINGS {
 | 
			
		||||
        public static List<String> CATEGORIES = new ArrayList<>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Comment({"Enable or disable part of the plugin","Note: A cache will use some memory if enabled"})
 | 
			
		||||
    public static final class ENABLED_COMPONENTS { // Group the following values into a new config section
 | 
			
		||||
        @Comment("The database stores all the plots")
 | 
			
		||||
        public static boolean DATABASE = true;
 | 
			
		||||
        @Comment("Events are needed to track a lot of things")
 | 
			
		||||
        public static boolean EVENTS = true;
 | 
			
		||||
        @Comment("Commands are used to interact with the plugin")
 | 
			
		||||
        public static boolean COMMANDS = true;
 | 
			
		||||
        @Comment("The UUID cacher is used to resolve player names")
 | 
			
		||||
        public static boolean UUID_CACHE = true;
 | 
			
		||||
        @Comment("Notify players of updates")
 | 
			
		||||
        public static boolean UPDATER = true;
 | 
			
		||||
        @Comment("Optimizes permission checks")
 | 
			
		||||
        public static boolean PERMISSION_CACHE = true;
 | 
			
		||||
        @Comment("Optimizes block changing code")
 | 
			
		||||
        public static boolean BLOCK_CACHE = true;
 | 
			
		||||
        @Comment("Getting a rating won't need the database")
 | 
			
		||||
        public static boolean RATING_CACHE = true;
 | 
			
		||||
        @Comment("The converter will attempt to convert the PlotMe database")
 | 
			
		||||
        public static boolean PLOTME_CONVERTER = true;
 | 
			
		||||
        @Comment("Allow WorldEdit to be restricted to plots")
 | 
			
		||||
        public static boolean WORLDEDIT_RESTRICTIONS = true;
 | 
			
		||||
        @Comment("Allow economy to be used")
 | 
			
		||||
        public static boolean ECONOMY = true;
 | 
			
		||||
        @Comment("Send anonymous usage statistics")
 | 
			
		||||
        public static boolean METRICS = true;
 | 
			
		||||
        @Comment("Expiry will clear old or simplistic plots")
 | 
			
		||||
        public static boolean PLOT_EXPIRY = false;
 | 
			
		||||
        @Comment("Processes chunks (trimming, or entity/tile limits) ")
 | 
			
		||||
        public static boolean CHUNK_PROCESSOR = false;
 | 
			
		||||
        @Comment("Kill mobs or vehicles on roads")
 | 
			
		||||
        public static boolean KILL_ROAD_MOBS = false;
 | 
			
		||||
        public static boolean KILL_ROAD_VEHICLES = false;
 | 
			
		||||
        @Comment("Notify a player of any missed comments upon plot entry")
 | 
			
		||||
        public static boolean COMMENT_NOTIFIER = false;
 | 
			
		||||
        @Comment("Actively purge invalid database entries")
 | 
			
		||||
        public static boolean DATABASE_PURGER = false;
 | 
			
		||||
        @Comment("Delete plots when a player is banned")
 | 
			
		||||
        public static boolean BAN_DELETER = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    END OF CONFIGURATION SECTION:
 | 
			
		||||
     */
 | 
			
		||||
    public static class DB {
 | 
			
		||||
        /**
 | 
			
		||||
         * MongoDB enabled?
 | 
			
		||||
         */
 | 
			
		||||
        public static boolean USE_MONGO = false;
 | 
			
		||||
        /**
 | 
			
		||||
         * SQLite enabled?
 | 
			
		||||
         */
 | 
			
		||||
        public static boolean USE_SQLITE = true;
 | 
			
		||||
        /**
 | 
			
		||||
         * MySQL Enabled?
 | 
			
		||||
         */
 | 
			
		||||
        public static boolean USE_MYSQL = false; /* NOTE: Fixed connector */
 | 
			
		||||
        /**
 | 
			
		||||
         * SQLite Database name
 | 
			
		||||
         */
 | 
			
		||||
        public static String SQLITE_DB = "storage";
 | 
			
		||||
        /**
 | 
			
		||||
         * MySQL Host name
 | 
			
		||||
         */
 | 
			
		||||
        public static String HOST_NAME = "localhost";
 | 
			
		||||
        /**
 | 
			
		||||
         * MySQL Port
 | 
			
		||||
         */
 | 
			
		||||
        public static String PORT = "3306";
 | 
			
		||||
        /**
 | 
			
		||||
         * MySQL DB
 | 
			
		||||
         */
 | 
			
		||||
        public static String DATABASE = "plot_db";
 | 
			
		||||
        /**
 | 
			
		||||
         * MySQL User
 | 
			
		||||
         */
 | 
			
		||||
        public static String USER = "root";
 | 
			
		||||
        /**
 | 
			
		||||
         * MySQL Password
 | 
			
		||||
         */
 | 
			
		||||
        public static String PASSWORD = "password";
 | 
			
		||||
        /**
 | 
			
		||||
         * MySQL Prefix
 | 
			
		||||
         */
 | 
			
		||||
        public static String PREFIX = "";
 | 
			
		||||
 | 
			
		||||
    public static void save(File file) {
 | 
			
		||||
        save(file, Settings.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void load(File file) {
 | 
			
		||||
        load(file, Settings.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean convertLegacy(File file) {
 | 
			
		||||
        if (!file.exists()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
 | 
			
		||||
 | 
			
		||||
        // Protection
 | 
			
		||||
        REDSTONE.DISABLE_OFFLINE = config.getBoolean("protection.redstone.disable-offline");
 | 
			
		||||
        REDSTONE.DISABLE_UNOCCUPIED = config.getBoolean("protection.redstone.disable-unoccupied", REDSTONE.DISABLE_UNOCCUPIED);
 | 
			
		||||
 | 
			
		||||
        // PlotMe
 | 
			
		||||
        PLOTME.ALIAS = config.getBoolean("plotme-alias", PLOTME.ALIAS);
 | 
			
		||||
        ENABLED_COMPONENTS.PLOTME_CONVERTER = config.getBoolean("plotme-convert.enabled", ENABLED_COMPONENTS.PLOTME_CONVERTER);
 | 
			
		||||
        PLOTME.CACHE_UUDS = config.getBoolean("plotme-convert.cache-uuids", PLOTME.CACHE_UUDS);
 | 
			
		||||
 | 
			
		||||
        // UUID
 | 
			
		||||
        UUID.USE_SQLUUIDHANDLER = config.getBoolean("uuid.use_sqluuidhandler", UUID.USE_SQLUUIDHANDLER);
 | 
			
		||||
        UUID.OFFLINE = config.getBoolean("UUID.offline", UUID.OFFLINE);
 | 
			
		||||
        UUID.FORCE_LOWERCASE = config.getBoolean("UUID.force-lowercase", UUID.FORCE_LOWERCASE);
 | 
			
		||||
 | 
			
		||||
        // Mob stuff
 | 
			
		||||
        ENABLED_COMPONENTS.KILL_ROAD_MOBS = config.getBoolean("kill_road_mobs", ENABLED_COMPONENTS.KILL_ROAD_MOBS);
 | 
			
		||||
        ENABLED_COMPONENTS.KILL_ROAD_VEHICLES = config.getBoolean("kill_road_vehicles", ENABLED_COMPONENTS.KILL_ROAD_VEHICLES);
 | 
			
		||||
 | 
			
		||||
        // Clearing + Expiry
 | 
			
		||||
//        FAST_CLEAR = config.getBoolean("clear.fastmode");
 | 
			
		||||
        ENABLED_COMPONENTS.PLOT_EXPIRY = config.getBoolean("clear.auto.enabled", ENABLED_COMPONENTS.PLOT_EXPIRY);
 | 
			
		||||
        if (ENABLED_COMPONENTS.PLOT_EXPIRY) {
 | 
			
		||||
            ENABLED_COMPONENTS.BAN_DELETER = config.getBoolean("clear.on.ban");
 | 
			
		||||
 | 
			
		||||
            AUTO_CLEAR.put("task1", new AUTO_CLEAR());
 | 
			
		||||
            AUTO_CLEAR task = AUTO_CLEAR.get("task1");
 | 
			
		||||
            task.CALIBRATION = new AUTO_CLEAR.CALIBRATION();
 | 
			
		||||
 | 
			
		||||
            task.DAYS = config.getInt("clear.auto.days", task.DAYS);
 | 
			
		||||
            task.THRESHOLD = config.getInt("clear.auto.threshold", task.THRESHOLD);
 | 
			
		||||
            task.CONFIRMATION = config.getBoolean("clear.auto.confirmation", task.CONFIRMATION);
 | 
			
		||||
            task.CALIBRATION.CHANGES = config.getInt("clear.auto.calibration.changes", task.CALIBRATION.CHANGES);
 | 
			
		||||
            task.CALIBRATION.FACES = config.getInt("clear.auto.calibration.faces", task.CALIBRATION.FACES);
 | 
			
		||||
            task.CALIBRATION.DATA = config.getInt("clear.auto.calibration.data", task.CALIBRATION.DATA);
 | 
			
		||||
            task.CALIBRATION.AIR = config.getInt("clear.auto.calibration.air", task.CALIBRATION.AIR);
 | 
			
		||||
            task.CALIBRATION.VARIETY = config.getInt("clear.auto.calibration.variety", task.CALIBRATION.VARIETY);
 | 
			
		||||
            task.CALIBRATION.CHANGES_SD = config.getInt("clear.auto.calibration.changes_sd", task.CALIBRATION.CHANGES_SD);
 | 
			
		||||
            task.CALIBRATION.FACES_SD = config.getInt("clear.auto.calibration.faces_sd", task.CALIBRATION.FACES_SD);
 | 
			
		||||
            task.CALIBRATION.DATA_SD = config.getInt("clear.auto.calibration.data_sd", task.CALIBRATION.DATA_SD);
 | 
			
		||||
            task.CALIBRATION.AIR_SD = config.getInt("clear.auto.calibration.air_sd", task.CALIBRATION.AIR_SD);
 | 
			
		||||
            task.CALIBRATION.VARIETY_SD = config.getInt("clear.auto.calibration.variety_sd", task.CALIBRATION.VARIETY_SD);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Done
 | 
			
		||||
        DONE.REQUIRED_FOR_RATINGS = config.getBoolean("approval.ratings.check-done", DONE.REQUIRED_FOR_RATINGS);
 | 
			
		||||
        DONE.COUNTS_TOWARDS_LIMIT = config.getBoolean("approval.done.counts-towards-limit", DONE.COUNTS_TOWARDS_LIMIT);
 | 
			
		||||
        DONE.RESTRICT_BUILDING = config.getBoolean("approval.done.restrict-building", DONE.RESTRICT_BUILDING);
 | 
			
		||||
        DONE.REQUIRED_FOR_DOWNLOAD = config.getBoolean("approval.done.required-for-download", DONE.REQUIRED_FOR_DOWNLOAD);
 | 
			
		||||
 | 
			
		||||
        // Schematics
 | 
			
		||||
        PATHS.SCHEMATICS = config.getString("schematics.save_path", PATHS.SCHEMATICS);
 | 
			
		||||
        PATHS.BO3 = config.getString("bo3.save_path", PATHS.BO3);
 | 
			
		||||
 | 
			
		||||
        // Web
 | 
			
		||||
        WEB.URL = config.getString("web.url", WEB.URL);
 | 
			
		||||
        WEB.SERVER_IP = config.getString("web.server-ip", WEB.SERVER_IP);
 | 
			
		||||
 | 
			
		||||
        // Caching
 | 
			
		||||
        ENABLED_COMPONENTS.PERMISSION_CACHE = config.getBoolean("cache.permissions", ENABLED_COMPONENTS.PERMISSION_CACHE);
 | 
			
		||||
        ENABLED_COMPONENTS.RATING_CACHE = config.getBoolean("cache.ratings", ENABLED_COMPONENTS.RATING_CACHE);
 | 
			
		||||
 | 
			
		||||
        // Rating system
 | 
			
		||||
        RATINGS.CATEGORIES = config.contains("ratings.categories") ? config.getStringList("ratings.categories") : RATINGS.CATEGORIES;
 | 
			
		||||
 | 
			
		||||
        // Titles
 | 
			
		||||
        TITLES = config.getBoolean("titles", TITLES);
 | 
			
		||||
 | 
			
		||||
        // Teleportation
 | 
			
		||||
        TELEPORT.DELAY = config.getInt("teleport.delay", TELEPORT.DELAY);
 | 
			
		||||
        TELEPORT.ON_LOGIN = config.getBoolean("teleport.on_login", TELEPORT.ON_LOGIN);
 | 
			
		||||
        TELEPORT.ON_DEATH = config.getBoolean("teleport.on_death", TELEPORT.ON_DEATH);
 | 
			
		||||
 | 
			
		||||
        // WorldEdit
 | 
			
		||||
//        WE_ALLOW_HELPER = config.getBoolean("worldedit.enable-for-helpers");
 | 
			
		||||
 | 
			
		||||
        // Chunk processor
 | 
			
		||||
        ENABLED_COMPONENTS.CHUNK_PROCESSOR = config.getBoolean("chunk-processor.enabled", ENABLED_COMPONENTS.CHUNK_PROCESSOR);
 | 
			
		||||
        CHUNK_PROCESSOR.AUTO_TRIM = config.getBoolean("chunk-processor.auto-unload", CHUNK_PROCESSOR.AUTO_TRIM);
 | 
			
		||||
        CHUNK_PROCESSOR.MAX_TILES = config.getInt("chunk-processor.max-blockstates", CHUNK_PROCESSOR.MAX_TILES);
 | 
			
		||||
        CHUNK_PROCESSOR.MAX_ENTITIES = config.getInt("chunk-processor.max-entities", CHUNK_PROCESSOR.MAX_ENTITIES);
 | 
			
		||||
        CHUNK_PROCESSOR.DISABLE_PHYSICS = config.getBoolean("chunk-processor.disable-physics", CHUNK_PROCESSOR.DISABLE_PHYSICS);
 | 
			
		||||
 | 
			
		||||
        // Comments
 | 
			
		||||
        ENABLED_COMPONENTS.COMMENT_NOTIFIER = config.getBoolean("comments.notifications.enabled", ENABLED_COMPONENTS.COMMENT_NOTIFIER);
 | 
			
		||||
 | 
			
		||||
        // Plot limits
 | 
			
		||||
        CLAIM.MAX_AUTO_AREA = config.getInt("claim.max-auto-area", CLAIM.MAX_AUTO_AREA);
 | 
			
		||||
        LIMIT.MAX_PLOTS = config.getInt("max_plots", LIMIT.MAX_PLOTS);
 | 
			
		||||
        LIMIT.GLOBAL = config.getBoolean("global_limit", LIMIT.GLOBAL);
 | 
			
		||||
 | 
			
		||||
        // Misc
 | 
			
		||||
        DEBUG = config.getBoolean("debug", DEBUG);
 | 
			
		||||
        CHAT.CONSOLE_COLOR = config.getBoolean("console.color", CHAT.CONSOLE_COLOR);
 | 
			
		||||
        CHAT.INTERACTIVE = config.getBoolean("chat.fancy", CHAT.INTERACTIVE);
 | 
			
		||||
 | 
			
		||||
        ENABLED_COMPONENTS.METRICS = config.getBoolean("metrics", ENABLED_COMPONENTS.METRICS);
 | 
			
		||||
        ENABLED_COMPONENTS.UPDATER = config.getBoolean("update-notifications", ENABLED_COMPONENTS.UPDATER);
 | 
			
		||||
        ENABLED_COMPONENTS.DATABASE_PURGER = config.getBoolean("auto-purge", ENABLED_COMPONENTS.DATABASE_PURGER);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
package com.intellectualcrafters.plot.config;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
 | 
			
		||||
public class Storage extends Config {
 | 
			
		||||
 | 
			
		||||
    @Final
 | 
			
		||||
    public static final String VERSION = null; // This value is set from PS before loading
 | 
			
		||||
 | 
			
		||||
    @Comment("MySQL section")
 | 
			
		||||
    public static final class MYSQL {
 | 
			
		||||
        @Comment("Should MySQL be used?")
 | 
			
		||||
        public static final boolean USE = false;
 | 
			
		||||
        public static final String HOST = "localhost";
 | 
			
		||||
        public static final String PORT = "3306";
 | 
			
		||||
        public static final String USER = "root";
 | 
			
		||||
        public static final String PASSWORD = "password";
 | 
			
		||||
        public static final String DATABASE = "plot_db";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Comment("SQLite section")
 | 
			
		||||
    public static final class SQLITE {
 | 
			
		||||
        @Comment("Should SQLite be used?")
 | 
			
		||||
        public static boolean USE = true;
 | 
			
		||||
        @Comment("The file to use")
 | 
			
		||||
        public static String DB = "storage";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final String PREFIX = "";
 | 
			
		||||
 | 
			
		||||
    public static void save(File file) {
 | 
			
		||||
        save(file, Storage.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void load(File file) {
 | 
			
		||||
        load(file, Storage.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -3,6 +3,7 @@ package com.intellectualcrafters.plot.database;
 | 
			
		||||
import com.intellectualcrafters.configuration.ConfigurationSection;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Storage;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.Flag;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.FlagManager;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.StringFlag;
 | 
			
		||||
@@ -17,7 +18,6 @@ import com.intellectualcrafters.plot.object.comment.PlotComment;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.StringMan;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.DatabaseMetaData;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
@@ -1321,7 +1321,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void deleteRatings(final Plot plot) {
 | 
			
		||||
        if (Settings.CACHE_RATINGS && plot.getSettings().getRatings().isEmpty()) {
 | 
			
		||||
        if (Settings.ENABLED_COMPONENTS.RATING_CACHE && plot.getSettings().getRatings().isEmpty()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        addPlotTask(plot, new UniqueStatement("delete_plot_ratings") {
 | 
			
		||||
@@ -1479,7 +1479,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
                    rs.close();
 | 
			
		||||
                    try (Statement statement = this.connection.createStatement()) {
 | 
			
		||||
                        statement.addBatch("DROP TABLE `" + this.prefix + "plot_comments`");
 | 
			
		||||
                        if (Settings.DB.USE_MYSQL) {
 | 
			
		||||
                        if (Storage.MYSQL.USE) {
 | 
			
		||||
                            statement.addBatch("CREATE TABLE IF NOT EXISTS `"
 | 
			
		||||
                                    + this.prefix
 | 
			
		||||
                                    + "plot_comments` ("
 | 
			
		||||
@@ -1590,8 +1590,8 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
        HashMap<Integer, Plot> plots = new HashMap<>();
 | 
			
		||||
        try {
 | 
			
		||||
            HashSet<String> areas = new HashSet<>();
 | 
			
		||||
            if (PS.get().config.contains("worlds")) {
 | 
			
		||||
                ConfigurationSection worldSection = PS.get().config.getConfigurationSection("worlds");
 | 
			
		||||
            if (PS.get().worlds.contains("worlds")) {
 | 
			
		||||
                ConfigurationSection worldSection = PS.get().worlds.getConfigurationSection("worlds");
 | 
			
		||||
                if (worldSection != null) {
 | 
			
		||||
                    for (String worldKey : worldSection.getKeys(false)) {
 | 
			
		||||
                        areas.add(worldKey);
 | 
			
		||||
@@ -1625,7 +1625,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
                        id = resultSet.getInt("id");
 | 
			
		||||
                        String areaid = resultSet.getString("world");
 | 
			
		||||
                        if (!areas.contains(areaid)) {
 | 
			
		||||
                            if (Settings.AUTO_PURGE) {
 | 
			
		||||
                            if (Settings.ENABLED_COMPONENTS.DATABASE_PURGER) {
 | 
			
		||||
                                toDelete.add(id);
 | 
			
		||||
                                continue;
 | 
			
		||||
                            } else {
 | 
			
		||||
@@ -1652,7 +1652,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
                            Plot last = map.put(p.getId(), p);
 | 
			
		||||
                            if (last != null) {
 | 
			
		||||
                                map.put(last.getId(), last);
 | 
			
		||||
                                if (Settings.AUTO_PURGE) {
 | 
			
		||||
                                if (Settings.ENABLED_COMPONENTS.DATABASE_PURGER) {
 | 
			
		||||
                                    toDelete.add(id);
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    PS.debug("&cPLOT " + id + " in `" + this.prefix
 | 
			
		||||
@@ -1669,7 +1669,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
                    }
 | 
			
		||||
                    deleteRows(toDelete, this.prefix + "plot", "id");
 | 
			
		||||
                }
 | 
			
		||||
                if (Settings.CACHE_RATINGS) {
 | 
			
		||||
                if (Settings.ENABLED_COMPONENTS.RATING_CACHE) {
 | 
			
		||||
                    try (ResultSet r = statement.executeQuery("SELECT `plot_plot_id`, `player`, `rating` FROM `" + this.prefix + "plot_rating`")) {
 | 
			
		||||
                        ArrayList<Integer> toDelete = new ArrayList<>();
 | 
			
		||||
                        while (r.next()) {
 | 
			
		||||
@@ -1683,7 +1683,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
                            Plot plot = plots.get(id);
 | 
			
		||||
                            if (plot != null) {
 | 
			
		||||
                                plot.getSettings().getRatings().put(user, r.getInt("rating"));
 | 
			
		||||
                            } else if (Settings.AUTO_PURGE) {
 | 
			
		||||
                            } else if (Settings.ENABLED_COMPONENTS.DATABASE_PURGER) {
 | 
			
		||||
                                toDelete.add(id);
 | 
			
		||||
                            } else {
 | 
			
		||||
                                PS.debug("&cENTRY " + id + " in `plot_rating` does not exist. Create this plot or set `auto-purge: true` in the "
 | 
			
		||||
@@ -1710,7 +1710,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
                        Plot plot = plots.get(id);
 | 
			
		||||
                        if (plot != null) {
 | 
			
		||||
                            plot.getTrusted().add(user);
 | 
			
		||||
                        } else if (Settings.AUTO_PURGE) {
 | 
			
		||||
                        } else if (Settings.ENABLED_COMPONENTS.DATABASE_PURGER) {
 | 
			
		||||
                            toDelete.add(id);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            PS.debug("&cENTRY " + id + " in `plot_helpers` does not exist. Create this plot or set `auto-purge: true` in the settings"
 | 
			
		||||
@@ -1736,7 +1736,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
                        Plot plot = plots.get(id);
 | 
			
		||||
                        if (plot != null) {
 | 
			
		||||
                            plot.getMembers().add(user);
 | 
			
		||||
                        } else if (Settings.AUTO_PURGE) {
 | 
			
		||||
                        } else if (Settings.ENABLED_COMPONENTS.DATABASE_PURGER) {
 | 
			
		||||
                            toDelete.add(id);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            PS.debug("&cENTRY " + id + " in `plot_trusted` does not exist. Create this plot or set `auto-purge: true` in the settings"
 | 
			
		||||
@@ -1762,7 +1762,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
                        Plot plot = plots.get(id);
 | 
			
		||||
                        if (plot != null) {
 | 
			
		||||
                            plot.getDenied().add(user);
 | 
			
		||||
                        } else if (Settings.AUTO_PURGE) {
 | 
			
		||||
                        } else if (Settings.ENABLED_COMPONENTS.DATABASE_PURGER) {
 | 
			
		||||
                            toDelete.add(id);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            PS.debug("&cENTRY " + id
 | 
			
		||||
@@ -1851,7 +1851,7 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
                                this.setFlags(plot, flags);
 | 
			
		||||
                            }
 | 
			
		||||
                            plot.getSettings().flags = flags;
 | 
			
		||||
                        } else if (Settings.AUTO_PURGE) {
 | 
			
		||||
                        } else if (Settings.ENABLED_COMPONENTS.DATABASE_PURGER) {
 | 
			
		||||
                            toDelete.add(id);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            PS.debug(
 | 
			
		||||
@@ -2504,8 +2504,8 @@ public class SQLManager implements AbstractDB {
 | 
			
		||||
        HashMap<Integer, PlotCluster> clusters = new HashMap<>();
 | 
			
		||||
        try {
 | 
			
		||||
            HashSet<String> areas = new HashSet<>();
 | 
			
		||||
            if (PS.get().config.contains("worlds")) {
 | 
			
		||||
                ConfigurationSection worldSection = PS.get().config.getConfigurationSection("worlds");
 | 
			
		||||
            if (PS.get().worlds.contains("worlds")) {
 | 
			
		||||
                ConfigurationSection worldSection = PS.get().worlds.getConfigurationSection("worlds");
 | 
			
		||||
                if (worldSection != null) {
 | 
			
		||||
                    for (String worldKey : worldSection.getKeys(false)) {
 | 
			
		||||
                        areas.add(worldKey);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,8 @@ public class SQLite extends Database {
 | 
			
		||||
     *
 | 
			
		||||
     * @param dbLocation Location of the Database (Must end in .db)
 | 
			
		||||
     */
 | 
			
		||||
    public SQLite(String dbLocation) {
 | 
			
		||||
        this.dbLocation = dbLocation;
 | 
			
		||||
    public SQLite(File dbLocation) {
 | 
			
		||||
        this.dbLocation = dbLocation.getAbsolutePath();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,10 @@ public abstract class Flag<V> {
 | 
			
		||||
        this.reserved = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void register() {
 | 
			
		||||
        Flags.registerFlag(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public abstract String valueToString(Object value);
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -16,13 +16,13 @@ public final class Flags {
 | 
			
		||||
 | 
			
		||||
    public static final IntegerFlag MUSIC = new IntegerFlag("music");
 | 
			
		||||
    public static final StringFlag DESCRIPTION = new StringFlag("description");
 | 
			
		||||
    public static final IntegerListFlag ANALYSIS = new IntegerListFlag("analysis");
 | 
			
		||||
    public static final IntegerListFlag ANALYSIS = (IntegerListFlag) new IntegerListFlag("analysis").reserve();
 | 
			
		||||
    public static final StringFlag GREETING = new StringFlag("greeting");
 | 
			
		||||
    public static final StringFlag FAREWELL = new StringFlag("farewell");
 | 
			
		||||
    public static final IntervalFlag FEED = new IntervalFlag("feed");
 | 
			
		||||
    public static final IntervalFlag HEAL = new IntervalFlag("heal");
 | 
			
		||||
    public static final GameModeFlag GAMEMODE = new GameModeFlag("gamemode");
 | 
			
		||||
    public static final StringFlag DONE = new StringFlag("done");
 | 
			
		||||
    public static final StringFlag DONE = (StringFlag) new StringFlag("done").reserve();
 | 
			
		||||
    public static final BooleanFlag REDSTONE = new BooleanFlag("redstone");
 | 
			
		||||
    public static final BooleanFlag FLY = new BooleanFlag("fly");
 | 
			
		||||
    public static final BooleanFlag NOTIFY_LEAVE = new BooleanFlag("notify-leave");
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package com.intellectualcrafters.plot.generator;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.commands.Template;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.object.ChunkLoc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.FileBytes;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
@@ -29,7 +30,7 @@ public class HybridPlotManager extends ClassicPlotManager {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void exportTemplate(PlotArea plotArea) throws IOException {
 | 
			
		||||
        HashSet<FileBytes> files = new HashSet<>(
 | 
			
		||||
                Collections.singletonList(new FileBytes("templates/tmp-data.yml", Template.getBytes(plotArea))));
 | 
			
		||||
                Collections.singletonList(new FileBytes(Settings.PATHS.TEMPLATES + "/tmp-data.yml", Template.getBytes(plotArea))));
 | 
			
		||||
        String dir = "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + plotArea.worldname + File.separator;
 | 
			
		||||
        String newDir = "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + "__TEMP_DIR__" + File.separator;
 | 
			
		||||
        try {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ import com.intellectualcrafters.plot.flag.Flags;
 | 
			
		||||
import com.intellectualcrafters.plot.object.ChunkLoc;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Location;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotArea;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotBlock;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ public class BO3 {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public File getFile() {
 | 
			
		||||
        return MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.BO3_SAVE_PATH + File.separator + getWorld() + File.separator + getFilename());
 | 
			
		||||
        return MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.PATHS.BO3 + File.separator + getWorld() + File.separator + getFilename());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getFilename() {
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ import com.intellectualcrafters.plot.util.StringMan;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.UUIDHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.WorldUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
 | 
			
		||||
import com.plotsquared.listener.PlotListener;
 | 
			
		||||
 | 
			
		||||
import java.awt.Rectangle;
 | 
			
		||||
@@ -785,7 +786,7 @@ public class Plot {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                Plot current = queue.poll();
 | 
			
		||||
                if (Plot.this.area.TERRAIN != 0 || Settings.FAST_CLEAR) {
 | 
			
		||||
                if (Plot.this.area.TERRAIN != 0) {
 | 
			
		||||
                    ChunkManager.manager.regenerateRegion(current.getBottomAbs(), current.getTopAbs(), false, this);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
@@ -925,8 +926,8 @@ public class Plot {
 | 
			
		||||
     * This will return null if the plot hasn't been analyzed
 | 
			
		||||
     * @return analysis of plot
 | 
			
		||||
     */
 | 
			
		||||
    public PlotAnalysis getComplexity() {
 | 
			
		||||
        return PlotAnalysis.getAnalysis(this);
 | 
			
		||||
    public PlotAnalysis getComplexity(Settings.AUTO_CLEAR settings) {
 | 
			
		||||
        return PlotAnalysis.getAnalysis(this, settings);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void analyze(RunnableVal<PlotAnalysis> whenDone) {
 | 
			
		||||
@@ -1736,7 +1737,7 @@ public class Plot {
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            String name = Plot.this.id + "," + Plot.this.area + ',' + MainUtil.getName(Plot.this.owner);
 | 
			
		||||
                            boolean result =
 | 
			
		||||
                                    SchematicHandler.manager.save(value, Settings.SCHEMATIC_SAVE_PATH + File.separator + name + ".schematic");
 | 
			
		||||
                                    SchematicHandler.manager.save(value, Settings.PATHS.SCHEMATICS + File.separator + name + ".schematic");
 | 
			
		||||
                            if (whenDone != null) {
 | 
			
		||||
                                whenDone.value = result;
 | 
			
		||||
                                TaskManager.runTask(whenDone);
 | 
			
		||||
@@ -2548,12 +2549,12 @@ public class Plot {
 | 
			
		||||
            } else {
 | 
			
		||||
                location = this.getDefaultHome();
 | 
			
		||||
            }
 | 
			
		||||
            if (Settings.TELEPORT_DELAY == 0 || Permissions.hasPermission(player, "plots.teleport.delay.bypass")) {
 | 
			
		||||
            if (Settings.TELEPORT.DELAY == 0 || Permissions.hasPermission(player, "plots.teleport.delay.bypass")) {
 | 
			
		||||
                MainUtil.sendMessage(player, C.TELEPORTED_TO_PLOT);
 | 
			
		||||
                player.teleport(location);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            MainUtil.sendMessage(player, C.TELEPORT_IN_SECONDS, Settings.TELEPORT_DELAY + "");
 | 
			
		||||
            MainUtil.sendMessage(player, C.TELEPORT_IN_SECONDS, Settings.TELEPORT.DELAY + "");
 | 
			
		||||
            final String name = player.getName();
 | 
			
		||||
            TaskManager.TELEPORT_QUEUE.add(name);
 | 
			
		||||
            TaskManager.runTaskLater(new Runnable() {
 | 
			
		||||
@@ -2569,7 +2570,7 @@ public class Plot {
 | 
			
		||||
                        player.teleport(location);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }, Settings.TELEPORT_DELAY * 20);
 | 
			
		||||
            }, Settings.TELEPORT.DELAY * 20);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -183,7 +183,7 @@ public abstract class PlotArea {
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isCompatible(PlotArea plotArea) {
 | 
			
		||||
        ConfigurationSection section = PS.get().config.getConfigurationSection("worlds");
 | 
			
		||||
        ConfigurationSection section = PS.get().worlds.getConfigurationSection("worlds");
 | 
			
		||||
        for (ConfigurationNode setting : plotArea.getSettingNodes()) {
 | 
			
		||||
            Object constant = section.get(plotArea.worldname + '.' + setting.getConstant());
 | 
			
		||||
            if (constant == null || !constant.equals(section.get(this.worldname + '.' + setting.getConstant()))) {
 | 
			
		||||
@@ -491,7 +491,7 @@ public abstract class PlotArea {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public int getPlotCount(UUID uuid) {
 | 
			
		||||
        if (!Settings.DONE_COUNTS_TOWARDS_LIMIT) {
 | 
			
		||||
        if (!Settings.DONE.COUNTS_TOWARDS_LIMIT) {
 | 
			
		||||
            int count = 0;
 | 
			
		||||
            for (Plot plot : getPlotsAbs(uuid)) {
 | 
			
		||||
                if (!plot.hasFlag(Flags.DONE)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
package com.intellectualcrafters.plot.object;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
 | 
			
		||||
public class PlotBlock {
 | 
			
		||||
 | 
			
		||||
    public static final PlotBlock EVERYTHING = new PlotBlock((short) 0, (byte) 0);
 | 
			
		||||
@@ -13,7 +15,7 @@ public class PlotBlock {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static PlotBlock get(int id, int data) {
 | 
			
		||||
        return CACHE[(id << 4) + data];
 | 
			
		||||
        return Settings.ENABLED_COMPONENTS.BLOCK_CACHE && data > 0 ? CACHE[(id << 4) + data] : new PlotBlock((short) id, (byte) data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public final short id;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package com.intellectualcrafters.plot.object;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.commands.Template;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@@ -68,7 +69,7 @@ public abstract class PlotManager {
 | 
			
		||||
 | 
			
		||||
    public void exportTemplate(PlotArea plotArea) throws IOException {
 | 
			
		||||
        HashSet<FileBytes> files = new HashSet<>(
 | 
			
		||||
                Collections.singletonList(new FileBytes("templates/tmp-data.yml", Template.getBytes(plotArea))));
 | 
			
		||||
                Collections.singletonList(new FileBytes(Settings.PATHS.TEMPLATES + "/tmp-data.yml", Template.getBytes(plotArea))));
 | 
			
		||||
        Template.zipAll(plotArea.worldname, files);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import com.intellectualcrafters.plot.database.DBFunc;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.Flags;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EconHandler;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.PlotGameMode;
 | 
			
		||||
import com.intellectualcrafters.plot.util.PlotWeather;
 | 
			
		||||
@@ -121,7 +121,7 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer {
 | 
			
		||||
     * @return number of allowed plots within the scope (globally, or in the player's current world as defined in the settings.yml)
 | 
			
		||||
     */
 | 
			
		||||
    public int getAllowedPlots() {
 | 
			
		||||
        return Permissions.hasPermissionRange(this, "plots.plot", Settings.MAX_PLOTS);
 | 
			
		||||
        return Permissions.hasPermissionRange(this, "plots.plot", Settings.LIMIT.MAX_PLOTS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -133,7 +133,7 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer {
 | 
			
		||||
     * @return number of plots within the scope (globally, or in the player's current world as defined in the settings.yml)
 | 
			
		||||
     */
 | 
			
		||||
    public int getPlotCount() {
 | 
			
		||||
        if (!Settings.GLOBAL_LIMIT) {
 | 
			
		||||
        if (!Settings.LIMIT.GLOBAL) {
 | 
			
		||||
            return getPlotCount(getLocation().getWorld());
 | 
			
		||||
        }
 | 
			
		||||
        final AtomicInteger count = new AtomicInteger(0);
 | 
			
		||||
@@ -141,7 +141,7 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer {
 | 
			
		||||
        PS.get().foreachPlotArea(new RunnableVal<PlotArea>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run(PlotArea value) {
 | 
			
		||||
                if (!Settings.DONE_COUNTS_TOWARDS_LIMIT) {
 | 
			
		||||
                if (!Settings.DONE.COUNTS_TOWARDS_LIMIT) {
 | 
			
		||||
                    for (Plot plot : value.getPlotsAbs(uuid)) {
 | 
			
		||||
                        if (!plot.hasFlag(Flags.DONE)) {
 | 
			
		||||
                            count.incrementAndGet();
 | 
			
		||||
@@ -164,7 +164,7 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer {
 | 
			
		||||
        UUID uuid = getUUID();
 | 
			
		||||
        int count = 0;
 | 
			
		||||
        for (PlotArea area : PS.get().getPlotAreas(world)) {
 | 
			
		||||
            if (!Settings.DONE_COUNTS_TOWARDS_LIMIT) {
 | 
			
		||||
            if (!Settings.DONE.COUNTS_TOWARDS_LIMIT) {
 | 
			
		||||
                for (Plot plot : area.getPlotsAbs(uuid)) {
 | 
			
		||||
                    if (!plot.getFlag(Flags.DONE).isPresent()) {
 | 
			
		||||
                        count++;
 | 
			
		||||
@@ -343,7 +343,7 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer {
 | 
			
		||||
        if (plot != null) {
 | 
			
		||||
            EventUtil.manager.callLeave(this, plot);
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.DELETE_PLOTS_ON_BAN && isBanned()) {
 | 
			
		||||
        if (Settings.ENABLED_COMPONENTS.BAN_DELETER && isBanned()) {
 | 
			
		||||
            for (Plot owned : getPlots()) {
 | 
			
		||||
                owned.deletePlot(null);
 | 
			
		||||
                PS.debug(String.format("&cPlot &6%s &cwas deleted + cleared due to &6%s&c getting banned", plot.getId(), getName()));
 | 
			
		||||
 
 | 
			
		||||
@@ -18,15 +18,15 @@ public class Rating {
 | 
			
		||||
    public Rating(int value) {
 | 
			
		||||
        this.initial = value;
 | 
			
		||||
        this.ratingMap = new HashMap<>();
 | 
			
		||||
        if (Settings.RATING_CATEGORIES != null && Settings.RATING_CATEGORIES.size() > 1) {
 | 
			
		||||
        if (Settings.RATINGS.CATEGORIES != null && Settings.RATINGS.CATEGORIES.size() > 1) {
 | 
			
		||||
            if (value < 10) {
 | 
			
		||||
                for (String ratingCategory : Settings.RATING_CATEGORIES) {
 | 
			
		||||
                for (String ratingCategory : Settings.RATINGS.CATEGORIES) {
 | 
			
		||||
                    this.ratingMap.put(ratingCategory, value);
 | 
			
		||||
                }
 | 
			
		||||
                this.changed = true;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            for (String ratingCategory : Settings.RATING_CATEGORIES) {
 | 
			
		||||
            for (String ratingCategory : Settings.RATINGS.CATEGORIES) {
 | 
			
		||||
                this.ratingMap.put(ratingCategory, value % 10 - 1);
 | 
			
		||||
                value = value / 10;
 | 
			
		||||
            }
 | 
			
		||||
@@ -66,10 +66,10 @@ public class Rating {
 | 
			
		||||
        if (!this.changed) {
 | 
			
		||||
            return this.initial;
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.RATING_CATEGORIES != null && Settings.RATING_CATEGORIES.size() > 1) {
 | 
			
		||||
        if (Settings.RATINGS.CATEGORIES != null && Settings.RATINGS.CATEGORIES.size() > 1) {
 | 
			
		||||
            int val = 0;
 | 
			
		||||
            for (int i = 0; i < Settings.RATING_CATEGORIES.size(); i++) {
 | 
			
		||||
                val += (i + 1) * Math.pow(10, this.ratingMap.get(Settings.RATING_CATEGORIES.get(i)));
 | 
			
		||||
            for (int i = 0; i < Settings.RATINGS.CATEGORIES.size(); i++) {
 | 
			
		||||
                val += (i + 1) * Math.pow(10, this.ratingMap.get(Settings.RATINGS.CATEGORIES.get(i)));
 | 
			
		||||
            }
 | 
			
		||||
            return val;
 | 
			
		||||
        } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -289,9 +289,9 @@ public class BO3Handler {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static File getBaseFile(String category) {
 | 
			
		||||
        File base = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.BO3_SAVE_PATH + File.separator + category + File.separator + "base.yml");
 | 
			
		||||
        File base = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.PATHS.BO3 + File.separator + category + File.separator + "base.yml");
 | 
			
		||||
        if (!base.exists()) {
 | 
			
		||||
            PS.get().copyFile("base.yml", Settings.BO3_SAVE_PATH + File.separator + category);
 | 
			
		||||
            PS.get().copyFile("base.yml", Settings.PATHS.BO3 + File.separator + category);
 | 
			
		||||
        }
 | 
			
		||||
        return base;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ public class CommentManager {
 | 
			
		||||
    public static final HashMap<String, CommentInbox> inboxes = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    public static void sendTitle(final PlotPlayer player, final Plot plot) {
 | 
			
		||||
        if (!Settings.COMMENT_NOTIFICATIONS || !plot.isOwner(player.getUUID())) {
 | 
			
		||||
        if (!Settings.ENABLED_COMPONENTS.COMMENT_NOTIFIER || !plot.isOwner(player.getUUID())) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        TaskManager.runTaskLaterAsync(new Runnable() {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ import com.intellectualcrafters.plot.object.PlotCluster;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotId;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Rating;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
 | 
			
		||||
import com.plotsquared.listener.PlayerBlockEventType;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
@@ -66,11 +67,11 @@ public abstract class EventUtil {
 | 
			
		||||
                MainUtil.sendMessage(player, C.WORLDEDIT_BYPASSED);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (PS.get().update != null && Permissions.hasPermission(player, C.PERMISSION_ADMIN_UPDATE) && Settings.UPDATE_NOTIFICATIONS) {
 | 
			
		||||
        if (PS.get().update != null && Permissions.hasPermission(player, C.PERMISSION_ADMIN_UPDATE) && Settings.ENABLED_COMPONENTS.UPDATER) {
 | 
			
		||||
            MainUtil.sendMessage(player, "&6An update for PlotSquared is available: &7/plot update");
 | 
			
		||||
        }
 | 
			
		||||
        final Plot plot = player.getCurrentPlot();
 | 
			
		||||
        if (Settings.TELEPORT_ON_LOGIN && plot != null) {
 | 
			
		||||
        if (Settings.TELEPORT.ON_LOGIN && plot != null) {
 | 
			
		||||
            TaskManager.runTask(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
@@ -83,7 +84,7 @@ public abstract class EventUtil {
 | 
			
		||||
 | 
			
		||||
    public void doRespawnTask(final PlotPlayer player) {
 | 
			
		||||
        final Plot plot = player.getCurrentPlot();
 | 
			
		||||
        if (Settings.TELEPORT_ON_DEATH && plot != null) {
 | 
			
		||||
        if (Settings.TELEPORT.ON_DEATH && plot != null) {
 | 
			
		||||
            TaskManager.runTask(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PseudoRandom;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RegionWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
@@ -124,15 +123,15 @@ public class MainUtil {
 | 
			
		||||
        final String website;
 | 
			
		||||
        if (uuid == null) {
 | 
			
		||||
            uuid = UUID.randomUUID();
 | 
			
		||||
            website = Settings.WEB_URL + "upload.php?" + uuid;
 | 
			
		||||
            website = Settings.WEB.URL + "upload.php?" + uuid;
 | 
			
		||||
            filename = "plot." + extension;
 | 
			
		||||
        } else {
 | 
			
		||||
            website = Settings.WEB_URL + "save.php?" + uuid;
 | 
			
		||||
            website = Settings.WEB.URL + "save.php?" + uuid;
 | 
			
		||||
            filename = file + '.' + extension;
 | 
			
		||||
        }
 | 
			
		||||
        final URL url;
 | 
			
		||||
        try {
 | 
			
		||||
            url = new URL(Settings.WEB_URL + "?key=" + uuid + "&ip=" + Settings.WEB_IP + "&type=" + extension);
 | 
			
		||||
            url = new URL(Settings.WEB.URL + "?key=" + uuid + "&ip=" + Settings.WEB.SERVER_IP + "&type=" + extension);
 | 
			
		||||
        } catch (MalformedURLException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            whenDone.run();
 | 
			
		||||
@@ -664,14 +663,14 @@ public class MainUtil {
 | 
			
		||||
        HashMap<UUID, Integer> rating;
 | 
			
		||||
        if (plot.getSettings().ratings != null) {
 | 
			
		||||
            rating = plot.getSettings().ratings;
 | 
			
		||||
        } else if (Settings.CACHE_RATINGS) {
 | 
			
		||||
        } else if (Settings.ENABLED_COMPONENTS.RATING_CACHE) {
 | 
			
		||||
            rating = new HashMap<>();
 | 
			
		||||
        } else {
 | 
			
		||||
            rating = DBFunc.getRatings(plot);
 | 
			
		||||
        }
 | 
			
		||||
        int size = 1;
 | 
			
		||||
        if (Settings.RATING_CATEGORIES != null) {
 | 
			
		||||
            size = Math.max(1, Settings.RATING_CATEGORIES.size());
 | 
			
		||||
        if (!Settings.RATINGS.CATEGORIES.isEmpty()) {
 | 
			
		||||
            size = Math.max(1, Settings.RATINGS.CATEGORIES.size());
 | 
			
		||||
        }
 | 
			
		||||
        double[] ratings = new double[size];
 | 
			
		||||
        if (rating == null || rating.isEmpty()) {
 | 
			
		||||
@@ -679,10 +678,10 @@ public class MainUtil {
 | 
			
		||||
        }
 | 
			
		||||
        for (Entry<UUID, Integer> entry : rating.entrySet()) {
 | 
			
		||||
            int current = entry.getValue();
 | 
			
		||||
            if (Settings.RATING_CATEGORIES == null || Settings.RATING_CATEGORIES.isEmpty()) {
 | 
			
		||||
            if (Settings.RATINGS.CATEGORIES.isEmpty()) {
 | 
			
		||||
                ratings[0] += current;
 | 
			
		||||
            } else {
 | 
			
		||||
                for (int i = 0; i < Settings.RATING_CATEGORIES.size(); i++) {
 | 
			
		||||
                for (int i = 0; i < Settings.RATINGS.CATEGORIES.size(); i++) {
 | 
			
		||||
                    ratings[i] += current % 10 - 1;
 | 
			
		||||
                    current /= 10;
 | 
			
		||||
                }
 | 
			
		||||
@@ -740,7 +739,7 @@ public class MainUtil {
 | 
			
		||||
        String members = getPlayerList(plot.getMembers());
 | 
			
		||||
        String denied = getPlayerList(plot.getDenied());
 | 
			
		||||
        String expires = C.UNKNOWN.s();
 | 
			
		||||
        if (Settings.AUTO_CLEAR) {
 | 
			
		||||
        if (Settings.ENABLED_COMPONENTS.PLOT_EXPIRY) {
 | 
			
		||||
            if (plot.hasOwner()) {
 | 
			
		||||
                Optional<?> keep = plot.getFlag(Flags.KEEP);
 | 
			
		||||
                if (keep.isPresent()) {
 | 
			
		||||
@@ -755,11 +754,11 @@ public class MainUtil {
 | 
			
		||||
                            expires = String.format("%d days", TimeUnit.MILLISECONDS.toDays(l));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else if (ExpireManager.IMP != null) {
 | 
			
		||||
                    long timestamp = ExpireManager.IMP.getTimestamp(plot.owner);
 | 
			
		||||
                    long compared = System.currentTimeMillis() - timestamp;
 | 
			
		||||
                    long l = Settings.AUTO_CLEAR_DAYS - TimeUnit.MILLISECONDS.toDays(compared);
 | 
			
		||||
                    expires = String.format("%d days", l);
 | 
			
		||||
//                } else if (ExpireManager.IMP != null) {
 | 
			
		||||
//                    long timestamp = ExpireManager.IMP.getTimestamp(plot.owner);
 | 
			
		||||
//                    long compared = System.currentTimeMillis() - timestamp;
 | 
			
		||||
//                    long l = Settings.AUTO_CLEAR_DAYS - TimeUnit.MILLISECONDS.toDays(compared);
 | 
			
		||||
//                    expires = String.format("%d days", l);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -804,11 +803,11 @@ public class MainUtil {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    int max = 10;
 | 
			
		||||
                    if (Settings.RATING_CATEGORIES != null && !Settings.RATING_CATEGORIES.isEmpty()) {
 | 
			
		||||
                    if (Settings.RATINGS.CATEGORIES != null && !Settings.RATINGS.CATEGORIES.isEmpty()) {
 | 
			
		||||
                        max = 8;
 | 
			
		||||
                    }
 | 
			
		||||
                    String info;
 | 
			
		||||
                    if (full && Settings.RATING_CATEGORIES != null && Settings.RATING_CATEGORIES.size() > 1) {
 | 
			
		||||
                    if (full && Settings.RATINGS.CATEGORIES != null && Settings.RATINGS.CATEGORIES.size() > 1) {
 | 
			
		||||
                        double[] ratings = MainUtil.getAverageRatings(plot);
 | 
			
		||||
                        for (double v : ratings) {
 | 
			
		||||
 | 
			
		||||
@@ -817,7 +816,7 @@ public class MainUtil {
 | 
			
		||||
                        String rating = "";
 | 
			
		||||
                        String prefix = "";
 | 
			
		||||
                        for (int i = 0; i < ratings.length; i++) {
 | 
			
		||||
                            rating += prefix + Settings.RATING_CATEGORIES.get(i) + '=' + String.format("%.1f", ratings[i]);
 | 
			
		||||
                            rating += prefix + Settings.RATINGS.CATEGORIES.get(i) + '=' + String.format("%.1f", ratings[i]);
 | 
			
		||||
                            prefix = ",";
 | 
			
		||||
                        }
 | 
			
		||||
                        info = newInfo.replaceAll("%rating%", rating);
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ public class Permissions {
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean hasPermission(PlotPlayer player, String permission) {
 | 
			
		||||
        if (!Settings.PERMISSION_CACHING) {
 | 
			
		||||
        if (!Settings.ENABLED_COMPONENTS.PERMISSION_CACHE) {
 | 
			
		||||
            return hasPermission((CommandCaller) player, permission);
 | 
			
		||||
        }
 | 
			
		||||
        HashMap<String, Boolean> map = player.getMeta("perm");
 | 
			
		||||
@@ -93,7 +93,7 @@ public class Permissions {
 | 
			
		||||
    /**
 | 
			
		||||
     * Check the the highest permission a PlotPlayer has within a specified range.<br>
 | 
			
		||||
     *  - Excessively high values will lag<br>
 | 
			
		||||
     *  - The default range that is checked is {@link Settings#MAX_PLOTS}<br>
 | 
			
		||||
     *  - The default range that is checked is {@link Settings#LIMIT#MAX_PLOTS}<br>
 | 
			
		||||
     * @param player
 | 
			
		||||
     * @param stub The permission stub to check e.g. for `plots.plot.#` the stub is `plots.plot`
 | 
			
		||||
     * @param range The range to check
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,7 @@ public abstract class SchematicHandler {
 | 
			
		||||
                }
 | 
			
		||||
                final String directory;
 | 
			
		||||
                if (outputDir == null) {
 | 
			
		||||
                    directory = Settings.SCHEMATIC_SAVE_PATH;
 | 
			
		||||
                    directory = Settings.PATHS.SCHEMATICS;
 | 
			
		||||
                } else {
 | 
			
		||||
                    directory = outputDir.getAbsolutePath();
 | 
			
		||||
                }
 | 
			
		||||
@@ -451,14 +451,14 @@ public abstract class SchematicHandler {
 | 
			
		||||
     * @return schematic if found, else null
 | 
			
		||||
     */
 | 
			
		||||
    public Schematic getSchematic(String name) {
 | 
			
		||||
        File parent = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.SCHEMATIC_SAVE_PATH);
 | 
			
		||||
        File parent = MainUtil.getFile(PS.get().IMP.getDirectory(), Settings.PATHS.SCHEMATICS);
 | 
			
		||||
        if (!parent.exists()) {
 | 
			
		||||
            if (!parent.mkdir()) {
 | 
			
		||||
                throw new RuntimeException("Could not create schematic parent directory");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        File file = MainUtil.getFile(PS.get().IMP.getDirectory(),
 | 
			
		||||
                Settings.SCHEMATIC_SAVE_PATH + File.separator + name + (name.endsWith(".schematic") ? "" : ".schematic"));
 | 
			
		||||
                Settings.PATHS.SCHEMATICS + File.separator + name + (name.endsWith(".schematic") ? "" : ".schematic"));
 | 
			
		||||
        return getSchematic(file);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@@ -512,7 +512,7 @@ public abstract class SchematicHandler {
 | 
			
		||||
    public List<String> getSaves(UUID uuid) {
 | 
			
		||||
        StringBuilder rawJSON = new StringBuilder();
 | 
			
		||||
        try {
 | 
			
		||||
            String website = Settings.WEB_URL + "list.php?" + uuid.toString();
 | 
			
		||||
            String website = Settings.WEB.URL + "list.php?" + uuid.toString();
 | 
			
		||||
            URL url = new URL(website);
 | 
			
		||||
            URLConnection connection = new URL(url.toString()).openConnection();
 | 
			
		||||
            connection.setRequestProperty("User-Agent", "Mozilla/5.0");
 | 
			
		||||
 
 | 
			
		||||
@@ -110,7 +110,7 @@ public abstract class UUIDHandlerImplementation {
 | 
			
		||||
         *  - Useful if the person misconfigured the database, or settings before
 | 
			
		||||
          *   PlotMe conversion
 | 
			
		||||
         */
 | 
			
		||||
        if (!Settings.OFFLINE_MODE && !this.unknown.isEmpty()) {
 | 
			
		||||
        if (!Settings.UUID.OFFLINE && !this.unknown.isEmpty()) {
 | 
			
		||||
            TaskManager.runTaskAsync(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
@@ -213,12 +213,12 @@ public abstract class UUIDHandlerImplementation {
 | 
			
		||||
            return uuid;
 | 
			
		||||
        }
 | 
			
		||||
        // Read from disk OR convert directly to offline UUID
 | 
			
		||||
        if (Settings.OFFLINE_MODE) {
 | 
			
		||||
        if (Settings.UUID.OFFLINE) {
 | 
			
		||||
            uuid = this.uuidWrapper.getUUID(name);
 | 
			
		||||
            add(new StringWrapper(name), uuid);
 | 
			
		||||
            return uuid;
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.UUID_FROM_DISK && (ifFetch != null)) {
 | 
			
		||||
        if ((ifFetch != null)) {
 | 
			
		||||
            fetchUUID(name, ifFetch);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package com.intellectualcrafters.plot.util;
 | 
			
		||||
package com.intellectualcrafters.plot.util.expiry;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Optional;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
@@ -10,27 +10,44 @@ import com.intellectualcrafters.plot.flag.Flags;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotArea;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotMessage;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal2;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal3;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.UUIDHandler;
 | 
			
		||||
import java.util.ArrayDeque;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
public class ExpireManager {
 | 
			
		||||
 | 
			
		||||
    public static ExpireManager IMP;
 | 
			
		||||
 | 
			
		||||
    private static HashSet<Plot> plotsToDelete;
 | 
			
		||||
    private final ConcurrentHashMap<UUID, Long> dates_cache = new ConcurrentHashMap<>();
 | 
			
		||||
    private volatile HashSet<Plot> plotsToDelete;
 | 
			
		||||
    private final ConcurrentHashMap<UUID, Long> dates_cache;
 | 
			
		||||
 | 
			
		||||
    private ArrayDeque<ExpiryTask> tasks;
 | 
			
		||||
 | 
			
		||||
    public ExpireManager() {
 | 
			
		||||
        tasks = new ArrayDeque<>();
 | 
			
		||||
        dates_cache = new ConcurrentHashMap<>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addTask(ExpiryTask task) {
 | 
			
		||||
        this.tasks.add(task);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 0 = stopped, 1 = stopping, 2 = running
 | 
			
		||||
     */
 | 
			
		||||
@@ -42,8 +59,7 @@ public class ExpireManager {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void handleEntry(PlotPlayer pp, Plot plot) {
 | 
			
		||||
        if (Settings.AUTO_CLEAR_CONFIRMATION && plotsToDelete != null && !plotsToDelete.isEmpty() && pp.hasPermission("plots.admin.command.autoclear")
 | 
			
		||||
                && plotsToDelete.contains(plot) && !isExpired(plot)) {
 | 
			
		||||
        if (plotsToDelete != null && !plotsToDelete.isEmpty() && pp.hasPermission("plots.admin.command.autoclear") && plotsToDelete.contains(plot) && !isExpired(new ArrayDeque<>(tasks), plot).isEmpty()) {
 | 
			
		||||
            plotsToDelete.remove(plot);
 | 
			
		||||
            confirmExpiry(pp);
 | 
			
		||||
        }
 | 
			
		||||
@@ -55,11 +71,11 @@ public class ExpireManager {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void confirmExpiry(final PlotPlayer pp) {
 | 
			
		||||
        if (Settings.AUTO_CLEAR_CONFIRMATION && plotsToDelete != null && !plotsToDelete.isEmpty() && pp
 | 
			
		||||
        if (plotsToDelete != null && !plotsToDelete.isEmpty() && pp
 | 
			
		||||
                .hasPermission("plots.admin.command.autoclear")) {
 | 
			
		||||
            final int num = plotsToDelete.size();
 | 
			
		||||
            for (final Plot current : plotsToDelete) {
 | 
			
		||||
                if (isExpired(current)) {
 | 
			
		||||
                if (!isExpired(new ArrayDeque<>(tasks), current).isEmpty()) {
 | 
			
		||||
                    TaskManager.runTask(new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
@@ -93,29 +109,100 @@ public class ExpireManager {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean runConfirmedTask() {
 | 
			
		||||
        if (plotsToDelete == null) {
 | 
			
		||||
            plotsToDelete = new HashSet<>();
 | 
			
		||||
        }
 | 
			
		||||
        return runTask(new RunnableVal2<Plot, Runnable>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run(Plot plot, Runnable runnable) {
 | 
			
		||||
                plotsToDelete.add(plot);
 | 
			
		||||
                runnable.run();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean runAutomatedTask() {
 | 
			
		||||
        return runTask(new RunnableVal2<Plot, Runnable>() {
 | 
			
		||||
        return runTask(new RunnableVal3<Plot, Runnable, Boolean>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run(Plot plot, Runnable runnable) {
 | 
			
		||||
                deleteWithMessage(plot, runnable);
 | 
			
		||||
            public void run(Plot plot, Runnable runnable, Boolean confirm) {
 | 
			
		||||
                if (confirm) {
 | 
			
		||||
                    if (plotsToDelete == null) {
 | 
			
		||||
                        plotsToDelete = new HashSet<>();
 | 
			
		||||
                    }
 | 
			
		||||
                    plotsToDelete.add(plot);
 | 
			
		||||
                    runnable.run();
 | 
			
		||||
                } else {
 | 
			
		||||
                    deleteWithMessage(plot, runnable);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean runTask(final RunnableVal2<Plot, Runnable> expiredTask) {
 | 
			
		||||
    public Collection<ExpiryTask> isExpired(ArrayDeque<ExpiryTask> applicable, Plot plot) {
 | 
			
		||||
        // Filter out invalid worlds
 | 
			
		||||
        for (int i = 0; i < applicable.size(); i++) {
 | 
			
		||||
            ExpiryTask et = applicable.poll();
 | 
			
		||||
            if (et.applies(plot.getArea())) {
 | 
			
		||||
                applicable.add(et);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (applicable.isEmpty()) {
 | 
			
		||||
            return new ArrayList<>();
 | 
			
		||||
        }
 | 
			
		||||
        long diff = getAge(plot);
 | 
			
		||||
        if (diff == 0) {
 | 
			
		||||
            return new ArrayList<>();
 | 
			
		||||
        }
 | 
			
		||||
        // Filter out non old plots
 | 
			
		||||
        for (int i = 0; i < applicable.size(); i++) {
 | 
			
		||||
            ExpiryTask et = applicable.poll();
 | 
			
		||||
            if (et.applies(diff)) {
 | 
			
		||||
                applicable.add(et);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (applicable.isEmpty()) {
 | 
			
		||||
            return new ArrayList<>();
 | 
			
		||||
        }
 | 
			
		||||
        // Run applicable non confirming tasks
 | 
			
		||||
        for (int i = 0; i < applicable.size(); i++) {
 | 
			
		||||
            ExpiryTask et = applicable.poll();
 | 
			
		||||
            if (!et.needsAnalysis() || plot.getArea().TYPE != 0) {
 | 
			
		||||
                if (!et.requiresConfirmation()) {
 | 
			
		||||
                    return Arrays.asList(et);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            applicable.add(et);
 | 
			
		||||
        }
 | 
			
		||||
        // Run applicable confirming tasks
 | 
			
		||||
        for (int i = 0; i < applicable.size(); i++) {
 | 
			
		||||
            ExpiryTask et = applicable.poll();
 | 
			
		||||
            if (!et.needsAnalysis() || plot.getArea().TYPE != 0) {
 | 
			
		||||
                return Arrays.asList(et);
 | 
			
		||||
            }
 | 
			
		||||
            applicable.add(et);
 | 
			
		||||
        }
 | 
			
		||||
        return applicable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ArrayDeque<ExpiryTask> getTasks(PlotArea area) {
 | 
			
		||||
        ArrayDeque<ExpiryTask> queue = new ArrayDeque<>(tasks);
 | 
			
		||||
        Iterator<ExpiryTask> iter = queue.iterator();
 | 
			
		||||
        while (iter.hasNext()) {
 | 
			
		||||
            if (!iter.next().applies(area)) {
 | 
			
		||||
                iter.remove();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return queue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void passesComplexity(PlotAnalysis analysis, Collection<ExpiryTask> applicable, RunnableVal<Boolean> success, Runnable failure) {
 | 
			
		||||
        if (analysis != null) {
 | 
			
		||||
            // Run non confirming tasks
 | 
			
		||||
            for (ExpiryTask et : applicable) {
 | 
			
		||||
                if (!et.requiresConfirmation() && et.applies(analysis)) {
 | 
			
		||||
                    success.run(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (ExpiryTask et : applicable) {
 | 
			
		||||
                if (et.applies(analysis)) {
 | 
			
		||||
                    success.run(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            failure.run();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean runTask(final RunnableVal3<Plot, Runnable, Boolean> expiredTask) {
 | 
			
		||||
        if (this.running != 0) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -128,7 +215,6 @@ public class ExpireManager {
 | 
			
		||||
                    ExpireManager.this.running = 0;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                final Runnable task = this;
 | 
			
		||||
                long start = System.currentTimeMillis();
 | 
			
		||||
                Iterator<Plot> iterator = plots.iterator();
 | 
			
		||||
                while (iterator.hasNext() && System.currentTimeMillis() - start < 2) {
 | 
			
		||||
@@ -138,38 +224,57 @@ public class ExpireManager {
 | 
			
		||||
                    }
 | 
			
		||||
                    final Plot plot = iterator.next();
 | 
			
		||||
                    iterator.remove();
 | 
			
		||||
                    if (!isExpired(plot)) {
 | 
			
		||||
                    PlotArea area = plot.getArea();
 | 
			
		||||
                    final ArrayDeque<ExpiryTask> applicable = new ArrayDeque<>(tasks);
 | 
			
		||||
                    final Collection<ExpiryTask> expired = isExpired(applicable, plot);
 | 
			
		||||
                    if (expired.isEmpty()) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    PlotArea area = plot.getArea();
 | 
			
		||||
                    if ((Settings.CLEAR_THRESHOLD != -1) && (area.TYPE == 0)) {
 | 
			
		||||
                        PlotAnalysis analysis = plot.getComplexity();
 | 
			
		||||
                        if (analysis != null) {
 | 
			
		||||
                            if (analysis.getComplexity() > Settings.CLEAR_THRESHOLD) {
 | 
			
		||||
                                PS.debug("$2[&5Expire&dManager$2] &bSkipping modified: " + plot);
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
                    for (ExpiryTask et : expired) {
 | 
			
		||||
                        if (!et.needsAnalysis()) {
 | 
			
		||||
                            expiredTask.run(plot, this, et.requiresConfirmation());
 | 
			
		||||
                        }
 | 
			
		||||
                        HybridUtils.manager.analyzePlot(plot, new RunnableVal<PlotAnalysis>() {
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void run(PlotAnalysis changed) {
 | 
			
		||||
                                if ((changed.changes != 0) && (changed.getComplexity() > Settings.CLEAR_THRESHOLD)) {
 | 
			
		||||
                                    PS.debug("$2[&5Expire&dManager$2] &bIgnoring modified plot: " + plot + " : " + changed.getComplexity() + " - "
 | 
			
		||||
                                            + changed.changes);
 | 
			
		||||
                                    FlagManager.addPlotFlag(plot, Flags.ANALYSIS, changed.asList());
 | 
			
		||||
                                    TaskManager.runTaskLaterAsync(task, Settings.CLEAR_INTERVAL * 20);
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    expiredTask.run(plot, new Runnable() {
 | 
			
		||||
                                        @Override
 | 
			
		||||
                                        public void run() {
 | 
			
		||||
                                            TaskManager.runTaskLater(task, Settings.CLEAR_INTERVAL * 20);
 | 
			
		||||
                                        }
 | 
			
		||||
                                    });
 | 
			
		||||
                    }
 | 
			
		||||
                    final Runnable task = this;
 | 
			
		||||
                    final RunnableVal<PlotAnalysis> handleAnalysis = new RunnableVal<PlotAnalysis>() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run(final PlotAnalysis changed) {
 | 
			
		||||
                            passesComplexity(changed, expired, new RunnableVal<Boolean>() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void run(Boolean confirmation) {
 | 
			
		||||
                                    expiredTask.run(plot, this, confirmation);
 | 
			
		||||
                                }
 | 
			
		||||
                            }, new Runnable() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void run() {
 | 
			
		||||
                                    FlagManager.addPlotFlag(plot, Flags.ANALYSIS, changed.asList());
 | 
			
		||||
                                    TaskManager.runTaskLaterAsync(task, 20);
 | 
			
		||||
                                }
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                    final Runnable doAnalysis = new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            HybridUtils.manager.analyzePlot(plot, handleAnalysis);
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    PlotAnalysis analysis = plot.getComplexity(null);
 | 
			
		||||
                    if (analysis != null) {
 | 
			
		||||
                        passesComplexity(analysis, expired, new RunnableVal<Boolean>() {
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void run(Boolean value) {
 | 
			
		||||
                                doAnalysis.run();
 | 
			
		||||
                            }
 | 
			
		||||
                        }, new Runnable() {
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void run() {
 | 
			
		||||
                                task.run();
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                    } else {
 | 
			
		||||
                        expiredTask.run(plot, this);
 | 
			
		||||
                        doAnalysis.run();
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
@@ -185,7 +290,7 @@ public class ExpireManager {
 | 
			
		||||
                        }
 | 
			
		||||
                    }, 86400000);
 | 
			
		||||
                } else {
 | 
			
		||||
                    TaskManager.runTaskLaterAsync(task, Settings.CLEAR_INTERVAL * 20);
 | 
			
		||||
                    TaskManager.runTaskLaterAsync(this, 20);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
@@ -217,10 +322,10 @@ public class ExpireManager {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        plot.deletePlot(whenDone);
 | 
			
		||||
        PlotAnalysis changed = plot.getComplexity();
 | 
			
		||||
        int complexity = changed == null ? 0 : changed.getComplexity();
 | 
			
		||||
        PlotAnalysis changed = plot.getComplexity(null);
 | 
			
		||||
        int changes = changed == null ? 0 : changed.changes_sd;
 | 
			
		||||
        int modified = changed == null ? 0 : changed.changes;
 | 
			
		||||
        PS.debug("$2[&5Expire&dManager$2] &cDeleted expired plot: " + plot + " : " + complexity + " - " + modified);
 | 
			
		||||
        PS.debug("$2[&5Expire&dManager$2] &cDeleted expired plot: " + plot + " : " + changes + " - " + modified);
 | 
			
		||||
        PS.debug("$4 - Area: " + plot.getArea());
 | 
			
		||||
        if (plot.hasOwner()) {
 | 
			
		||||
            PS.debug("$4 - Owner: " + UUIDHandler.getName(plot.owner));
 | 
			
		||||
@@ -229,16 +334,16 @@ public class ExpireManager {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isExpired(UUID uuid) {
 | 
			
		||||
    public long getAge(UUID uuid) {
 | 
			
		||||
        if (UUIDHandler.getPlayer(uuid) != null) {
 | 
			
		||||
            return false;
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        String name = UUIDHandler.getName(uuid);
 | 
			
		||||
        if (name != null) {
 | 
			
		||||
            Long last = this.dates_cache.get(uuid);
 | 
			
		||||
            if (last == null) {
 | 
			
		||||
                OfflinePlotPlayer opp;
 | 
			
		||||
                if (Settings.TWIN_MODE_UUID) {
 | 
			
		||||
                if (Settings.UUID.NATIVE_UUID_PROVIDER) {
 | 
			
		||||
                    opp = UUIDHandler.getUUIDWrapper().getOfflinePlayer(uuid);
 | 
			
		||||
                } else {
 | 
			
		||||
                    opp = UUIDHandler.getUUIDWrapper().getOfflinePlayer(name);
 | 
			
		||||
@@ -246,44 +351,44 @@ public class ExpireManager {
 | 
			
		||||
                if ((last = opp.getLastPlayed()) != 0) {
 | 
			
		||||
                    this.dates_cache.put(uuid, last);
 | 
			
		||||
                } else {
 | 
			
		||||
                    return false;
 | 
			
		||||
                    return 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (last == 0) {
 | 
			
		||||
                return false;
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
            long compared = System.currentTimeMillis() - last;
 | 
			
		||||
            if (compared >= TimeUnit.DAYS.toMillis(Settings.AUTO_CLEAR_DAYS)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            return compared;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isExpired(Plot plot) {
 | 
			
		||||
    public long getAge(Plot plot) {
 | 
			
		||||
        if (!plot.hasOwner() || Objects.equals(DBFunc.everyone, plot.owner) || UUIDHandler.getPlayer(plot.owner) != null || plot.getRunning() > 0) {
 | 
			
		||||
            return false;
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        Optional<?> keep = plot.getFlag(Flags.KEEP);
 | 
			
		||||
        if (keep.isPresent()) {
 | 
			
		||||
            Object value = keep.get();
 | 
			
		||||
            if (value instanceof Boolean) {
 | 
			
		||||
                if (Boolean.TRUE.equals(value)) {
 | 
			
		||||
                    return false;
 | 
			
		||||
                    return 0;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (value instanceof Long) {
 | 
			
		||||
                if ((Long) value > System.currentTimeMillis()) {
 | 
			
		||||
                    return false;
 | 
			
		||||
                    return 0;
 | 
			
		||||
                }
 | 
			
		||||
            } else { // Invalid?
 | 
			
		||||
                return false;
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        long max = 0;
 | 
			
		||||
        for (UUID owner : plot.getOwners()) {
 | 
			
		||||
            if (!isExpired(owner)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            long age = getAge(owner);
 | 
			
		||||
            if (age > max) {
 | 
			
		||||
                max = age;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
        return max;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
package com.intellectualcrafters.plot.util.expiry;
 | 
			
		||||
 | 
			
		||||
public class ExpirySettings {
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
package com.intellectualcrafters.plot.util.expiry;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotArea;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
public class ExpiryTask {
 | 
			
		||||
    private final Settings.AUTO_CLEAR settings;
 | 
			
		||||
 | 
			
		||||
    public ExpiryTask(Settings.AUTO_CLEAR settings) {
 | 
			
		||||
        this.settings = settings;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean applies(PlotArea area) {
 | 
			
		||||
        return settings.WORLDS.contains(area.toString()) || settings.WORLDS.contains(area.worldname) || settings.WORLDS.contains("*");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean applies(long diff) {
 | 
			
		||||
        return diff > TimeUnit.DAYS.toMillis(settings.DAYS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean needsAnalysis() {
 | 
			
		||||
        return settings.THRESHOLD > 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean applies(PlotAnalysis analysis) {
 | 
			
		||||
        return analysis.getComplexity(settings) <= settings.THRESHOLD;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean requiresConfirmation() {
 | 
			
		||||
        return settings.CONFIRMATION;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +1,14 @@
 | 
			
		||||
package com.intellectualcrafters.plot.object;
 | 
			
		||||
package com.intellectualcrafters.plot.util.expiry;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Optional;
 | 
			
		||||
import com.intellectualcrafters.configuration.file.YamlConfiguration;
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.flag.Flags;
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.object.Plot;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MathMan;
 | 
			
		||||
import com.intellectualcrafters.plot.util.TaskManager;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.Array;
 | 
			
		||||
import java.util.ArrayDeque;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
@@ -18,8 +18,6 @@ import java.util.List;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
			
		||||
 | 
			
		||||
public class PlotAnalysis {
 | 
			
		||||
 | 
			
		||||
    public static final PlotAnalysis MODIFIERS = new PlotAnalysis();
 | 
			
		||||
    public static boolean running = false;
 | 
			
		||||
    public int changes;
 | 
			
		||||
    public int faces;
 | 
			
		||||
@@ -33,7 +31,7 @@ public class PlotAnalysis {
 | 
			
		||||
    public int variety_sd;
 | 
			
		||||
    private int complexity;
 | 
			
		||||
 | 
			
		||||
    public static PlotAnalysis getAnalysis(Plot plot) {
 | 
			
		||||
    public static PlotAnalysis getAnalysis(Plot plot, Settings.AUTO_CLEAR settings) {
 | 
			
		||||
        Optional<List<Integer>> flag = plot.getFlag(Flags.ANALYSIS);
 | 
			
		||||
        if (flag.isPresent()) {
 | 
			
		||||
            PlotAnalysis analysis = new PlotAnalysis();
 | 
			
		||||
@@ -50,7 +48,7 @@ public class PlotAnalysis {
 | 
			
		||||
            analysis.air_sd = values.get(8); // 18909
 | 
			
		||||
            analysis.variety_sd = values.get(9); // 263
 | 
			
		||||
 | 
			
		||||
            analysis.complexity = analysis.getComplexity();
 | 
			
		||||
            analysis.complexity = settings != null ? analysis.getComplexity(settings) : 0;
 | 
			
		||||
            return analysis;
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
@@ -182,7 +180,7 @@ public class PlotAnalysis {
 | 
			
		||||
                for (int i = 0; i < plots.size(); i++) {
 | 
			
		||||
                    Plot plot = plots.get(i);
 | 
			
		||||
                    PS.debug(" | " + plot);
 | 
			
		||||
                    PlotAnalysis analysis = plot.getComplexity();
 | 
			
		||||
                    PlotAnalysis analysis = plot.getComplexity(null);
 | 
			
		||||
 | 
			
		||||
                    changes[i] = analysis.changes;
 | 
			
		||||
                    faces[i] = analysis.faces;
 | 
			
		||||
@@ -208,12 +206,14 @@ public class PlotAnalysis {
 | 
			
		||||
                PS.debug(" - The analyzed plots which were processed and put into bulk data will be compared and correlated to the plot ranking");
 | 
			
		||||
                PS.debug(" - The calculated correlation constant will then be used to calibrate the threshold for auto plot clearing");
 | 
			
		||||
 | 
			
		||||
                Settings.AUTO_CLEAR settings = new Settings.AUTO_CLEAR();
 | 
			
		||||
                
 | 
			
		||||
                int[] rankChanges = rank(changes);
 | 
			
		||||
                int[] sdChanges = getSD(rankChanges, rankRatings);
 | 
			
		||||
                int[] varianceChanges = square(sdChanges);
 | 
			
		||||
                int sumChanges = sum(varianceChanges);
 | 
			
		||||
                double factorChanges = getCC(n, sumChanges);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.changes = factorChanges == 1 ? 0 : (int) (factorChanges * 1000 / MathMan.getMean(changes));
 | 
			
		||||
                settings.CALIBRATION.CHANGES = factorChanges == 1 ? 0 : (int) (factorChanges * 1000 / MathMan.getMean(changes));
 | 
			
		||||
                PS.debug(" - | changes " + factorChanges);
 | 
			
		||||
 | 
			
		||||
                int[] rankFaces = rank(faces);
 | 
			
		||||
@@ -221,7 +221,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int[] varianceFaces = square(sdFaces);
 | 
			
		||||
                int sumFaces = sum(varianceFaces);
 | 
			
		||||
                double factorFaces = getCC(n, sumFaces);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.faces = factorFaces == 1 ? 0 : (int) (factorFaces * 1000 / MathMan.getMean(faces));
 | 
			
		||||
                settings.CALIBRATION.FACES = factorFaces == 1 ? 0 : (int) (factorFaces * 1000 / MathMan.getMean(faces));
 | 
			
		||||
                PS.debug(" - | faces " + factorFaces);
 | 
			
		||||
 | 
			
		||||
                int[] rankData = rank(data);
 | 
			
		||||
@@ -229,7 +229,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int[] variance_data = square(sdData);
 | 
			
		||||
                int sum_data = sum(variance_data);
 | 
			
		||||
                double factor_data = getCC(n, sum_data);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.data = factor_data == 1 ? 0 : (int) (factor_data * 1000 / MathMan.getMean(data));
 | 
			
		||||
                settings.CALIBRATION.DATA = factor_data == 1 ? 0 : (int) (factor_data * 1000 / MathMan.getMean(data));
 | 
			
		||||
                PS.debug(" - | data " + factor_data);
 | 
			
		||||
 | 
			
		||||
                int[] rank_air = rank(air);
 | 
			
		||||
@@ -237,7 +237,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int[] variance_air = square(sd_air);
 | 
			
		||||
                int sum_air = sum(variance_air);
 | 
			
		||||
                double factor_air = getCC(n, sum_air);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.air = factor_air == 1 ? 0 : (int) (factor_air * 1000 / MathMan.getMean(air));
 | 
			
		||||
                settings.CALIBRATION.AIR = factor_air == 1 ? 0 : (int) (factor_air * 1000 / MathMan.getMean(air));
 | 
			
		||||
                PS.debug(" - | air " + factor_air);
 | 
			
		||||
 | 
			
		||||
                int[] rank_variety = rank(variety);
 | 
			
		||||
@@ -245,7 +245,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int[] variance_variety = square(sd_variety);
 | 
			
		||||
                int sum_variety = sum(variance_variety);
 | 
			
		||||
                double factor_variety = getCC(n, sum_variety);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.variety = factor_variety == 1 ? 0 : (int) (factor_variety * 1000 / MathMan.getMean(variety));
 | 
			
		||||
                settings.CALIBRATION.VARIETY = factor_variety == 1 ? 0 : (int) (factor_variety * 1000 / MathMan.getMean(variety));
 | 
			
		||||
                PS.debug(" - | variety " + factor_variety);
 | 
			
		||||
 | 
			
		||||
                int[] rank_changes_sd = rank(changes_sd);
 | 
			
		||||
@@ -253,7 +253,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int[] variance_changes_sd = square(sd_changes_sd);
 | 
			
		||||
                int sum_changes_sd = sum(variance_changes_sd);
 | 
			
		||||
                double factor_changes_sd = getCC(n, sum_changes_sd);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.changes_sd = factor_changes_sd == 1 ? 0 : (int) (factor_changes_sd * 1000 / MathMan.getMean(changes_sd));
 | 
			
		||||
                settings.CALIBRATION.CHANGES_SD = factor_changes_sd == 1 ? 0 : (int) (factor_changes_sd * 1000 / MathMan.getMean(changes_sd));
 | 
			
		||||
                PS.debug(" - | changes_sd " + factor_changes_sd);
 | 
			
		||||
 | 
			
		||||
                int[] rank_faces_sd = rank(faces_sd);
 | 
			
		||||
@@ -261,7 +261,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int[] variance_faces_sd = square(sd_faces_sd);
 | 
			
		||||
                int sum_faces_sd = sum(variance_faces_sd);
 | 
			
		||||
                double factor_faces_sd = getCC(n, sum_faces_sd);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.faces_sd = factor_faces_sd == 1 ? 0 : (int) (factor_faces_sd * 1000 / MathMan.getMean(faces_sd));
 | 
			
		||||
                settings.CALIBRATION.FACES_SD = factor_faces_sd == 1 ? 0 : (int) (factor_faces_sd * 1000 / MathMan.getMean(faces_sd));
 | 
			
		||||
                PS.debug(" - | faces_sd " + factor_faces_sd);
 | 
			
		||||
 | 
			
		||||
                int[] rank_data_sd = rank(data_sd);
 | 
			
		||||
@@ -269,7 +269,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int[] variance_data_sd = square(sd_data_sd);
 | 
			
		||||
                int sum_data_sd = sum(variance_data_sd);
 | 
			
		||||
                double factor_data_sd = getCC(n, sum_data_sd);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.data_sd = factor_data_sd == 1 ? 0 : (int) (factor_data_sd * 1000 / MathMan.getMean(data_sd));
 | 
			
		||||
                settings.CALIBRATION.DATA_SD = factor_data_sd == 1 ? 0 : (int) (factor_data_sd * 1000 / MathMan.getMean(data_sd));
 | 
			
		||||
                PS.debug(" - | data_sd " + factor_data_sd);
 | 
			
		||||
 | 
			
		||||
                int[] rank_air_sd = rank(air_sd);
 | 
			
		||||
@@ -277,7 +277,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int[] variance_air_sd = square(sd_air_sd);
 | 
			
		||||
                int sum_air_sd = sum(variance_air_sd);
 | 
			
		||||
                double factor_air_sd = getCC(n, sum_air_sd);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.air_sd = factor_air_sd == 1 ? 0 : (int) (factor_air_sd * 1000 / MathMan.getMean(air_sd));
 | 
			
		||||
                settings.CALIBRATION.AIR_SD = factor_air_sd == 1 ? 0 : (int) (factor_air_sd * 1000 / MathMan.getMean(air_sd));
 | 
			
		||||
                PS.debug(" - | air_sd " + factor_air_sd);
 | 
			
		||||
 | 
			
		||||
                int[] rank_variety_sd = rank(variety_sd);
 | 
			
		||||
@@ -285,7 +285,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int[] variance_variety_sd = square(sd_variety_sd);
 | 
			
		||||
                int sum_variety_sd = sum(variance_variety_sd);
 | 
			
		||||
                double factor_variety_sd = getCC(n, sum_variety_sd);
 | 
			
		||||
                PlotAnalysis.MODIFIERS.variety_sd = factor_variety_sd == 1 ? 0 : (int) (factor_variety_sd * 1000 / MathMan.getMean(variety_sd));
 | 
			
		||||
                settings.CALIBRATION.VARIETY_SD = factor_variety_sd == 1 ? 0 : (int) (factor_variety_sd * 1000 / MathMan.getMean(variety_sd));
 | 
			
		||||
                PS.debug(" - | variety_sd " + factor_variety_sd);
 | 
			
		||||
 | 
			
		||||
                int[] complexity = new int[n];
 | 
			
		||||
@@ -295,7 +295,7 @@ public class PlotAnalysis {
 | 
			
		||||
                int min = 0;
 | 
			
		||||
                for (int i = 0; i < n; i++) {
 | 
			
		||||
                    Plot plot = plots.get(i);
 | 
			
		||||
                    PlotAnalysis analysis = plot.getComplexity();
 | 
			
		||||
                    PlotAnalysis analysis = plot.getComplexity(settings);
 | 
			
		||||
                    complexity[i] = analysis.complexity;
 | 
			
		||||
                    if (analysis.complexity < min) {
 | 
			
		||||
                        min = analysis.complexity;
 | 
			
		||||
@@ -338,24 +338,8 @@ public class PlotAnalysis {
 | 
			
		||||
 | 
			
		||||
                // Save calibration
 | 
			
		||||
                PS.debug(" $1Saving calibration");
 | 
			
		||||
                YamlConfiguration config = PS.get().config;
 | 
			
		||||
                config.set("clear.auto.threshold", optimalComplexity);
 | 
			
		||||
                config.set("clear.auto.calibration.changes", PlotAnalysis.MODIFIERS.changes);
 | 
			
		||||
                config.set("clear.auto.calibration.faces", PlotAnalysis.MODIFIERS.faces);
 | 
			
		||||
                config.set("clear.auto.calibration.data", PlotAnalysis.MODIFIERS.data);
 | 
			
		||||
                config.set("clear.auto.calibration.air", PlotAnalysis.MODIFIERS.air);
 | 
			
		||||
                config.set("clear.auto.calibration.variety", PlotAnalysis.MODIFIERS.variety);
 | 
			
		||||
                config.set("clear.auto.calibration.changes_sd", PlotAnalysis.MODIFIERS.changes_sd);
 | 
			
		||||
                config.set("clear.auto.calibration.faces_sd", PlotAnalysis.MODIFIERS.faces_sd);
 | 
			
		||||
                config.set("clear.auto.calibration.data_sd", PlotAnalysis.MODIFIERS.data_sd);
 | 
			
		||||
                config.set("clear.auto.calibration.air_sd", PlotAnalysis.MODIFIERS.air_sd);
 | 
			
		||||
                config.set("clear.auto.calibration.variety_sd", PlotAnalysis.MODIFIERS.variety_sd);
 | 
			
		||||
                try {
 | 
			
		||||
                    PS.get().config.save(PS.get().configFile);
 | 
			
		||||
                } catch (IOException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Settings.AUTO_CLEAR.put("auto-calibrated", settings);
 | 
			
		||||
                Settings.save(PS.get().worldsFile);
 | 
			
		||||
                PS.debug("$1Done!");
 | 
			
		||||
                running = false;
 | 
			
		||||
                for (Plot plot : plots) {
 | 
			
		||||
@@ -544,20 +528,21 @@ public class PlotAnalysis {
 | 
			
		||||
                this.variety_sd);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getComplexity() {
 | 
			
		||||
    public int getComplexity(Settings.AUTO_CLEAR settings) {
 | 
			
		||||
        Settings.AUTO_CLEAR.CALIBRATION modifiers = settings.CALIBRATION;
 | 
			
		||||
        if (this.complexity != 0) {
 | 
			
		||||
            return this.complexity;
 | 
			
		||||
        }
 | 
			
		||||
        this.complexity = this.changes * MODIFIERS.changes
 | 
			
		||||
                + this.faces * MODIFIERS.faces
 | 
			
		||||
                + this.data * MODIFIERS.data
 | 
			
		||||
                + this.air * MODIFIERS.air
 | 
			
		||||
                + this.variety * MODIFIERS.variety
 | 
			
		||||
                + this.changes_sd * MODIFIERS.changes_sd
 | 
			
		||||
                + this.faces_sd * MODIFIERS.faces_sd
 | 
			
		||||
                + this.data_sd * MODIFIERS.data_sd
 | 
			
		||||
                + this.air_sd * MODIFIERS.air_sd
 | 
			
		||||
                + this.variety_sd * MODIFIERS.variety_sd;
 | 
			
		||||
        this.complexity = this.changes * modifiers.CHANGES
 | 
			
		||||
                + this.faces * modifiers.FACES
 | 
			
		||||
                + this.data * modifiers.DATA
 | 
			
		||||
                + this.air * modifiers.AIR
 | 
			
		||||
                + this.variety * modifiers.VARIETY
 | 
			
		||||
                + this.changes_sd * modifiers.CHANGES_SD
 | 
			
		||||
                + this.faces_sd * modifiers.FACES_SD
 | 
			
		||||
                + this.data_sd * modifiers.DATA_SD
 | 
			
		||||
                + this.air_sd * modifiers.AIR_SD
 | 
			
		||||
                + this.variety_sd * modifiers.VARIETY_SD;
 | 
			
		||||
        return this.complexity;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -14,7 +14,7 @@ import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
import com.intellectualcrafters.plot.util.AbstractTitle;
 | 
			
		||||
import com.intellectualcrafters.plot.util.CommentManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.EventUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.ExpireManager;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.intellectualcrafters.plot.util.PlotGameMode;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,9 +2,7 @@ package com.plotsquared.listener;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.PS;
 | 
			
		||||
import com.intellectualcrafters.plot.config.Settings;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotBlock;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RegionWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.util.SetQueue;
 | 
			
		||||
import com.sk89q.worldedit.Vector;
 | 
			
		||||
import com.sk89q.worldedit.Vector2D;
 | 
			
		||||
import com.sk89q.worldedit.WorldEditException;
 | 
			
		||||
@@ -16,7 +14,6 @@ import com.sk89q.worldedit.extent.Extent;
 | 
			
		||||
import com.sk89q.worldedit.extent.NullExtent;
 | 
			
		||||
import com.sk89q.worldedit.util.Location;
 | 
			
		||||
import com.sk89q.worldedit.world.biome.BaseBiome;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
 | 
			
		||||
@@ -87,7 +84,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                this.BScount++;
 | 
			
		||||
                if (this.BScount > Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES) {
 | 
			
		||||
                if (this.BScount > Settings.CHUNK_PROCESSOR.MAX_TILES) {
 | 
			
		||||
                    this.BSblocked = true;
 | 
			
		||||
                    PS.debug("&cPlotSquared detected unsafe WorldEdit: " + location.getBlockX() + "," + location.getBlockZ());
 | 
			
		||||
                }
 | 
			
		||||
@@ -209,16 +206,18 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
 | 
			
		||||
                        case 190:
 | 
			
		||||
                        case 191:
 | 
			
		||||
                        case 192:
 | 
			
		||||
                            if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) {
 | 
			
		||||
                                SetQueue.IMP.setBlock(this.world, x, y, z, id);
 | 
			
		||||
                            } else {
 | 
			
		||||
//                            if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) {
 | 
			
		||||
//                                SetQueue.IMP.setBlock(this.world, x, y, z, id);
 | 
			
		||||
//                            } else
 | 
			
		||||
                            {
 | 
			
		||||
                                super.setBlock(location, block);
 | 
			
		||||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) {
 | 
			
		||||
                                SetQueue.IMP.setBlock(this.world, x, y, z, PlotBlock.get((short) id, (byte) block.getData()));
 | 
			
		||||
                            } else {
 | 
			
		||||
//                            if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) {
 | 
			
		||||
//                                SetQueue.IMP.setBlock(this.world, x, y, z, PlotBlock.get((short) id, (byte) block.getData()));
 | 
			
		||||
//                            } else
 | 
			
		||||
                            {
 | 
			
		||||
                                super.setBlock(location, block);
 | 
			
		||||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
@@ -236,7 +235,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        this.Ecount++;
 | 
			
		||||
        if (this.Ecount > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
 | 
			
		||||
        if (this.Ecount > Settings.CHUNK_PROCESSOR.MAX_ENTITIES) {
 | 
			
		||||
            this.Eblocked = true;
 | 
			
		||||
            PS.debug("&cPlotSquared detected unsafe WorldEdit: " + location.getBlockX() + "," + location.getBlockZ());
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -46,11 +46,11 @@ public class WEManager {
 | 
			
		||||
            return regions;
 | 
			
		||||
        }
 | 
			
		||||
        for (Plot plot : area.getPlots()) {
 | 
			
		||||
            if (!plot.isBasePlot() || (Settings.DONE_RESTRICTS_BUILDING && (plot.getFlag(Flags.DONE).isPresent()))) {
 | 
			
		||||
            if (!plot.isBasePlot() || (Settings.DONE.RESTRICT_BUILDING && (plot.getFlag(Flags.DONE).isPresent()))) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (Settings.WE_ALLOW_HELPER && plot.isAdded(uuid) || !Settings.WE_ALLOW_HELPER && (plot.isOwner(uuid) || plot.getTrusted()
 | 
			
		||||
                    .contains(uuid))) {
 | 
			
		||||
            boolean allowMember = player.hasPermission("plots.worldedit.member");
 | 
			
		||||
            if (allowMember && plot.isAdded(uuid) || !allowMember && (plot.isOwner(uuid) || plot.getTrusted().contains(uuid))) {
 | 
			
		||||
                regions.addAll(plot.getRegions());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -8,25 +8,15 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RegionWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.util.MainUtil;
 | 
			
		||||
import com.intellectualcrafters.plot.util.Permissions;
 | 
			
		||||
import com.sk89q.worldedit.LocalSession;
 | 
			
		||||
import com.sk89q.worldedit.WorldEdit;
 | 
			
		||||
import com.sk89q.worldedit.command.tool.BrushTool;
 | 
			
		||||
import com.sk89q.worldedit.command.tool.Tool;
 | 
			
		||||
import com.sk89q.worldedit.entity.Player;
 | 
			
		||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
 | 
			
		||||
import com.sk89q.worldedit.extension.platform.Actor;
 | 
			
		||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
 | 
			
		||||
import com.sk89q.worldedit.extent.ChangeSetExtent;
 | 
			
		||||
import com.sk89q.worldedit.extent.MaskingExtent;
 | 
			
		||||
import com.sk89q.worldedit.extent.NullExtent;
 | 
			
		||||
import com.sk89q.worldedit.extent.reorder.MultiStageReorder;
 | 
			
		||||
import com.sk89q.worldedit.extent.world.FastModeExtent;
 | 
			
		||||
import com.sk89q.worldedit.util.Location;
 | 
			
		||||
import com.sk89q.worldedit.util.eventbus.EventHandler.Priority;
 | 
			
		||||
import com.sk89q.worldedit.util.eventbus.Subscribe;
 | 
			
		||||
import com.sk89q.worldedit.world.World;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
 | 
			
		||||
public class WESubscriber {
 | 
			
		||||
@@ -71,69 +61,7 @@ public class WESubscriber {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (Settings.CHUNK_PROCESSOR) {
 | 
			
		||||
                if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        LocalSession session = worldedit.getSessionManager().findByName(name);
 | 
			
		||||
                        boolean hasMask = session.getMask() != null;
 | 
			
		||||
                        Player objPlayer = (Player) actor;
 | 
			
		||||
                        int item = objPlayer.getItemInHand();
 | 
			
		||||
                        if (!hasMask) {
 | 
			
		||||
                            try {
 | 
			
		||||
                                Tool tool = session.getTool(item);
 | 
			
		||||
                                if (tool instanceof BrushTool) {
 | 
			
		||||
                                    hasMask = ((BrushTool) tool).getMask() != null;
 | 
			
		||||
                                }
 | 
			
		||||
                            } catch (Exception ignored) {}
 | 
			
		||||
                        }
 | 
			
		||||
                        AbstractDelegateExtent extent = (AbstractDelegateExtent) event.getExtent();
 | 
			
		||||
                        ChangeSetExtent history = null;
 | 
			
		||||
                        MultiStageReorder reorder = null;
 | 
			
		||||
                        MaskingExtent maskextent = null;
 | 
			
		||||
                        boolean fast = session.hasFastMode();
 | 
			
		||||
                        while (extent.getExtent() != null && extent.getExtent() instanceof AbstractDelegateExtent) {
 | 
			
		||||
                            AbstractDelegateExtent tmp = (AbstractDelegateExtent) extent.getExtent();
 | 
			
		||||
                            if (tmp.getExtent() != null && tmp.getExtent() instanceof AbstractDelegateExtent) {
 | 
			
		||||
                                if (tmp instanceof ChangeSetExtent) {
 | 
			
		||||
                                    history = (ChangeSetExtent) tmp;
 | 
			
		||||
                                }
 | 
			
		||||
                                if (tmp instanceof MultiStageReorder) {
 | 
			
		||||
                                    reorder = (MultiStageReorder) tmp;
 | 
			
		||||
                                }
 | 
			
		||||
                                if (hasMask && tmp instanceof MaskingExtent) {
 | 
			
		||||
                                    maskextent = (MaskingExtent) tmp;
 | 
			
		||||
                                }
 | 
			
		||||
                                extent = tmp;
 | 
			
		||||
                            } else {
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        int max = event.getMaxBlocks();
 | 
			
		||||
                        Field field = AbstractDelegateExtent.class.getDeclaredField("extent");
 | 
			
		||||
                        field.setAccessible(true);
 | 
			
		||||
                        if (history == null) {
 | 
			
		||||
                            ExtentWrapper wrapper = new ExtentWrapper(event.getExtent());
 | 
			
		||||
                            event.setExtent(wrapper);
 | 
			
		||||
                            field.set(extent, new ProcessedWEExtent(world, mask, max, new FastModeExtent(worldObj, true), wrapper));
 | 
			
		||||
                        } else if (fast) {
 | 
			
		||||
                            event.setExtent(new ExtentWrapper(extent));
 | 
			
		||||
                        } else {
 | 
			
		||||
                            ExtentWrapper wrapper;
 | 
			
		||||
                            if (maskextent != null) {
 | 
			
		||||
                                wrapper = new ExtentWrapper(maskextent);
 | 
			
		||||
                                field.set(maskextent, history);
 | 
			
		||||
                            } else {
 | 
			
		||||
                                wrapper = new ExtentWrapper(history);
 | 
			
		||||
                            }
 | 
			
		||||
                            event.setExtent(wrapper);
 | 
			
		||||
                            field.set(history, reorder);
 | 
			
		||||
                            field.set(reorder, new ProcessedWEExtent(world, mask, max, new FastModeExtent(worldObj, true), wrapper));
 | 
			
		||||
                        }
 | 
			
		||||
                        return;
 | 
			
		||||
                    } catch (IllegalAccessException | SecurityException | NoSuchFieldException | IllegalArgumentException e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            if (Settings.ENABLED_COMPONENTS.CHUNK_PROCESSOR) {
 | 
			
		||||
                if (PS.get().hasPlotArea(world)) {
 | 
			
		||||
                    event.setExtent(new ProcessedWEExtent(world, mask, event.getMaxBlocks(), event.getExtent(), event.getExtent()));
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -134,7 +134,7 @@ public class SpongeMain implements IPlotMain {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void log(String message) {
 | 
			
		||||
        message = C.format(message, C.replacements);
 | 
			
		||||
        if (!Settings.CONSOLE_COLOR) {
 | 
			
		||||
        if (!Settings.CHAT.CONSOLE_COLOR) {
 | 
			
		||||
            message = message.replaceAll('\u00a7' + "[a-z|0-9]", "");
 | 
			
		||||
        }
 | 
			
		||||
        if (this.server == null) {
 | 
			
		||||
@@ -262,7 +262,7 @@ public class SpongeMain implements IPlotMain {
 | 
			
		||||
    @Override
 | 
			
		||||
    public UUIDHandlerImplementation initUUIDHandler() {
 | 
			
		||||
        UUIDWrapper wrapper;
 | 
			
		||||
        if (Settings.OFFLINE_MODE) {
 | 
			
		||||
        if (Settings.UUID.OFFLINE) {
 | 
			
		||||
            wrapper = new SpongeLowerOfflineUUIDWrapper();
 | 
			
		||||
        } else {
 | 
			
		||||
            wrapper = new SpongeOnlineUUIDWrapper();
 | 
			
		||||
@@ -307,7 +307,7 @@ public class SpongeMain implements IPlotMain {
 | 
			
		||||
        World world = SpongeUtil.getWorld(worldName);
 | 
			
		||||
        if (world == null) {
 | 
			
		||||
            // create world
 | 
			
		||||
            ConfigurationSection worldConfig = PS.get().config.getConfigurationSection("worlds." + worldName);
 | 
			
		||||
            ConfigurationSection worldConfig = PS.get().worlds.getConfigurationSection("worlds." + worldName);
 | 
			
		||||
            String manager = worldConfig.getString("generator.plugin", "PlotSquared");
 | 
			
		||||
            String generator = worldConfig.getString("generator.init", manager);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -55,14 +55,14 @@ public class SpongeSetupUtils extends SetupUtils {
 | 
			
		||||
        final ConfigurationNode[] steps = object.step;
 | 
			
		||||
        final String world = object.world;
 | 
			
		||||
        for (final ConfigurationNode step : steps) {
 | 
			
		||||
            PS.get().config.set("worlds." + world + "." + step.getConstant(), step.getValue());
 | 
			
		||||
            PS.get().worlds.set("worlds." + world + "." + step.getConstant(), step.getValue());
 | 
			
		||||
        }
 | 
			
		||||
        if (object.type != 0) {
 | 
			
		||||
            PS.get().config.set("worlds." + world + ".generator.type", object.type);
 | 
			
		||||
            PS.get().config.set("worlds." + world + ".generator.terrain", object.terrain);
 | 
			
		||||
            PS.get().config.set("worlds." + world + ".generator.plugin", object.plotManager);
 | 
			
		||||
            PS.get().worlds.set("worlds." + world + ".generator.type", object.type);
 | 
			
		||||
            PS.get().worlds.set("worlds." + world + ".generator.terrain", object.terrain);
 | 
			
		||||
            PS.get().worlds.set("worlds." + world + ".generator.plugin", object.plotManager);
 | 
			
		||||
            if ((object.setupGenerator != null) && !object.setupGenerator.equals(object.plotManager)) {
 | 
			
		||||
                PS.get().config.set("worlds." + world + ".generator.init", object.setupGenerator);
 | 
			
		||||
                PS.get().worlds.set("worlds." + world + ".generator.init", object.setupGenerator);
 | 
			
		||||
            }
 | 
			
		||||
            final PlotGenerator<WorldGenerator> gen = (PlotGenerator<WorldGenerator>) generators.get(object.setupGenerator);
 | 
			
		||||
            if ((gen != null) && (gen.generator instanceof SpongePlotGenerator)) {
 | 
			
		||||
@@ -70,7 +70,7 @@ public class SpongeSetupUtils extends SetupUtils {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            PS.get().config.save(PS.get().configFile);
 | 
			
		||||
            PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
        } catch (final IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -95,7 +95,7 @@ public class MainListener {
 | 
			
		||||
                if (source == null) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (Settings.USE_PLOTME_ALIAS) {
 | 
			
		||||
                if (Settings.PLOTME.ALIAS) {
 | 
			
		||||
                    SpongeMain.THIS.getGame().getCommandManager().process(source, ("plots " + event.getArguments()).trim());
 | 
			
		||||
                } else {
 | 
			
		||||
                    source.sendMessage(SpongeUtil.getText(C.NOT_USING_PLOTME.s()));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package com.plotsquared.sponge.util;
 | 
			
		||||
 | 
			
		||||
import com.intellectualcrafters.plot.generator.HybridUtils;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
 | 
			
		||||
import com.intellectualcrafters.plot.object.PlotBlock;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RegionWrapper;
 | 
			
		||||
import com.intellectualcrafters.plot.object.RunnableVal;
 | 
			
		||||
 
 | 
			
		||||
@@ -69,10 +69,10 @@ public class SpongeSetupUtils extends SetupUtils {
 | 
			
		||||
        String world = object.world;
 | 
			
		||||
        int type = object.type;
 | 
			
		||||
        String worldPath = "worlds." + object.world;
 | 
			
		||||
        if (!PS.get().config.contains(worldPath)) {
 | 
			
		||||
            PS.get().config.createSection(worldPath);
 | 
			
		||||
        if (!PS.get().worlds.contains(worldPath)) {
 | 
			
		||||
            PS.get().worlds.createSection(worldPath);
 | 
			
		||||
        }
 | 
			
		||||
        ConfigurationSection worldSection = PS.get().config.getConfigurationSection(worldPath);
 | 
			
		||||
        ConfigurationSection worldSection = PS.get().worlds.getConfigurationSection(worldPath);
 | 
			
		||||
        switch (type) {
 | 
			
		||||
            case 2: {
 | 
			
		||||
                if (object.id != null) {
 | 
			
		||||
@@ -115,11 +115,11 @@ public class SpongeSetupUtils extends SetupUtils {
 | 
			
		||||
                for (ConfigurationNode step : steps) {
 | 
			
		||||
                    worldSection.set(step.getConstant(), step.getValue());
 | 
			
		||||
                }
 | 
			
		||||
                PS.get().config.set("worlds." + world + ".generator.type", object.type);
 | 
			
		||||
                PS.get().config.set("worlds." + world + ".generator.terrain", object.terrain);
 | 
			
		||||
                PS.get().config.set("worlds." + world + ".generator.plugin", object.plotManager);
 | 
			
		||||
                PS.get().worlds.set("worlds." + world + ".generator.type", object.type);
 | 
			
		||||
                PS.get().worlds.set("worlds." + world + ".generator.terrain", object.terrain);
 | 
			
		||||
                PS.get().worlds.set("worlds." + world + ".generator.plugin", object.plotManager);
 | 
			
		||||
                if (object.setupGenerator != null && !object.setupGenerator.equals(object.plotManager)) {
 | 
			
		||||
                    PS.get().config.set("worlds." + world + ".generator.init", object.setupGenerator);
 | 
			
		||||
                    PS.get().worlds.set("worlds." + world + ".generator.init", object.setupGenerator);
 | 
			
		||||
                }
 | 
			
		||||
                GeneratorWrapper<?> gen = SetupUtils.generators.get(object.setupGenerator);
 | 
			
		||||
                if (gen != null && gen.isFull()) {
 | 
			
		||||
@@ -133,7 +133,7 @@ public class SpongeSetupUtils extends SetupUtils {
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            PS.get().config.save(PS.get().configFile);
 | 
			
		||||
            PS.get().worlds.save(PS.get().worldsFile);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ ext {
 | 
			
		||||
    git = Grgit.open(file(".git"))
 | 
			
		||||
    revision = "-${git.head().abbreviatedId}"
 | 
			
		||||
}
 | 
			
		||||
version = "3.4.0${revision}"
 | 
			
		||||
version = "3.4.1${revision}"
 | 
			
		||||
description = """PlotSquared"""
 | 
			
		||||
 | 
			
		||||
subprojects {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user