diff --git a/PlotSquared/pom.xml b/PlotSquared/pom.xml index e120c309b..08b1385c8 100644 --- a/PlotSquared/pom.xml +++ b/PlotSquared/pom.xml @@ -8,7 +8,7 @@ UTF-8 PlotSquared - 2.7.0 + 2.7.1 PlotSquared jar diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java index ee28f480b..c7c381a67 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java @@ -21,6 +21,9 @@ package com.intellectualcrafters.plot.commands; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; @@ -43,6 +46,7 @@ import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.ExpireManager; import com.intellectualcrafters.plot.util.PlayerFunctions; import com.intellectualcrafters.plot.util.UUIDHandler; +import com.sk89q.worldedit.regions.Region; public class DebugExec extends SubCommand { @@ -55,7 +59,7 @@ public class DebugExec extends SubCommand { @Override public boolean execute(final Player player, final String... args) { - List allowed_params = Arrays.asList(new String[]{"stop-expire","start-expire", "show-expired", "update-expired", "seen", "trim-check-chunks", "trim-get-chunks"}); + List allowed_params = Arrays.asList(new String[]{"stop-expire","start-expire", "show-expired", "update-expired", "seen", "trim-check"}); if (args.length > 0) { String arg = args[0].toLowerCase(); switch (arg) { @@ -127,52 +131,48 @@ public class DebugExec extends SubCommand { PlayerFunctions.sendMessage(null, "Local: " + date.toLocaleString()); return true; } - case "trim-get-chunks": { + case "trim-check": { if (args.length != 2) { - PlayerFunctions.sendMessage(null, "Use /plot debugexec trim-get-chunks "); + PlayerFunctions.sendMessage(null, "Use /plot debugexec trim-check "); PlayerFunctions.sendMessage(null, "&7 - Generates a list of regions to trim"); return PlayerFunctions.sendMessage(null, "&7 - Run after plot expiry has run"); } - World world = Bukkit.getWorld(args[1]); + final World world = Bukkit.getWorld(args[1]); if (world == null || !PlotMain.isPlotWorld(args[1])) { return PlayerFunctions.sendMessage(null, "Invalid world: "+args[1]); } - ArrayList chunks0 = Trim.getTrimChunks(world); - PlayerFunctions.sendMessage(null, "BULK MCR: " + chunks0.size()); - ArrayList chunks = Trim.getTrimPlots(world); - chunks.addAll(chunks0); - this.chunks = chunks; - this.world = world; - PlayerFunctions.sendMessage(null, "MCR: " + chunks.size()); - PlayerFunctions.sendMessage(null, "CHUNKS: " + chunks.size() * 256); - PlayerFunctions.sendMessage(null, "Calculating size on disk..."); - PlayerFunctions.sendMessage(null, "SIZE (bytes): " + Trim.calculateSizeOnDisk(world, chunks)); - return true; - } - case "trim-check-chunks": { - if (this.chunks == null) { - return PlayerFunctions.sendMessage(null, "Please run the 'trim-get-chunks' command first"); + final ArrayList empty = new ArrayList<>(); + boolean result = Trim.getTrimRegions(empty, world, new Runnable() { + @Override + public void run() { + Trim.sendMessage("Processing is complete! Here's how many chunks would be deleted:"); + Trim.sendMessage(" - MCA #: " + empty.size()); + Trim.sendMessage(" - CHUNKS: " + (empty.size() * 1024) + " (max)"); + Trim.sendMessage("Exporting log for manual approval..."); + final File file = new File(PlotMain.getMain().getDataFolder() + File.separator + "trim.txt"); + PrintWriter writer; + try { + writer = new PrintWriter(file); + String worldname = world.getName(); + for (ChunkLoc loc : empty) { + writer.println(worldname +"/region/r." + loc.x + "." + loc.z +".mca" ); + } + writer.close(); + Trim.sendMessage("File saved to 'plugins/PlotSquared/trim.txt'"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + Trim.sendMessage("File failed to save! :("); + } + Trim.sendMessage("How to get the chunk coords from a region file:"); + Trim.sendMessage(" - Locate the x,z values for the region file (the two numbers which are separated by a dot)"); + Trim.sendMessage(" - Multiply each number by 32; this gives you the starting position"); + Trim.sendMessage(" - Add 31 to each number to get the end position"); + } + }); + if (!result) { + PlayerFunctions.sendMessage(null, "Trim task already started!"); } - - PlayerFunctions.sendMessage(null, "Checking MCR files for existing plots:"); - int count = 0; - for (ChunkLoc loc : chunks) { - int sx = loc.x << 4; - int sz = loc.z << 4; - loop: - for (int x = sx; x < sx + 16; x++) { - for (int z = sz; z < sz + 16; z++) { - Chunk chunk = world.getChunkAt(x, z); - Plot plot = ChunkManager.hasPlot(world, chunk); - if (plot != null) { - PlayerFunctions.sendMessage(null, " - " + plot); - count++; - break loop; - } - } - } - } - PlayerFunctions.sendMessage(null, "Found " + count + "plots."); + return result; } } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/FlagCmd.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/FlagCmd.java index 4c60884f6..65780803f 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/FlagCmd.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/FlagCmd.java @@ -100,7 +100,7 @@ public class FlagCmd extends SubCommand { PlayerFunctions.sendMessage(player, C.NO_PERMISSION, "plots.set.flag"); return false; } - if (args.length != 3) { + if (args.length < 3) { PlayerFunctions.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag set "); return false; } @@ -173,7 +173,7 @@ public class FlagCmd extends SubCommand { PlayerFunctions.sendMessage(player, C.NO_PERMISSION, "plots.flag.add"); return false; } - if (args.length != 3) { + if (args.length < 3) { PlayerFunctions.sendMessage(player, C.COMMAND_SYNTAX, "/plot flag add "); return false; } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/RegenAllRoads.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/RegenAllRoads.java index d751e9f56..48d7d7d3f 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/RegenAllRoads.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/RegenAllRoads.java @@ -67,7 +67,7 @@ public class RegenAllRoads extends SubCommand { PlotMain.sendConsoleSenderMessage("&cIf no schematic is set, the following will not do anything"); PlotMain.sendConsoleSenderMessage("&7 - To set a schematic, stand in a plot and use &c/plot createroadschematic"); - PlotMain.sendConsoleSenderMessage("&6Potential chunks to update: &7"+ (chunks.size() * 256)); + PlotMain.sendConsoleSenderMessage("&6Potential chunks to update: &7"+ (chunks.size() * 1024)); PlotMain.sendConsoleSenderMessage("&6Estimated time: &7"+ (chunks.size()) + " seconds"); boolean result = hpm.scheduleRoadUpdate(world); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Trim.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Trim.java index dff5a158d..2968a7273 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Trim.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Trim.java @@ -29,10 +29,12 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Chunk; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; @@ -46,6 +48,7 @@ import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.ExpireManager; import com.intellectualcrafters.plot.util.PlayerFunctions; +import com.intellectualcrafters.plot.util.PlotHelper; import com.intellectualcrafters.plot.util.TaskManager; public class Trim extends SubCommand { @@ -101,37 +104,49 @@ public class Trim extends SubCommand { PlayerFunctions.sendMessage(plr, C.NOT_VALID_WORLD); return false; } - if (runTrimTask(world)) { - sendMessage(C.TRIM_START.s()); - return true; + + if (Trim.TASK) { + sendMessage(C.TRIM_IN_PROGRESS.s()); + return false; } - sendMessage(C.TRIM_IN_PROGRESS.s()); - return false; + + sendMessage(C.TRIM_START.s()); + final ArrayList empty = new ArrayList<>(); + getTrimRegions(empty, world, new Runnable() { + @Override + public void run() { + deleteChunks(world, empty); + } + }); + return true; } - public boolean runTrimTask(final World world) { + public static boolean getBulkRegions(final ArrayList empty, final World world, final Runnable whenDone) { if (Trim.TASK) { return false; } - Trim.TASK = true; TaskManager.runTask(new Runnable() { @Override public void run() { - final HybridPlotManager manager = (HybridPlotManager) PlotMain.getPlotManager(world); - final HybridPlotWorld plotworld = (HybridPlotWorld) PlotMain.getWorldSettings(world); - final String worldname = world.getName(); String directory = world.getName() + File.separator + "region"; File folder = new File(directory); File[] regionFiles = folder.listFiles(); - ArrayList chunkChunks = new ArrayList<>(); for (File file : regionFiles) { String name = file.getName(); if (name.endsWith("mca")) { if (file.getTotalSpace() <= 8192) { - file.delete(); + try { + String[] split = name.split("\\."); + int x = Integer.parseInt(split[1]); + int z = Integer.parseInt(split[2]); + ChunkLoc loc = new ChunkLoc(x, z); + empty.add(loc); + } + catch (Exception e) { + System.out.print("INVALID MCA: " + name); + } } else { - boolean delete = false; Path path = Paths.get(file.getPath()); try { BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class); @@ -139,51 +154,72 @@ public class Trim extends SubCommand { long modification = file.lastModified(); long diff = Math.abs(creation - modification); if (diff < 10000) { - PlotMain.sendConsoleSenderMessage("&6 - Deleted region "+name+" (max 256 chunks)"); - file.delete(); - delete = true; + try { + String[] split = name.split("\\."); + int x = Integer.parseInt(split[1]); + int z = Integer.parseInt(split[2]); + ChunkLoc loc = new ChunkLoc(x, z); + empty.add(loc); + } + catch (Exception e) { + System.out.print("INVALID MCA: " + name); + } } } catch (Exception e) { } - if (!delete) { - String[] split = name.split("\\."); - try { - int x = Integer.parseInt(split[1]); - int z = Integer.parseInt(split[2]); - ChunkLoc loc = new ChunkLoc(x, z); - chunkChunks.add(loc); - } - catch (Exception e) { } - } } } } - final Set plots = ExpireManager.getOldPlots(world.getName()).keySet(); - Trim.TASK_ID = Bukkit.getScheduler().scheduleSyncRepeatingTask(PlotMain.getMain(), new Runnable() { - @Override - public void run() { - if (manager != null && plots.size() > 0) { - Plot plot = plots.iterator().next(); - if (plot.hasOwner()) { - HybridPlotManager.checkModified(plot, 0); - } - if (plot.owner == null || !HybridPlotManager.checkModified(plot, plotworld.REQUIRED_CHANGES)) { - PlotMain.removePlot(worldname, plot.id, true); - } - plots.remove(0); - } - else { - trimPlots(world); - Trim.TASK = false; - sendMessage("Done!"); - Bukkit.getScheduler().cancelTask(Trim.TASK_ID); - return; - } - } - }, 1, 1); + Trim.TASK = false; + TaskManager.runTask(whenDone); } }); + Trim.TASK = true; + return true; + } + + public static boolean getTrimRegions(final ArrayList empty, final World world, final Runnable whenDone) { + if (Trim.TASK) { + return false; + } + final long startOld = System.currentTimeMillis(); + sendMessage("Collecting region data..."); + final ArrayList plots = new ArrayList<>(); + plots.addAll(PlotMain.getPlots(world).values()); + final HashSet chunks = new HashSet<>(ChunkManager.getChunkChunks(world)); + sendMessage(" - MCA #: " + chunks.size()); + sendMessage(" - CHUNKS: " + (chunks.size() * 1024) +" (max)"); + sendMessage(" - TIME ESTIMATE: " + (chunks.size()/1200) +" minutes"); + Trim.TASK_ID = Bukkit.getScheduler().scheduleSyncRepeatingTask(PlotMain.getMain(), new Runnable() { + @Override + public void run() { + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < 50) { + if (plots.size() == 0) { + empty.addAll(chunks); + System.out.print("DONE!"); + Trim.TASK = false; + TaskManager.runTask(whenDone); + Bukkit.getScheduler().cancelTask(Trim.TASK_ID); + return; + } + Plot plot = plots.get(0); + plots.remove(0); + Location pos1 = PlotHelper.getPlotBottomLoc(world, plot.id); + Location pos2 = PlotHelper.getPlotTopLoc(world, plot.id); + + Location pos3 = new Location(world, pos1.getBlockX(), 64, pos2.getBlockZ()); + Location pos4 = new Location(world, pos2.getBlockX(), 64, pos1.getBlockZ()); + + chunks.remove(ChunkManager.getChunkChunk(pos1)); + chunks.remove(ChunkManager.getChunkChunk(pos2)); + chunks.remove(ChunkManager.getChunkChunk(pos3)); + chunks.remove(ChunkManager.getChunkChunk(pos4)); + } + } + }, 20L, 20L); + Trim.TASK = true; return true; } @@ -219,99 +255,7 @@ public class Trim extends SubCommand { }, 1, 1); } - public static long calculateSizeOnDisk(World world, ArrayList chunks) { - int result = 0; - for (ChunkLoc loc : chunks) { - String directory = world.getName() + File.separator + "region" + File.separator + "r." + loc.x + "." + loc.z + ".mca"; - File file = new File(directory); - try { - result += file.length(); - } - catch (Exception e) { - e.printStackTrace(); - } - } - return result; - } - - public static ArrayList getTrimChunks(World world) { - ArrayList toRemove = new ArrayList<>(); - String directory = world.getName() + File.separator + "region"; - File folder = new File(directory); - File[] regionFiles = folder.listFiles(); - for (File file : regionFiles) { - String name = file.getName(); - if (name.endsWith("mca")) { - if (file.getTotalSpace() <= 8192) { - try { - String[] split = name.split("\\."); - int x = Integer.parseInt(split[1]); - int z = Integer.parseInt(split[2]); - ChunkLoc loc = new ChunkLoc(x, z); - toRemove.add(loc); - } - catch (Exception e) { - System.out.print(name); - } - continue; - } - else { - Path path = Paths.get(file.getPath()); - try { - BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class); - long creation = attr.creationTime().toMillis(); - long modification = file.lastModified(); - long diff = Math.abs(creation - modification); - if (diff < 10000) { - PlotMain.sendConsoleSenderMessage("&6 - Deleted region "+name+" (max 256 chunks)"); - try { - String[] split = name.split("\\."); - int x = Integer.parseInt(split[1]); - int z = Integer.parseInt(split[2]); - ChunkLoc loc = new ChunkLoc(x, z); - toRemove.add(loc); - } - catch (Exception e) { - System.out.print(name); - } - } - } catch (Exception e) { - - } - } - } - } - return toRemove; - } - - public static ArrayList getTrimPlots(World world) { - ArrayList toRemove = new ArrayList<>(); - ArrayList chunks = ChunkManager.getChunkChunks(world); - for (ChunkLoc loc : chunks) { - int sx = loc.x << 4; - int sz = loc.z << 4; - - boolean delete = true; - - loop: - for (int x = sx; x < sx + 16; x++) { - for (int z = sz; z < sz + 16; z++) { - Chunk chunk = world.getChunkAt(x, z); - if (ChunkManager.hasPlot(world, chunk) != null) { - delete = false; - break loop; - } - } - } - if (delete) { - toRemove.add(loc); - } - } - return toRemove; - } - - public static void trimPlots(World world) { - ArrayList chunks = getTrimPlots(world); + public static void deleteChunks(World world, ArrayList chunks) { String worldname = world.getName(); for (ChunkLoc loc : chunks) { ChunkManager.deleteRegionFile(worldname, loc); @@ -319,7 +263,7 @@ public class Trim extends SubCommand { } public static void sendMessage(final String message) { - PlotMain.sendConsoleSenderMessage("&3PlotSquared -> World trim&8: " + message); + PlotMain.sendConsoleSenderMessage("&3PlotSquared -> World trim&8: &7" + message); } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/PlotMeConverter.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/PlotMeConverter.java index 2b238840c..74034f0e4 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/PlotMeConverter.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/PlotMeConverter.java @@ -42,6 +42,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import com.intellectualcrafters.plot.PlotMain; import com.intellectualcrafters.plot.generator.HybridGen; +import com.intellectualcrafters.plot.generator.HybridPlotWorld; import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.util.UUIDHandler; @@ -112,7 +113,9 @@ public class PlotMeConverter { count++; final PlotId id = new PlotId(r.getInt("idX"), r.getInt("idZ")); final String name = r.getString("owner"); - final String world = r.getString("world"); + final String world = getWorld(r.getString("world")); + + if (!plotSize.containsKey(world)) { final int size = r.getInt("topZ") - r.getInt("bottomZ"); plotSize.put(world, size); @@ -136,7 +139,7 @@ public class PlotMeConverter { while (r.next()) { final PlotId id = new PlotId(r.getInt("idX"), r.getInt("idZ")); final String name = r.getString("player"); - final String world = r.getString("world"); + final String world = getWorld(r.getString("world")); UUID helper = UUIDHandler.getUUID(name); if (helper == null) { if (name.equals("*")) { @@ -155,7 +158,7 @@ public class PlotMeConverter { while (r.next()) { final PlotId id = new PlotId(r.getInt("idX"), r.getInt("idZ")); final String name = r.getString("player"); - final String world = r.getString("world"); + final String world = getWorld(r.getString("world")); UUID denied = UUIDHandler.getUUID(name); if (denied == null) { if (name.equals("*")) { @@ -175,25 +178,29 @@ public class PlotMeConverter { for (final String world : plots.keySet()) { sendMessage("Copying config for: " + world); try { - final Integer pathwidth = plotConfig.getInt("worlds." + world + ".PathWidth"); // + String plotMeWorldName = world.toLowerCase(); + final Integer pathwidth = plotConfig.getInt("worlds." + plotMeWorldName + ".PathWidth"); // PlotMain.config.set("worlds." + world + ".road.width", pathwidth); - final Integer plotsize = plotConfig.getInt("worlds." + world + ".PlotSize"); // + final Integer plotsize = plotConfig.getInt("worlds." + plotMeWorldName + ".PlotSize"); // PlotMain.config.set("worlds." + world + ".plot.size", plotsize); - final String wallblock = plotConfig.getString("worlds." + world + ".WallBlockId"); // + final String wallblock = plotConfig.getString("worlds." + plotMeWorldName + ".WallBlockId"); // PlotMain.config.set("worlds." + world + ".wall.block", wallblock); - final String floor = plotConfig.getString("worlds." + world + ".PlotFloorBlockId"); // + final String floor = plotConfig.getString("worlds." + plotMeWorldName + ".PlotFloorBlockId"); // PlotMain.config.set("worlds." + world + ".plot.floor", Arrays.asList(floor)); - final String filling = plotConfig.getString("worlds." + world + ".PlotFillingBlockId"); // + final String filling = plotConfig.getString("worlds." + plotMeWorldName + ".PlotFillingBlockId"); // PlotMain.config.set("worlds." + world + ".plot.filling", Arrays.asList(filling)); - final String road = plotConfig.getString("worlds." + world + ".RoadMainBlockId"); + final String road = plotConfig.getString("worlds." + plotMeWorldName + ".RoadMainBlockId"); PlotMain.config.set("worlds." + world + ".road.block", road); - final Integer height = plotConfig.getInt("worlds." + world + ".RoadHeight"); // + Integer height = plotConfig.getInt("worlds." + plotMeWorldName + ".RoadHeight"); // + if (height == null) { + height = 64; + } PlotMain.config.set("worlds." + world + ".road.height", height); } catch (final Exception e) { sendMessage("&c-- &lFailed to save configuration for world '" + world + "'\nThis will need to be done using the setup command, or manually"); @@ -205,26 +212,53 @@ public class PlotMeConverter { final YamlConfiguration PLOTME_DG_YML = YamlConfiguration.loadConfiguration(PLOTME_DG_FILE); try { for (final String world : plots.keySet()) { - final Integer pathwidth = PLOTME_DG_YML.getInt("worlds." + world + ".PathWidth"); // + String plotMeWorldName = world.toLowerCase(); + Integer pathwidth = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".PathWidth"); // + if (pathwidth == null) { + pathwidth = 7; + } PlotMain.config.set("worlds." + world + ".road.width", pathwidth); - final Integer plotsize = PLOTME_DG_YML.getInt("worlds." + world + ".PlotSize"); // + Integer plotsize = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".PlotSize"); // + if (plotsize == null) { + plotsize = 32; + } PlotMain.config.set("worlds." + world + ".plot.size", plotsize); - final String wallblock = PLOTME_DG_YML.getString("worlds." + world + ".WallBlock"); // + String wallblock = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".WallBlock"); // + if (wallblock == null) { + wallblock = "44"; + } PlotMain.config.set("worlds." + world + ".wall.block", wallblock); - final String floor = PLOTME_DG_YML.getString("worlds." + world + ".PlotFloorBlock"); // + String floor = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".PlotFloorBlock"); // + if (floor == null) { + floor = "2"; + } PlotMain.config.set("worlds." + world + ".plot.floor", Arrays.asList(floor)); - final String filling = PLOTME_DG_YML.getString("worlds." + world + ".FillBlock"); // + String filling = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".FillBlock"); // + if (filling == null) { + filling = "3"; + } PlotMain.config.set("worlds." + world + ".plot.filling", Arrays.asList(filling)); - final String road = PLOTME_DG_YML.getString("worlds." + world + ".RoadMainBlock"); + String road = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".RoadMainBlock"); + if (road == null) { + road = "5"; + } PlotMain.config.set("worlds." + world + ".road.block", road); - final Integer height = PLOTME_DG_YML.getInt("worlds." + world + ".RoadHeight"); // + Integer height = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".RoadHeight"); // + if (height == null || height == 0) { + height = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".GroundHeight"); // + if (height == null || height == 0) { + height = 64; + } + } PlotMain.config.set("worlds." + world + ".road.height", height); + PlotMain.config.set("worlds." + world + ".plot.height", height); + PlotMain.config.set("worlds." + world + ".wall.height", height); } } catch (final Exception e) { @@ -270,34 +304,35 @@ public class PlotMeConverter { } for (final String worldname : worlds) { - final World world = Bukkit.getWorld(worldname); - sendMessage("Reloading generator for world: '" + worldname + "'..."); + final World world = Bukkit.getWorld(getWorld(worldname)); + final String actualWorldName = world.getName(); + sendMessage("Reloading generator for world: '" + actualWorldName + "'..."); - PlotMain.removePlotWorld(worldname); + PlotMain.removePlotWorld(actualWorldName); if (MV) { // unload - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv unload " + worldname); + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv unload " + actualWorldName); try { Thread.sleep(1000); } catch (final InterruptedException ex) { Thread.currentThread().interrupt(); } // load - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv import " + worldname + " normal -g PlotSquared"); + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv import " + actualWorldName + " normal -g PlotSquared"); } else if (MW) { // unload - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw unload " + worldname); + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw unload " + actualWorldName); try { Thread.sleep(1000); } catch (final InterruptedException ex) { Thread.currentThread().interrupt(); } // load - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + worldname + " plugin:PlotSquared"); + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + actualWorldName + " plugin:PlotSquared"); } else { Bukkit.getServer().unloadWorld(world, true); - final World myworld = WorldCreator.name(worldname).generator(new HybridGen(worldname)).createWorld(); + final World myworld = WorldCreator.name(actualWorldName).generator(new HybridGen(actualWorldName)).createWorld(); myworld.save(); } } @@ -316,6 +351,16 @@ public class PlotMeConverter { } }, 20); } + + public String getWorld(String world) { + for (World newworld : Bukkit.getWorlds()) { + if (newworld.getName().equalsIgnoreCase(world)) { + return newworld.getName(); + } + } + return world; + } + private UUID uuidFromBytes(byte[] byteArray) { ByteBuffer wrapped = ByteBuffer.wrap(byteArray); long minor = wrapped.getLong(); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java index 286833ed4..7c54c5bc5 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java @@ -68,7 +68,7 @@ import com.intellectualcrafters.plot.object.PlotWorld; if (PlotMain.getAllPlotsRaw() != null) { for (Plot plot : PlotMain.getPlots()) { for (Flag flag : plot.settings.flags) { - if (flag.getAbstractFlag().getKey().equals(af)) { + if (flag.getAbstractFlag().getKey().equals(af.getKey())) { flag.setKey(af); } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/AugmentedPopulator.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/AugmentedPopulator.java index d4f55cb3a..affa49569 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/AugmentedPopulator.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/AugmentedPopulator.java @@ -17,6 +17,8 @@ import com.intellectualcrafters.plot.object.PlotGenerator; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotManager; import com.intellectualcrafters.plot.object.PlotWorld; +import com.intellectualcrafters.plot.object.RegionWrapper; +import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.PlotHelper; import com.intellectualcrafters.plot.util.TaskManager; @@ -174,8 +176,15 @@ public class AugmentedPopulator extends BlockPopulator { } int xx = x + blockInfo.x; int zz = z + blockInfo.z; - if (p && manager.getPlotIdAbs(plotworld, new Location(world, xx, 0, zz)) != null) { - continue; + if (p) { + if (ChunkManager.CURRENT_PLOT_CLEAR != null) { + if (ChunkManager.isIn(ChunkManager.CURRENT_PLOT_CLEAR, xx, zz)) { + continue; + } + } + else if (manager.getPlotIdAbs(plotworld, new Location(world, xx, 0, zz)) != null) { + continue; + } } PlotHelper.setBlock(world, xx, blockInfo.y, zz, blockInfo.id, (byte) 0); } @@ -184,4 +193,8 @@ public class AugmentedPopulator extends BlockPopulator { populator.populate(world, r,world.getChunkAt(X, Z)); } } + + public boolean isIn(RegionWrapper plot, int x, int z) { + return (x >= plot.minX && x <= plot.maxX && z >= plot.minZ && z <= plot.maxZ); + } } \ No newline at end of file diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/HybridPlotManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/HybridPlotManager.java index 004ffebdf..af83e3d45 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/HybridPlotManager.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/HybridPlotManager.java @@ -180,13 +180,13 @@ import com.intellectualcrafters.plot.util.SendChunk; public void regenerateChunkChunk(World world, ChunkLoc loc) { - int sx = loc.x << 4; - int sz = loc.z << 4; + int sx = loc.x << 5; + int sz = loc.z << 5; HashSet chunks = new HashSet(); - for (int x = sx; x < sx + 16; x++) { - for (int z = sz; z < sz + 16; z++) { + for (int x = sx; x < sx + 32; x++) { + for (int z = sz; z < sz + 32; z++) { Chunk chunk = world.getChunkAt(x, z); chunk.load(false); chunks.add(chunk); @@ -263,7 +263,7 @@ import com.intellectualcrafters.plot.util.SendChunk; } for (Chunk chunk : world.getLoadedChunks()) { - ChunkLoc loc = new ChunkLoc(chunk.getX() >> 4, chunk.getZ() >> 4); + ChunkLoc loc = new ChunkLoc(chunk.getX() >> 5, chunk.getZ() >> 5); if (!chunks.contains(loc)) { chunks.add(loc); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotPlusListener.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotPlusListener.java index 5d60164a8..e37288c65 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotPlusListener.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotPlusListener.java @@ -173,7 +173,7 @@ import java.util.*; public void onPlotEnter(final PlayerEnterPlotEvent event) { final Plot plot = event.getPlot(); if (FlagManager.getPlotFlag(plot, "greeting") != null) { - event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_GREETING.s() + FlagManager.getPlotFlag(plot, "greeting").getValueString())); + event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_GREETING.s().replaceAll("%id%", plot.id + "") + FlagManager.getPlotFlag(plot, "greeting").getValueString())); } if (booleanFlag(plot, "notify-enter", false)) { if (plot.hasOwner()) { @@ -210,7 +210,7 @@ import java.util.*; event.getPlayer().playEffect(event.getPlayer().getLocation(), Effect.RECORD_PLAY, 0); final Plot plot = event.getPlot(); if (FlagManager.getPlotFlag(plot, "farewell") != null) { - event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_FAREWELL.s() + FlagManager.getPlotFlag(plot, "farewell").getValueString())); + event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_FAREWELL.s().replaceAll("%id%", plot.id + "") + FlagManager.getPlotFlag(plot, "farewell").getValueString())); } if (feedRunnable.containsKey(event.getPlayer().getName())) { feedRunnable.remove(event.getPlayer().getName()); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityWrapper.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityWrapper.java index 15f2e8164..3773616bd 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityWrapper.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityWrapper.java @@ -72,6 +72,9 @@ public class EntityWrapper { entity.setCustomName(this.lived.name); entity.setCustomNameVisible(this.lived.visible); } + if (this.lived.potions != null && this.lived.potions.size() > 0) { + entity.addPotionEffects(this.lived.potions); + } entity.setRemainingAir(this.lived.air); entity.setRemoveWhenFarAway(this.lived.persistent); @@ -98,6 +101,7 @@ public class EntityWrapper { public void storeLiving(final LivingEntity lived) { this.lived = new LivingEntityStats(); + this.lived.potions = lived.getActivePotionEffects(); this.lived.loot = lived.getCanPickupItems(); this.lived.name = lived.getCustomName(); this.lived.visible = lived.isCustomNameVisible(); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/LivingEntityStats.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/LivingEntityStats.java index dcfd400fe..e482a63b8 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/LivingEntityStats.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/LivingEntityStats.java @@ -1,6 +1,9 @@ package com.intellectualcrafters.plot.object.entity; +import java.util.Collection; + import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; public class LivingEntityStats { @@ -22,5 +25,6 @@ public class LivingEntityStats { public ItemStack boots; public ItemStack leggings; public ItemStack chestplate; + public Collection potions; } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java index d8454ac48..7c572f8da 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java @@ -8,10 +8,13 @@ import java.util.HashSet; import org.apache.commons.lang.mutable.MutableInt; import org.bukkit.Bukkit; import org.bukkit.Chunk; +import org.bukkit.DyeColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Note; +import org.bukkit.SkullType; import org.bukkit.World; +import org.bukkit.block.Banner; import org.bukkit.block.Beacon; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -28,14 +31,14 @@ import org.bukkit.block.Jukebox; import org.bukkit.block.NoteBlock; import org.bukkit.block.Sign; import org.bukkit.block.Skull; +import org.bukkit.block.banner.Pattern; +import org.bukkit.block.banner.PatternType; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import com.intellectualcrafters.plot.PlotMain; -import com.intellectualcrafters.plot.config.C; -import com.intellectualcrafters.plot.generator.HybridPlotManager; import com.intellectualcrafters.plot.object.BlockLoc; import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.Plot; @@ -50,6 +53,12 @@ public class ChunkManager { public static MutableInt index = new MutableInt(0); public static HashMap tasks = new HashMap<>(); + public static ChunkLoc getChunkChunk(Location loc) { + int x = loc.getBlockX() >> 9; + int z = loc.getBlockZ() >> 9; + return new ChunkLoc(x, z); + } + public static ArrayList getChunkChunks(World world) { File[] regionFiles = new File(world.getName() + File.separator + "region").listFiles(); ArrayList chunks = new ArrayList<>(); @@ -71,7 +80,7 @@ public class ChunkManager { public void run() { String directory = world + File.separator + "region" + File.separator + "r." + loc.x + "." + loc.z + ".mca"; File file = new File(directory); - PlotMain.sendConsoleSenderMessage("&6 - Deleted region "+file.getName()+" (max 256 chunks)"); + PlotMain.sendConsoleSenderMessage("&6 - Deleting file: " + file.getName() + " (max 1024 chunks)"); if (file.exists()) { file.delete(); } @@ -114,6 +123,8 @@ public class ChunkManager { private static HashMap cmdData; private static HashMap signContents; private static HashMap noteBlockContents; + private static HashMap> bannerColors; + private static HashMap bannerBase; private static HashSet entities; @@ -231,6 +242,8 @@ public class ChunkManager { noteBlockContents = new HashMap<>(); signContents = new HashMap<>(); cmdData = new HashMap<>(); + bannerBase= new HashMap<>(); + bannerColors = new HashMap<>(); entities = new HashSet<>(); } @@ -261,6 +274,7 @@ public class ChunkManager { entity.spawn(world, x_offset, z_offset); } catch (Exception e) { + System.out.print("Failed to restore entity " + entity.x + "," + entity.y + "," + entity.z + " : " + entity.id); e.printStackTrace(); } } @@ -338,7 +352,10 @@ public class ChunkManager { ((Skull) (state)).setOwner((String) data[0]); } if (((Integer) data[1]) != 0) { - ((Skull) (state)).setRotation(getRotation((Integer) data[1])); + ((Skull) (state)).setRotation(BlockFace.values()[(int) data[1]]); + } + if (((Integer) data[2]) != 0) { + ((Skull) (state)).setSkullType(SkullType.values()[(int) data[2]]); } state.update(true); } @@ -418,6 +435,22 @@ public class ChunkManager { } else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate furnace: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); } } + + for (BlockLoc loc: bannerBase.keySet()) { + Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset); + BlockState state = block.getState(); + if (state instanceof Banner) { + Banner banner = (Banner) state; + byte base = bannerBase.get(loc); + ArrayList colors = bannerColors.get(loc); + banner.setBaseColor(DyeColor.values()[base]); + for (Byte[] color : colors) { + banner.addPattern(new Pattern(DyeColor.getByDyeData(color[1]), PatternType.values()[color[0]])); + } + state.update(true); + } + else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate banner: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); } + } } public static void saveBlock(World world, int maxY, int x, int z) { @@ -436,8 +469,8 @@ public class ChunkManager { switch (id) { case 54: bl = new BlockLoc(x, y, z); - Chest chest = (Chest) block.getState(); - ItemStack[] inventory = chest.getBlockInventory().getContents().clone(); + InventoryHolder chest = (InventoryHolder) block.getState(); + ItemStack[] inventory = chest.getInventory().getContents().clone(); chestContents.put(bl, inventory); break; case 52: @@ -525,8 +558,23 @@ public class ChunkManager { bl = new BlockLoc(x, y, z); Skull skull = (Skull) block.getState(); String o = skull.getOwner(); - short rot = (short) skull.getRotation().ordinal(); - skullData.put(bl, new Object[] {o, rot}); + byte skulltype = getOrdinal(SkullType.values(),skull.getSkullType()); + BlockFace te = skull.getRotation(); + short rot = (short) getOrdinal(BlockFace.values(), skull.getRotation()); + skullData.put(bl, new Object[] {o, rot, skulltype}); + break; + case 176: + case 177: + bl = new BlockLoc(x, y, z); + Banner banner = (Banner) block.getState(); + byte base = getOrdinal(DyeColor.values(), banner.getBaseColor()); + ArrayList types = new ArrayList<>(); + + for (Pattern pattern : banner.getPatterns()) { + types.add(new Byte[] {getOrdinal(PatternType.values(), pattern.getPattern()), pattern.getColor().getDyeData() }); + } + bannerBase.put(bl, base); + bannerColors.put(bl, types); break; } } @@ -536,59 +584,12 @@ public class ChunkManager { GENERATE_DATA.put(loc, datas); } - public static BlockFace getRotation(int ordinal) { - switch (ordinal) { - case 0: { - return BlockFace.NORTH; - } - case 1: { - return BlockFace.NORTH_NORTH_EAST; - } - case 2: { - return BlockFace.NORTH_EAST; - } - case 3: { - return BlockFace.EAST_NORTH_EAST; - } - case 4: { - return BlockFace.EAST; - } - case 5: { - return BlockFace.EAST_SOUTH_EAST; - } - case 6: { - return BlockFace.SOUTH_EAST; - } - case 7: { - return BlockFace.SOUTH_SOUTH_EAST; - } - case 8: { - return BlockFace.SOUTH; - } - case 9: { - return BlockFace.SOUTH_SOUTH_WEST; - } - case 10: { - return BlockFace.SOUTH_WEST; - } - case 11: { - return BlockFace.WEST_SOUTH_WEST; - } - case 12: { - return BlockFace.WEST; - } - case 13: { - return BlockFace.WEST_NORTH_WEST; - } - case 14: { - return BlockFace.NORTH_WEST; - } - case 15: { - return BlockFace.NORTH_NORTH_WEST; - } - default: { - return BlockFace.NORTH; + private static byte getOrdinal(Object[] list, Object value) { + for (byte i = 0; i < list.length; i++) { + if (list[i].equals(value)) { + return i; } } + return 0; } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SchematicHandler.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SchematicHandler.java index 168ec56b3..6760defe4 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SchematicHandler.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SchematicHandler.java @@ -192,7 +192,7 @@ public class SchematicHandler { return getSchematic(tag, file); } catch (final Exception e) { - e.printStackTrace(); + PlotMain.sendConsoleSenderMessage(file.toString() + " is not in GZIP format"); return null; } }