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..b268b389a 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 { @@ -127,53 +131,46 @@ 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, "&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)); + final ArrayList empty = new ArrayList<>(); + 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() * 256) + " (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"); + } 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"); + } + }); return true; } - case "trim-check-chunks": { - if (this.chunks == null) { - return PlayerFunctions.sendMessage(null, "Please run the 'trim-get-chunks' command first"); - } - - 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."); - } } } PlayerFunctions.sendMessage(player, "Possible sub commands: /plot debugexec <" + StringUtils.join(allowed_params, "|") + ">"); 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..e1794a161 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Trim.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Trim.java @@ -101,37 +101,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 +151,70 @@ 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; + } + sendMessage("Collecting region data..."); + final ArrayList chunks = ChunkManager.getChunkChunks(world); + sendMessage(" - MCA #: " + chunks.size()); + sendMessage(" - CHUNKS: " + (chunks.size() * 256) +" (max)"); + sendMessage(" - TIME ESTIMATE: " + (chunks.size()/1200) +" minutes"); + Trim.TASK_ID = Bukkit.getScheduler().scheduleSyncRepeatingTask(PlotMain.getMain(), new Runnable() { + @Override + public void run() { + if (chunks.size() == 0) { + TaskManager.runTask(whenDone); + Bukkit.getScheduler().cancelTask(Trim.TASK_ID); + return; + } + ChunkLoc loc = chunks.get(0); + int sx = loc.x << 5; + int sz = loc.z << 5; + + boolean delete = true; + + loop: + for (int x = sx; x < sx + 32; x++) { + for (int z = sz; z < sz + 32; z++) { + Chunk chunk = world.getChunkAt(x, z); + if (ChunkManager.hasPlot(world, chunk) != null) { + delete = false; + break loop; + } + } + } + if (delete) { + empty.add(loc); + } + } + }, 1L, 1L); + Trim.TASK = true; return true; } @@ -219,99 +250,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 +258,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/generator/HybridPlotManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/HybridPlotManager.java index 004ffebdf..e55ac02fa 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); 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 cd4ffd0a5..a796ed909 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java @@ -78,7 +78,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(); }