diff --git a/pom.xml b/pom.xml index db657e472..699788e16 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ UTF-8 PlotSquared - 3.1.10 + 3.2.0 PlotSquared jar diff --git a/src/main/java/com/intellectualcrafters/plot/PS.java b/src/main/java/com/intellectualcrafters/plot/PS.java index 534b6e9ee..80f8a611b 100644 --- a/src/main/java/com/intellectualcrafters/plot/PS.java +++ b/src/main/java/com/intellectualcrafters/plot/PS.java @@ -399,6 +399,9 @@ public class PS { plots.put(world, new ConcurrentHashMap()); } plots.get(world).put(plot.id, plot); + for (PlotPlayer pp : plot.getPlayersInPlot()) { + pp.setMeta("lastplot", plot); + } } /** @@ -1090,13 +1093,13 @@ public class PS { } return new HashMap<>(myplots); } - return new HashMap<>(); + return new HashMap<>(0); } public Collection getPlotsInWorld(final String world) { final ConcurrentHashMap map = plots.get(world); if (map == null) { - return new HashSet<>(); + return new HashSet<>(0); } try { return map.values(); @@ -1776,24 +1779,25 @@ public class PS { // Clearing + Expiry options.put("clear.fastmode", Settings.ENABLE_CLUSTERS); options.put("clear.on.ban", false); - options.put("clear.auto.enabled", false); - options.put("clear.auto.days", 365); + 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", 2); - options.put("clear.auto.calibration.data", 32); + 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", 1); - options.put("clear.auto.calibration.changes_sd", 64); - options.put("clear.auto.calibration.faces_sd", 32); - options.put("clear.auto.calibration.data_sd", 1); + 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", 1); + options.put("clear.auto.calibration.variety_sd", 0); final int keep = config.getInt("clear.keep-if-modified"); final int ignore = config.getInt("clear.ignore-if-modified"); if ((keep > 0) || (ignore > 0)) { options.put("clear.auto.threshold", 1); + options.put("clear.auto.enabled", false); log("&cIMPORTANT MESSAGE ABOUT THIS UPDATE!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); log("&cSorry for all the exclamation marks, but this could be important."); log("&cPlot clearing has changed to a new system that requires calibration."); diff --git a/src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java b/src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java index c1bb37e77..6fdbe9ae3 100644 --- a/src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java +++ b/src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java @@ -429,11 +429,11 @@ public class PlotAPI { * * @return plot, null if ID is wrong * - * @see MainUtil#getPlot(String, com.intellectualcrafters.plot.object.PlotId) + * @see MainUtil#getPlotAbs(String, com.intellectualcrafters.plot.object.PlotId) * @see com.intellectualcrafters.plot.object.Plot */ public Plot getPlot(final World world, final int x, final int z) { - return MainUtil.getPlot(world.getName(), new PlotId(x, z)); + return MainUtil.getPlotAbs(world.getName(), new PlotId(x, z)); } /** @@ -443,11 +443,11 @@ public class PlotAPI { * * @return plot if found, otherwise it creates a temporary plot- * - * @see MainUtil#getPlot(com.intellectualcrafters.plot.object.Location) + * @see MainUtil#getPlotAbs(com.intellectualcrafters.plot.object.Location) * @see com.intellectualcrafters.plot.object.Plot */ public Plot getPlot(final Location l) { - return MainUtil.getPlot(BukkitUtil.getLocation(l)); + return MainUtil.getPlotAbs(BukkitUtil.getLocation(l)); } /** @@ -558,8 +558,8 @@ public class PlotAPI { */ public Location[] getLocations(final Plot p) { return new Location[] { - BukkitUtil.getLocation(MainUtil.getPlotBottomLoc(p.world, p.id)), - BukkitUtil.getLocation(MainUtil.getPlotTopLoc(p.world, p.id)), + BukkitUtil.getLocation(MainUtil.getPlotBottomLocAbs(p.world, p.id).subtract(1, 0, 1)), + BukkitUtil.getLocation(MainUtil.getPlotTopLocAbs(p.world, p.id)), BukkitUtil.getLocation(MainUtil.getPlotHome(p.world, p.id)) }; } @@ -590,7 +590,7 @@ public class PlotAPI { * @see com.intellectualcrafters.plot.object.Plot */ public Location getBottomLocation(final Plot p) { - return BukkitUtil.getLocation(MainUtil.getPlotBottomLoc(p.world, p.id)); + return BukkitUtil.getLocation(MainUtil.getPlotBottomLocAbs(p.world, p.id).subtract(1, 0, 1)); } /** @@ -604,7 +604,7 @@ public class PlotAPI { * @see com.intellectualcrafters.plot.object.Plot */ public Location getTopLocation(final Plot p) { - return BukkitUtil.getLocation(MainUtil.getPlotTopLoc(p.world, p.id)); + return BukkitUtil.getLocation(MainUtil.getPlotTopLocAbs(p.world, p.id)); } /** @@ -614,10 +614,10 @@ public class PlotAPI { * * @return true if the player is in a plot, false if not- * - * @see com.intellectualcrafters.plot.util.MainUtil#getPlot(com.intellectualcrafters.plot.object.Location) + * @see com.intellectualcrafters.plot.util.MainUtil#getPlotAbs(com.intellectualcrafters.plot.object.Location) */ public boolean isInPlot(final Player player) { - return MainUtil.getPlot(BukkitUtil.getLocation(player)) != null; + return MainUtil.getPlotAbs(BukkitUtil.getLocation(player)) != null; } /** diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Add.java b/src/main/java/com/intellectualcrafters/plot/commands/Add.java index 1f8d5f291..d4fbae708 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Add.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Add.java @@ -52,7 +52,7 @@ public class Add extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Auto.java b/src/main/java/com/intellectualcrafters/plot/commands/Auto.java index f70b987aa..28a66aa89 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Auto.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Auto.java @@ -161,7 +161,7 @@ public class Auto extends SubCommand { final PlotWorld plotworld = PS.get().getPlotWorld(worldname); if (plotworld.TYPE == 2) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(new Location(worldname, loc.getX(), loc.getY(), loc.getZ())); + final Plot plot = MainUtil.getPlotAbs(new Location(worldname, loc.getX(), loc.getY(), loc.getZ())); if (plot == null) { return sendMessage(plr, C.NOT_IN_PLOT); } @@ -180,8 +180,8 @@ public class Auto extends SubCommand { // for (int i = 0; i <= max; i++) { final PlotId currentId = new PlotId(origin.x + id.x, origin.y + id.y); - final Plot current = MainUtil.getPlot(worldname, currentId); - if (MainUtil.canClaim(plr, current) && (current.getSettings().isMerged() == false) && cluster.equals(current.getCluster())) { + final Plot current = MainUtil.getPlotAbs(worldname, currentId); + if (MainUtil.canClaim(plr, current) && (current.isMerged() == false) && cluster.equals(current.getCluster())) { Claim.claimPlot(plr, current, true, true); return true; } @@ -194,7 +194,7 @@ public class Auto extends SubCommand { boolean br = false; if ((size_x == 1) && (size_z == 1)) { while (!br) { - final Plot plot = MainUtil.getPlot(worldname, getLastPlot(worldname)); + final Plot plot = MainUtil.getPlotAbs(worldname, getLastPlot(worldname)); if (MainUtil.canClaim(plr, plot)) { Claim.claimPlot(plr, plot, true, true); br = true; @@ -217,7 +217,7 @@ public class Auto extends SubCommand { if (MainUtil.canClaim(plr, worldname, start, end)) { for (int i = start.x; i <= end.x; i++) { for (int j = start.y; j <= end.y; j++) { - final Plot plot = MainUtil.getPlot(worldname, new PlotId(i, j)); + final Plot plot = MainUtil.getPlotAbs(worldname, new PlotId(i, j)); final boolean teleport = ((i == end.x) && (j == end.y)); Claim.claimPlot(plr, plot, teleport, true); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/BO3.java b/src/main/java/com/intellectualcrafters/plot/commands/BO3.java index 87cc3dbd4..dd07c1979 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/BO3.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/BO3.java @@ -40,7 +40,7 @@ public class BO3 extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if ((plot == null) || !plot.hasOwner()) { return !sendMessage(plr, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Buy.java b/src/main/java/com/intellectualcrafters/plot/commands/Buy.java index ca9873fe9..75ee02fad 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Buy.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Buy.java @@ -20,6 +20,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// package com.intellectualcrafters.plot.commands; +import java.util.HashSet; +import java.util.Set; + import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.Settings; @@ -58,64 +61,54 @@ public class Buy extends SubCommand { if (!PS.get().isPlotWorld(world)) { return sendMessage(plr, C.NOT_IN_PLOT_WORLD); } + Set plots; Plot plot; if (args.length > 0) { try { final String[] split = args[0].split(";"); final PlotId id = new PlotId(Integer.parseInt(split[0]), Integer.parseInt(split[1])); - plot = MainUtil.getPlot(world, id); + plot = MainUtil.getPlotAbs(world, id); + plots = MainUtil.getConnectedPlots(plot); } catch (final Exception e) { return sendMessage(plr, C.NOT_VALID_PLOT_ID); } } else { - plot = MainUtil.getPlot(loc); + plot = MainUtil.getPlotAbs(loc); + plots = MainUtil.getConnectedPlots(plot); } - if (plot == null) { + if (plots == null) { return sendMessage(plr, C.NOT_IN_PLOT); } - final int currentPlots = Settings.GLOBAL_LIMIT ? MainUtil.getPlayerPlotCount(plr) : MainUtil.getPlayerPlotCount(world, plr); - if (currentPlots >= MainUtil.getAllowedPlots(plr)) { - return sendMessage(plr, C.CANT_CLAIM_MORE_PLOTS); - } if (!plot.hasOwner()) { return sendMessage(plr, C.PLOT_UNOWNED); } - if (PlotHandler.isOwner(plot, plr.getUUID())) { - return sendMessage(plr, C.CANNOT_BUY_OWN); + final int currentPlots = MainUtil.getPlayerPlotCount(plr) + plots.size(); + if (currentPlots > MainUtil.getAllowedPlots(plr)) { + return sendMessage(plr, C.CANT_CLAIM_MORE_PLOTS); } final Flag flag = FlagManager.getPlotFlag(plot, "price"); if (flag == null) { return sendMessage(plr, C.NOT_FOR_SALE); } - double initPrice = (double) flag.getValue(); - double price = initPrice; - final PlotId id = plot.id; - final PlotId id2 = MainUtil.getTopPlot(plot).id; - final int size = MainUtil.getPlotSelectionIds(id, id2).size(); - final PlotWorld plotworld = PS.get().getPlotWorld(world); - if (plotworld.USE_ECONOMY) { - price += plotworld.PLOT_PRICE * size; - initPrice += plotworld.SELL_PRICE * size; + if (plot.isOwner(plr.getUUID())) { + return sendMessage(plr, C.CANNOT_BUY_OWN); } + double price = (double) flag.getValue(); if ((EconHandler.manager != null) && (price > 0d)) { if (EconHandler.manager.getMoney(plr) < price) { return sendMessage(plr, C.CANNOT_AFFORD_PLOT, "" + price); } EconHandler.manager.withdrawMoney(plr, price); sendMessage(plr, C.REMOVED_BALANCE, price + ""); - EconHandler.manager.depositMoney(UUIDHandler.getUUIDWrapper().getOfflinePlayer(plot.owner), initPrice); + EconHandler.manager.depositMoney(UUIDHandler.getUUIDWrapper().getOfflinePlayer(plot.owner), price); final PlotPlayer owner = UUIDHandler.getPlayer(plot.owner); if (owner != null) { - sendMessage(plr, C.PLOT_SOLD, plot.id + "", plr.getName(), initPrice + ""); + sendMessage(plr, C.PLOT_SOLD, plot.id + "", plr.getName(), price + ""); } FlagManager.removePlotFlag(plot, "price"); } - final Plot top = MainUtil.getTopPlot(plot); - - for (final PlotId myId : MainUtil.getPlotSelectionIds(plot.id, top.id)) { - final Plot myPlot = MainUtil.getPlot(plot.world, myId); - myPlot.owner = plr.getUUID(); - DBFunc.setOwner(plot, myPlot.owner); + for (final Plot current : plots) { + plot.setOwner(plr.getUUID()); } MainUtil.sendMessage(plr, C.CLAIMED); return true; diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Claim.java b/src/main/java/com/intellectualcrafters/plot/commands/Claim.java index 056ddfd98..2cf0749a4 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Claim.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Claim.java @@ -51,7 +51,7 @@ public class Claim extends SubCommand { } public static boolean claimPlot(final PlotPlayer player, final Plot plot, final boolean teleport, final String schematic, final boolean auto) { - if (plot.hasOwner() || plot.getSettings().isMerged()) { + if (plot.hasOwner() || plot.isMerged()) { return false; } final boolean result = EventUtil.manager.callClaim(player, plot, false); @@ -94,13 +94,12 @@ public class Claim extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String... args) { - String schematic = ""; if (args.length >= 1) { schematic = args[0]; } final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return sendMessage(plr, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Clear.java b/src/main/java/com/intellectualcrafters/plot/commands/Clear.java index e48e0890a..6580fbfa6 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Clear.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Clear.java @@ -33,6 +33,7 @@ import com.intellectualcrafters.plot.object.PlotPlayer; import com.intellectualcrafters.plot.util.CmdConfirm; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.Permissions; +import com.intellectualcrafters.plot.util.SetBlockQueue; import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.UUIDHandler; import com.plotsquared.general.commands.CommandDeclaration; @@ -59,10 +60,10 @@ public class Clear extends SubCommand { return false; } } else { - plot = MainUtil.getPlot(loc.getWorld(), id); + plot = MainUtil.getPlotAbs(loc.getWorld(), id); } } else { - plot = MainUtil.getPlot(loc); + plot = MainUtil.getPlotAbs(loc); } if (plot == null) { MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot clear [X;Z|mine]"); @@ -71,11 +72,10 @@ public class Clear extends SubCommand { // if (!MainUtil.getTopPlot(plot).equals(MainUtil.getBottomPlot(plot))) { // return sendMessage(plr, C.UNLINK_REQUIRED); // } - if (((plot == null) || !plot.hasOwner() || !plot.isOwner(UUIDHandler.getUUID(plr))) && !Permissions.hasPermission(plr, "plots.admin.command.clear")) { + if (((plot == null) || !plot.hasOwner() || !plot.isOwner(plr.getUUID())) && !Permissions.hasPermission(plr, "plots.admin.command.clear")) { return sendMessage(plr, C.NO_PLOT_PERMS); } - assert plot != null; - if (MainUtil.runners.containsKey(plot)) { + if (plot.getRunning() != 0) { MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); return false; } @@ -91,19 +91,29 @@ public class Clear extends SubCommand { final boolean result = MainUtil.clearAsPlayer(plot, plot.owner == null, new Runnable() { @Override public void run() { - // If the state changes, then mark it as no longer done - if (FlagManager.getPlotFlag(plot, "done") != null) { - FlagManager.removePlotFlag(plot, "done"); - } - if (FlagManager.getPlotFlag(plot, "analysis") != null) { - FlagManager.removePlotFlag(plot, "analysis"); - } - MainUtil.sendMessage(plr, C.CLEARING_DONE, "" + (System.currentTimeMillis() - start)); + plot.unlink(); + SetBlockQueue.addNotify(new Runnable() { + @Override + public void run() { + plot.removeRunning(); + // If the state changes, then mark it as no longer done + if (FlagManager.getPlotFlag(plot, "done") != null) { + FlagManager.removePlotFlag(plot, "done"); + } + if (FlagManager.getPlotFlag(plot, "analysis") != null) { + FlagManager.removePlotFlag(plot, "analysis"); + } + MainUtil.sendMessage(plr, C.CLEARING_DONE, "" + (System.currentTimeMillis() - start)); + } + }); } }); if (!result) { MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); } + else { + plot.addRunning(); + } } }; if (Settings.CONFIRM_CLEAR && !(Permissions.hasPermission(plr, "plots.confirm.bypass"))) { diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Comment.java b/src/main/java/com/intellectualcrafters/plot/commands/Comment.java index 381cd5dac..564fa2521 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Comment.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Comment.java @@ -59,10 +59,10 @@ public class Comment extends SubCommand { return false; } index = 2; - plot = MainUtil.getPlot(loc.getWorld(), id); + plot = MainUtil.getPlotAbs(loc.getWorld(), id); } else { index = 1; - plot = MainUtil.getPlot(loc); + plot = MainUtil.getPlotAbs(loc); } if (!inbox.canWrite(plot, player)) { sendMessage(player, C.NO_PERM_INBOX, ""); diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Condense.java b/src/main/java/com/intellectualcrafters/plot/commands/Condense.java index 461df81a3..1904830df 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Condense.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Condense.java @@ -23,8 +23,10 @@ package com.intellectualcrafters.plot.commands; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.object.Plot; @@ -33,6 +35,7 @@ import com.intellectualcrafters.plot.object.PlotPlayer; import com.intellectualcrafters.plot.util.BlockManager; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.MathMan; +import com.intellectualcrafters.plot.util.TaskManager; import com.plotsquared.general.commands.CommandDeclaration; @CommandDeclaration(command = "condense", permission = "plots.admin", description = "Condense a plotworld", category = CommandCategory.DEBUG, requiredType = RequiredType.CONSOLE) @@ -70,18 +73,53 @@ public class Condense extends SubCommand { return false; } final int radius = Integer.parseInt(args[2]); - final Collection plots = PS.get().getPlotsInWorld(worldname); - final int size = plots.size(); + ArrayList plots = new ArrayList<>(PS.get().getPlotsInWorld(worldname)); + // remove non base plots + Iterator iter = plots.iterator(); + int maxSize = 0; + ArrayList sizes = new ArrayList<>(); + while (iter.hasNext()) { + Plot plot = iter.next(); + if (!plot.isBasePlot()) { + iter.remove(); + continue; + } + int size = plot.getConnectedPlots().size(); + if (size > maxSize) { + maxSize = size; + } + sizes.add(size - 1); + } + // Sort plots by size (buckets?)] + ArrayList[] buckets = new ArrayList[maxSize]; + for (int i = 0; i < plots.size(); i++) { + Plot plot = plots.get(i); + int size = sizes.get(i); + ArrayList array = buckets[size]; + if (array == null) { + array = new ArrayList(); + buckets[size] = array; + } + array.add(plot); + } + final ArrayList allPlots = new ArrayList(plots.size()); + for (int i = buckets.length - 1; i >= 0; i--) { + ArrayList array = buckets[i]; + if (array != null) { + allPlots.addAll(array); + } + } + final int size = allPlots.size(); final int minimum_radius = (int) Math.ceil((Math.sqrt(size) / 2) + 1); if (radius < minimum_radius) { MainUtil.sendMessage(plr, "RADIUS TOO SMALL"); return false; } - final List to_move = new ArrayList<>(getPlots(plots, radius)); + final List to_move = new ArrayList<>(getPlots(allPlots, radius)); final List free = new ArrayList<>(); PlotId start = new PlotId(0, 0); while ((start.x <= minimum_radius) && (start.y <= minimum_radius)) { - final Plot plot = MainUtil.getPlot(worldname, start); + final Plot plot = MainUtil.getPlotAbs(worldname, start); if (!plot.hasOwner()) { free.add(plot.id); } @@ -91,53 +129,54 @@ public class Condense extends SubCommand { MainUtil.sendMessage(plr, "NO FREE PLOTS FOUND"); return false; } - MainUtil.move(MainUtil.getPlot(worldname, to_move.get(0)), MainUtil.getPlot(worldname, free.get(0)), new Runnable() { + MainUtil.sendMessage(plr, "TASK STARTED..."); + Runnable run = new Runnable() { @Override public void run() { if (!TASK) { - MainUtil.sendMessage(plr, "CONDENSE TASK CANCELLED"); - return; + MainUtil.sendMessage(plr, "TASK CANCELLED."); } - to_move.remove(0); - free.remove(0); - int index = 0; - for (final PlotId id : to_move) { - final Plot plot = MainUtil.getPlot(worldname, id); - if (plot.hasOwner()) { - break; - } - index++; - } - for (int i = 0; i < index; i++) { - to_move.remove(0); - } - index = 0; - for (final PlotId id : free) { - final Plot plot = MainUtil.getPlot(worldname, id); - if (!plot.hasOwner()) { - break; - } - index++; - } - for (int i = 0; i < index; i++) { - free.remove(0); - } - if (to_move.size() == 0) { - MainUtil.sendMessage(plr, "TASK COMPLETE. PLEASE VERIFY THAT NO NEW PLOTS HAVE BEEN CLAIMED DURING TASK."); + if (allPlots.size() == 0) { TASK = false; + MainUtil.sendMessage(plr, "TASK COMPLETE. PLEASE VERIFY THAT NO NEW PLOTS HAVE BEEN CLAIMED DURING TASK."); return; } + final Runnable task = this; + final Plot origin = allPlots.remove(0); + int i = 0; + while (free.size() > i) { + final Plot possible = MainUtil.getPlotAbs(origin.world, free.get(i)); + if (possible.owner != null) { + free.remove(i); + continue; + } + i++; + final AtomicBoolean result = new AtomicBoolean(false); + result.set(MainUtil.move(origin, possible, new Runnable() { + @Override + public void run() { + if (result.get()) { + MainUtil.sendMessage(plr, "Moving: " + origin + " -> " + possible); + TaskManager.runTaskLater(task, 1); + } + } + }, false)); + if (result.get()) { + break; + } + } if (free.size() == 0) { - MainUtil.sendMessage(plr, "TASK FAILED. NO FREE PLOTS FOUND!"); TASK = false; + MainUtil.sendMessage(plr, "TASK FAILED. NO FREE PLOTS FOUND!"); return; } - MainUtil.sendMessage(plr, "MOVING " + to_move.get(0) + " to " + free.get(0)); - MainUtil.move(MainUtil.getPlot(worldname, to_move.get(0)), MainUtil.getPlot(worldname, free.get(0)), this); + if (i >= free.size()) { + MainUtil.sendMessage(plr, "SKIPPING COMPLEX PLOT: " + origin); + } } - }); + }; TASK = true; - MainUtil.sendMessage(plr, "TASK STARTED..."); + TaskManager.runTaskAsync(run); return true; } case "stop": { diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Continue.java b/src/main/java/com/intellectualcrafters/plot/commands/Continue.java index 12deb58f1..409ec4c61 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Continue.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Continue.java @@ -41,7 +41,7 @@ public class Continue extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if ((plot == null) || !plot.hasOwner()) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -49,7 +49,7 @@ public class Continue extends SubCommand { MainUtil.sendMessage(plr, C.NO_PLOT_PERMS); return false; } - if (!plot.getSettings().flags.containsKey("done")) { + if (!plot.getFlags().containsKey("done")) { MainUtil.sendMessage(plr, C.DONE_NOT_DONE); return false; } @@ -57,7 +57,7 @@ public class Continue extends SubCommand { MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.admin.command.continue"); return false; } - if (MainUtil.runners.containsKey(plot)) { + if (plot.getRunning() > 0) { MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); return false; } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Copy.java b/src/main/java/com/intellectualcrafters/plot/commands/Copy.java index 1393d5607..ad11438ca 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Copy.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Copy.java @@ -23,7 +23,6 @@ package com.intellectualcrafters.plot.commands; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; -import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotPlayer; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.Permissions; @@ -45,29 +44,30 @@ public class Copy extends SubCommand { } @Override - public boolean onCommand(final PlotPlayer plr, final String... args) { + public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot1 = MainUtil.getPlot(loc); + final Plot plot1 = MainUtil.getPlotAbs(loc); if (plot1 == null) { return !MainUtil.sendMessage(plr, C.NOT_IN_PLOT); } - if (!plot1.isAdded(plr.getUUID()) && !Permissions.hasPermission(plr, C.PERMISSION_ADMIN.s())) { + if (!plot1.isOwner(plr.getUUID()) && !Permissions.hasPermission(plr, C.PERMISSION_ADMIN.s())) { MainUtil.sendMessage(plr, C.NO_PLOT_PERMS); return false; } - final String world = loc.getWorld(); - final PlotId plot2 = MainUtil.parseId(args[0]); + final Plot plot2 = MainUtil.getPlotFromString(plr, args[0], true); if ((plot2 == null)) { + return false; + } + if (plot1.equals(plot2)) { MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID); MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot copy "); return false; } - if (plot1.id.equals(plot2)) { - MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID); - MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot copy "); + if (!plot1.getWorld().equals(plot2.getWorld())) { + C.PLOTWORLD_INCOMPATIBLE.send(plr); return false; } - if (MainUtil.copy(world, plot1.id, plot2, new Runnable() { + if (MainUtil.copy(plot1, plot2, new Runnable() { @Override public void run() { MainUtil.sendMessage(plr, C.COPY_SUCCESS); diff --git a/src/main/java/com/intellectualcrafters/plot/commands/CreateRoadSchematic.java b/src/main/java/com/intellectualcrafters/plot/commands/CreateRoadSchematic.java index d267581f2..1943639a8 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/CreateRoadSchematic.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/CreateRoadSchematic.java @@ -43,7 +43,7 @@ public class CreateRoadSchematic extends SubCommand { @Override public boolean onCommand(final PlotPlayer player, final String... args) { final Location loc = player.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return sendMessage(player, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/DebugClaimTest.java b/src/main/java/com/intellectualcrafters/plot/commands/DebugClaimTest.java index bd0d713f2..0d319ac64 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/DebugClaimTest.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/DebugClaimTest.java @@ -95,7 +95,7 @@ public class DebugClaimTest extends SubCommand { final PlotWorld plotworld = PS.get().getPlotWorld(world); final ArrayList plots = new ArrayList<>(); for (final PlotId id : MainUtil.getPlotSelectionIds(min, max)) { - final Plot plot = MainUtil.getPlot(world, id); + final Plot plot = MainUtil.getPlotAbs(world, id); if (PS.get().getPlot(world, plot.id) != null) { MainUtil.sendMessage(null, " - &cDB Already contains: " + plot.id); continue; diff --git a/src/main/java/com/intellectualcrafters/plot/commands/DebugClear.java b/src/main/java/com/intellectualcrafters/plot/commands/DebugClear.java deleted file mode 100644 index 506644ad1..000000000 --- a/src/main/java/com/intellectualcrafters/plot/commands/DebugClear.java +++ /dev/null @@ -1,67 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////// -// PlotSquared - A plot manager and world generator for the Bukkit API / -// Copyright (c) 2014 IntellectualSites/IntellectualCrafters / -// / -// This program is free software; you can redistribute it and/or modify / -// it under the terms of the GNU General Public License as published by / -// the Free Software Foundation; either version 3 of the License, or / -// (at your option) any later version. / -// / -// This program is distributed in the hope that it will be useful, / -// but WITHOUT ANY WARRANTY; without even the implied warranty of / -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the / -// GNU General Public License for more details. / -// / -// You should have received a copy of the GNU General Public License / -// along with this program; if not, write to the Free Software Foundation, / -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA / -// / -// You can contact us via: support@intellectualsites.com / -//////////////////////////////////////////////////////////////////////////////////////////////////// -package com.intellectualcrafters.plot.commands; - -import com.intellectualcrafters.plot.PS; -import com.intellectualcrafters.plot.config.C; -import com.intellectualcrafters.plot.generator.SquarePlotWorld; -import com.intellectualcrafters.plot.object.Location; -import com.intellectualcrafters.plot.object.Plot; -import com.intellectualcrafters.plot.object.PlotPlayer; -import com.intellectualcrafters.plot.util.ChunkManager; -import com.intellectualcrafters.plot.util.MainUtil; -import com.intellectualcrafters.plot.util.Permissions; -import com.intellectualcrafters.plot.util.UUIDHandler; -import com.plotsquared.general.commands.CommandDeclaration; - -@CommandDeclaration(command = "debugclear", aliases = { "fastclear" }, description = "Clear a plot using a fast experiment algorithm", category = CommandCategory.DEBUG) -public class DebugClear extends SubCommand { - - @Override - public boolean onCommand(final PlotPlayer plr, final String[] args) { - final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); - if ((plot == null) || !(PS.get().getPlotWorld(loc.getWorld()) instanceof SquarePlotWorld)) { - return sendMessage(plr, C.NOT_IN_PLOT); - } - if (!MainUtil.getTopPlot(plot).equals(MainUtil.getBottomPlot(plot))) { - return sendMessage(plr, C.UNLINK_REQUIRED); - } - if ((!plot.hasOwner() || !plot.isOwner(UUIDHandler.getUUID(plr))) && !Permissions.hasPermission(plr, "plots.admin.command.debugclear")) { - return sendMessage(plr, C.NO_PLOT_PERMS); - } - final Location pos1 = MainUtil.getPlotBottomLoc(loc.getWorld(), plot.id).add(1, 0, 1); - final Location pos2 = MainUtil.getPlotTopLoc(loc.getWorld(), plot.id); - if (MainUtil.runners.containsKey(plot)) { - MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); - return false; - } - MainUtil.runners.put(plot, 1); - ChunkManager.manager.regenerateRegion(pos1, pos2, new Runnable() { - @Override - public void run() { - MainUtil.runners.remove(plot); - MainUtil.sendMessage(plr, "&aDone!"); - } - }); - return true; - } -} diff --git a/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java b/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java index 165d2f74a..f0c5df95b 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java @@ -160,7 +160,7 @@ public class DebugExec extends SubCommand { boolean async = false; switch (arg) { case "analyze": { - final Plot plot = MainUtil.getPlot(player.getLocation()); + final Plot plot = MainUtil.getPlotAbs(player.getLocation()); if (plot == null) { MainUtil.sendMessage(player, C.NOT_IN_PLOT); return false; @@ -168,7 +168,7 @@ public class DebugExec extends SubCommand { final PlotAnalysis analysis = plot.getComplexity(); if (analysis != null) { final int complexity = analysis.getComplexity(); - MainUtil.sendMessage(player, "Changes: " + analysis.changes); + MainUtil.sendMessage(player, "Changes/column: " + (analysis.changes / 1.0)); MainUtil.sendMessage(player, "Complexity: " + complexity); return true; } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/DebugFill.java b/src/main/java/com/intellectualcrafters/plot/commands/DebugFill.java deleted file mode 100644 index 9342901cf..000000000 --- a/src/main/java/com/intellectualcrafters/plot/commands/DebugFill.java +++ /dev/null @@ -1,166 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////// -// PlotSquared - A plot manager and world generator for the Bukkit API / -// Copyright (c) 2014 IntellectualSites/IntellectualCrafters / -// / -// This program is free software; you can redistribute it and/or modify / -// it under the terms of the GNU General Public License as published by / -// the Free Software Foundation; either version 3 of the License, or / -// (at your option) any later version. / -// / -// This program is distributed in the hope that it will be useful, / -// but WITHOUT ANY WARRANTY; without even the implied warranty of / -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the / -// GNU General Public License for more details. / -// / -// You should have received a copy of the GNU General Public License / -// along with this program; if not, write to the Free Software Foundation, / -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA / -// / -// You can contact us via: support@intellectualsites.com / -//////////////////////////////////////////////////////////////////////////////////////////////////// -package com.intellectualcrafters.plot.commands; - -import com.intellectualcrafters.plot.config.C; -import com.intellectualcrafters.plot.object.Location; -import com.intellectualcrafters.plot.object.Plot; -import com.intellectualcrafters.plot.object.PlotBlock; -import com.intellectualcrafters.plot.object.PlotPlayer; -import com.intellectualcrafters.plot.util.MainUtil; -import com.intellectualcrafters.plot.util.Permissions; -import com.intellectualcrafters.plot.util.SetBlockQueue; -import com.intellectualcrafters.plot.util.TaskManager; -import com.plotsquared.general.commands.CommandDeclaration; - -@CommandDeclaration( -command = "fill", -permission = "plots.fill", -description = "Fill or surround a plot in bedrock", -usage = "/plot fill", -aliases = { "debugfill" }, -category = CommandCategory.DEBUG, -requiredType = RequiredType.NONE) -public class DebugFill extends SubCommand { - - @Override - public boolean onCommand(final PlotPlayer player, final String... args) { - if ((args.length != 1) || (!args[0].equalsIgnoreCase("outline") && !args[0].equalsIgnoreCase("all"))) { - MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot fill "); - return true; - } - final Location loc = player.getLocation(); - final Plot plot = MainUtil.getPlot(loc); - if (plot == null) { - return !sendMessage(player, C.NOT_IN_PLOT); - } - if (!plot.hasOwner()) { - MainUtil.sendMessage(player, C.PLOT_UNOWNED); - return false; - } - if (!plot.isOwner(player.getUUID()) && !Permissions.hasPermission(player, "plots.admin.command.fill")) { - MainUtil.sendMessage(player, C.NO_PLOT_PERMS); - return true; - } - if (MainUtil.runners.containsKey(plot)) { - MainUtil.sendMessage(player, C.WAIT_FOR_TIMER); - return false; - } - final Location bottom = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); - final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id); - MainUtil.sendMessage(player, "&cPreparing task"); - MainUtil.runners.put(plot, 1); - SetBlockQueue.addNotify(new Runnable() { - @Override - public void run() { - TaskManager.runTaskAsync(new Runnable() { - @Override - public void run() { - MainUtil.sendMessage(player, "&7 - Starting"); - if (args[0].equalsIgnoreCase("all")) { - int height = 255; - PlotBlock block = new PlotBlock((short) 7, (byte) 0); - final PlotBlock air = new PlotBlock((short) 0, (byte) 0); - if (args.length > 2) { - try { - block = new PlotBlock(Short.parseShort(args[1]), (byte) 0); - if (args.length == 3) { - height = Integer.parseInt(args[2]); - } - } catch (final Exception e) { - MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot fill all "); - MainUtil.runners.remove(plot); - return; - } - } - for (int y = 0; y <= height; y++) { - for (int x = bottom.getX(); x <= top.getX(); x++) { - for (int z = bottom.getZ(); z <= top.getZ(); z++) { - SetBlockQueue.setBlock(plot.world, x, y, z, block); - } - } - } - for (int y = height + 1; y <= 255; y++) { - for (int x = bottom.getX(); x <= top.getX(); x++) { - for (int z = bottom.getZ(); z <= top.getZ(); z++) { - SetBlockQueue.setBlock(plot.world, x, y, z, air); - } - } - } - SetBlockQueue.addNotify(new Runnable() { - @Override - public void run() { - MainUtil.runners.remove(plot); - MainUtil.sendMessage(player, "&aFill task complete!"); - } - }); - } else if (args[0].equals("outline")) { - int x, z; - z = bottom.getZ(); - for (x = bottom.getX(); x <= (top.getX() - 1); x++) { - for (int y = 1; y <= 255; y++) { - SetBlockQueue.setBlock(plot.world, x, y, z, 7); - } - } - x = top.getX(); - for (z = bottom.getZ(); z <= (top.getZ() - 1); z++) { - for (int y = 1; y <= 255; y++) { - SetBlockQueue.setBlock(plot.world, x, y, z, 7); - } - } - z = top.getZ(); - for (x = top.getX(); x >= (bottom.getX() + 1); x--) { - for (int y = 1; y <= 255; y++) { - SetBlockQueue.setBlock(plot.world, x, y, z, 7); - } - } - x = bottom.getX(); - for (z = top.getZ(); z >= (bottom.getZ() + 1); z--) { - for (int y = 1; y <= 255; y++) { - SetBlockQueue.setBlock(plot.world, x, y, z, 7); - } - } - SetBlockQueue.addNotify(new Runnable() { - @Override - public void run() { - MainUtil.sendMessage(player, "&aWalls complete! The ceiling will take a while :("); - bottom.setY(255); - top.add(1, 0, 1); - SetBlockQueue.setSlow(true); - MainUtil.setSimpleCuboidAsync(plot.world, bottom, top, new PlotBlock((short) 7, (byte) 0)); - SetBlockQueue.addNotify(new Runnable() { - @Override - public void run() { - MainUtil.runners.remove(plot); - MainUtil.sendMessage(player, "&aFill task complete!"); - SetBlockQueue.setSlow(false); - } - }); - } - }); - } - } - }); - } - }); - return true; - } -} diff --git a/src/main/java/com/intellectualcrafters/plot/commands/DebugFixFlags.java b/src/main/java/com/intellectualcrafters/plot/commands/DebugFixFlags.java index 094bd6040..c991bd28d 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/DebugFixFlags.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/DebugFixFlags.java @@ -58,7 +58,7 @@ public class DebugFixFlags extends SubCommand { } MainUtil.sendMessage(plr, "&8--- &6Starting task &8 ---"); for (final Plot plot : PS.get().getPlotsInWorld(world)) { - final HashMap flags = plot.getSettings().flags; + final HashMap flags = plot.getFlags(); final Iterator> i = flags.entrySet().iterator(); boolean changed = false; while (i.hasNext()) { @@ -68,7 +68,7 @@ public class DebugFixFlags extends SubCommand { } } if (changed) { - DBFunc.setFlags(plot, plot.getSettings().flags.values()); + DBFunc.setFlags(plot, plot.getFlags().values()); } } MainUtil.sendMessage(plr, "&aDone!"); diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Delete.java b/src/main/java/com/intellectualcrafters/plot/commands/Delete.java index 437943666..0ed9a050e 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Delete.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Delete.java @@ -20,6 +20,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// package com.intellectualcrafters.plot.commands; +import java.util.HashSet; + import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.Settings; @@ -49,51 +51,52 @@ public class Delete extends SubCommand { public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } - if (!MainUtil.getTopPlot(plot).equals(MainUtil.getBottomPlot(plot))) { - return !sendMessage(plr, C.UNLINK_REQUIRED); + if (!plot.hasOwner()) { + return !sendMessage(plr, C.PLOT_UNOWNED); } - if (((!plot.hasOwner() || !plot.isOwner(plr.getUUID()))) && !Permissions.hasPermission(plr, "plots.admin.command.delete")) { + if (!plot.isOwner(plr.getUUID()) && !Permissions.hasPermission(plr, "plots.admin.command.delete")) { return !sendMessage(plr, C.NO_PLOT_PERMS); } - final PlotWorld pWorld = PS.get().getPlotWorld(plot.world); - if (MainUtil.runners.containsKey(plot)) { - MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); - return false; - } - final Runnable runnable = new Runnable() { + final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); + final HashSet plots = MainUtil.getConnectedPlots(plot); + final Runnable run = new Runnable() { @Override public void run() { - if ((EconHandler.manager != null) && pWorld.USE_ECONOMY && plot.hasOwner() && plot.isOwner(UUIDHandler.getUUID(plr))) { - final double c = pWorld.SELL_PRICE; - if (c > 0d) { - EconHandler.manager.depositMoney(plr, c); - sendMessage(plr, C.ADDED_BALANCE, c + ""); - } + if (plot.getRunning() > 0) { + MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); + return; } - if (plot.unclaim()) { - final long start = System.currentTimeMillis(); - final boolean result = MainUtil.clearAsPlayer(plot, true, new Runnable() { - @Override - public void run() { - MainUtil.sendMessage(plr, C.CLEARING_DONE, "" + (System.currentTimeMillis() - start)); + final long start = System.currentTimeMillis(); + boolean result = plot.deletePlot(new Runnable() { + @Override + public void run() { + plot.removeRunning(); + if ((EconHandler.manager != null) && plotworld.USE_ECONOMY) { + final double value = plotworld.SELL_PRICE * plots.size(); + if (value > 0d) { + EconHandler.manager.depositMoney(plr, value); + sendMessage(plr, C.ADDED_BALANCE, value + ""); + } } - }); - if (!result) { - MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); + MainUtil.sendMessage(plr, C.CLEARING_DONE, "" + (System.currentTimeMillis() - start)); } - } else { - MainUtil.sendMessage(plr, C.UNCLAIM_FAILED); + }); + if (result) { + plot.addRunning(); + } + else { + MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); } } }; if (Settings.CONFIRM_DELETE && !(Permissions.hasPermission(plr, "plots.confirm.bypass"))) { - CmdConfirm.addPending(plr, "/plot delete " + plot.id, runnable); + CmdConfirm.addPending(plr, "/plot delete " + plot.id, run); } else { - TaskManager.runTask(runnable); + TaskManager.runTask(run); } return true; } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Deny.java b/src/main/java/com/intellectualcrafters/plot/commands/Deny.java index 5685515c4..cf66252d8 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Deny.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Deny.java @@ -47,7 +47,7 @@ public class Deny extends SubCommand { public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -95,7 +95,7 @@ public class Deny extends SubCommand { private void handleKick(final UUID uuid, final Plot plot) { final PlotPlayer pp = UUIDHandler.getPlayer(uuid); - if ((pp != null) && plot.equals(MainUtil.getPlot(pp.getLocation()))) { + if ((pp != null) && plot.equals(MainUtil.getPlotAbs(pp.getLocation()))) { pp.teleport(BlockManager.manager.getSpawn(pp.getLocation().getWorld())); MainUtil.sendMessage(pp, C.YOU_GOT_DENIED); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Done.java b/src/main/java/com/intellectualcrafters/plot/commands/Done.java index 505082ec0..a984b02f3 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Done.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Done.java @@ -40,7 +40,7 @@ public class Done extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if ((plot == null) || !plot.hasOwner()) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -48,11 +48,11 @@ public class Done extends SubCommand { MainUtil.sendMessage(plr, C.NO_PLOT_PERMS); return false; } - if (plot.getSettings().flags.containsKey("done")) { + if (plot.getFlags().containsKey("done")) { MainUtil.sendMessage(plr, C.DONE_ALREADY_DONE); return false; } - if (MainUtil.runners.containsKey(plot)) { + if (plot.getRunning() > 0) { MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); return false; } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Download.java b/src/main/java/com/intellectualcrafters/plot/commands/Download.java index be0c55819..47c88b1e6 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Download.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Download.java @@ -30,7 +30,7 @@ public class Download extends SubCommand { if (!PS.get().isPlotWorld(world)) { return !sendMessage(plr, C.NOT_IN_PLOT_WORLD); } - final Plot plot = MainUtil.getPlot(plr.getLocation()); + final Plot plot = MainUtil.getPlotAbs(plr.getLocation()); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -42,7 +42,7 @@ public class Download extends SubCommand { MainUtil.sendMessage(plr, C.NO_PLOT_PERMS); return false; } - if (MainUtil.runners.containsKey(plot)) { + if (plot.getRunning() > 0) { MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); return false; } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/FlagCmd.java b/src/main/java/com/intellectualcrafters/plot/commands/FlagCmd.java index 4a851bdc5..0419bce94 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/FlagCmd.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/FlagCmd.java @@ -68,7 +68,7 @@ public class FlagCmd extends SubCommand { return false; } final Location loc = player.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { MainUtil.sendMessage(player, C.NOT_IN_PLOT); return false; @@ -172,7 +172,7 @@ public class FlagCmd extends SubCommand { if ((args.length == 3) && flag.getAbstractFlag().isList()) { final String value = StringMan.join(Arrays.copyOfRange(args, 2, args.length), " "); ((FlagValue.ListValue) flag.getAbstractFlag().value).remove(flag.getValue(), value); - DBFunc.setFlags(plot, plot.getSettings().flags.values()); + DBFunc.setFlags(plot, plot.getFlags().values()); } else { final boolean result = FlagManager.removePlotFlag(plot, flag.getKey()); if (!result) { @@ -222,7 +222,7 @@ public class FlagCmd extends SubCommand { MainUtil.sendMessage(player, C.FLAG_NOT_ADDED); return false; } - DBFunc.setFlags(plot, plot.getSettings().flags.values()); + DBFunc.setFlags(plot, plot.getFlags().values()); MainUtil.sendMessage(player, C.FLAG_ADDED); return true; } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Inbox.java b/src/main/java/com/intellectualcrafters/plot/commands/Inbox.java index 4397fa703..3440aeb7e 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Inbox.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Inbox.java @@ -83,7 +83,7 @@ public class Inbox extends SubCommand { @Override public boolean onCommand(final PlotPlayer player, final String[] args) { - final Plot plot = MainUtil.getPlot(player.getLocation()); + final Plot plot = MainUtil.getPlotAbs(player.getLocation()); if (args.length == 0) { sendMessage(player, C.COMMAND_SYNTAX, "/plot inbox [inbox] [delete |clear|page]"); for (final CommentInbox inbox : CommentManager.inboxes.values()) { diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Info.java b/src/main/java/com/intellectualcrafters/plot/commands/Info.java index 3cf649b92..a74ed37ad 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Info.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Info.java @@ -32,10 +32,12 @@ import com.intellectualcrafters.plot.flag.Flag; import com.intellectualcrafters.plot.flag.FlagManager; import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; +import com.intellectualcrafters.plot.object.PlotBlock; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotInventory; import com.intellectualcrafters.plot.object.PlotItemStack; import com.intellectualcrafters.plot.object.PlotPlayer; +import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.util.BlockManager; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.StringMan; @@ -139,14 +141,14 @@ public class Info extends SubCommand { inv.setItem(1, new PlotItemStack(388, (short) 0, 1, "&cPlot Info", new String[] { "&cID: &6" + plot.getId().toString(), "&cOwner: &6" + name, - "&cAlias: &6" + plot.getSettings().getAlias(), + "&cAlias: &6" + plot.getAlias(), "&cBiome: &6" + plot.getBiome().toString().replaceAll("_", "").toLowerCase(), "&cCan Build: &6" + plot.isAdded(uuid), "&cIs Denied: &6" + plot.isDenied(uuid) })); inv.setItem(1, new PlotItemStack(388, (short) 0, 1, "&cTrusted", new String[] { "&cAmount: &6" + plot.getTrusted().size(), "&8Click to view a list of the trusted users" })); inv.setItem(1, new PlotItemStack(388, (short) 0, 1, "&cMembers", new String[] { "&cAmount: &6" + plot.getMembers().size(), "&8Click to view a list of plot members" })); inv.setItem(1, new PlotItemStack(388, (short) 0, 1, "&cDenied", new String[] { "&cDenied", "&cAmount: &6" + plot.getDenied().size(), "&8Click to view a list of denied players" })); - inv.setItem(1, new PlotItemStack(388, (short) 0, 1, "&cFlags", new String[] { "&cFlags", "&cAmount: &6" + plot.getSettings().flags.size(), "&8Click to view a list of plot flags" })); + inv.setItem(1, new PlotItemStack(388, (short) 0, 1, "&cFlags", new String[] { "&cFlags", "&cAmount: &6" + plot.getFlags().size(), "&8Click to view a list of plot flags" })); inv.openInventory(); return true; } @@ -205,12 +207,10 @@ public class Info extends SubCommand { } private void formatAndSend(String info, final String world, final Plot plot, final PlotPlayer player, final boolean full) { - final PlotId id = plot.id; - final PlotId id2 = MainUtil.getTopPlot(plot).id; - final int num = MainUtil.getPlotSelectionIds(id, id2).size(); - final String alias = plot.getSettings().getAlias().length() > 0 ? plot.getSettings().getAlias() : C.NONE.s(); - final Location top = MainUtil.getPlotTopLoc(world, plot.id); - final Location bot = MainUtil.getPlotBottomLoc(world, plot.id).add(1, 0, 1); + final int num = MainUtil.getConnectedPlots(plot).size(); + final String alias = plot.getAlias().length() > 0 ? plot.getAlias() : C.NONE.s(); + final Location top = MainUtil.getPlotTopLocAbs(world, plot.id); + final Location bot = MainUtil.getPlotBottomLocAbs(world, plot.id); final String biome = BlockManager.manager.getBiome(plot.world, bot.getX() + ((top.getX() - bot.getX()) / 2), bot.getZ() + ((top.getZ() - bot.getZ()) / 2)); final String trusted = getPlayerList(plot.getTrusted()); final String members = getPlayerList(plot.getMembers()); @@ -227,9 +227,8 @@ public class Info extends SubCommand { final String owner = plot.owner == null ? "unowned" : getPlayerList(plot.getOwners()); + info = info.replaceAll("%id%", plot.id.toString()); info = info.replaceAll("%alias%", alias); - info = info.replaceAll("%id%", id.toString()); - info = info.replaceAll("%id2%", id2.toString()); info = info.replaceAll("%num%", num + ""); info = info.replaceAll("%desc%", description); info = info.replaceAll("%biome%", biome); diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Kick.java b/src/main/java/com/intellectualcrafters/plot/commands/Kick.java index aad63aefb..f8a05c2d1 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Kick.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Kick.java @@ -37,7 +37,7 @@ public class Kick extends SubCommand { public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -55,7 +55,7 @@ public class Kick extends SubCommand { return false; } final Location otherLoc = player.getLocation(); - if (!plr.getLocation().getWorld().equals(otherLoc.getWorld()) || !plot.equals(MainUtil.getPlot(otherLoc))) { + if (!plr.getLocation().getWorld().equals(otherLoc.getWorld()) || !plot.equals(MainUtil.getPlotAbs(otherLoc))) { MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[0]); return false; } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Load.java b/src/main/java/com/intellectualcrafters/plot/commands/Load.java index 3ce4f803e..ac2a3f7c7 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Load.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Load.java @@ -39,7 +39,7 @@ public class Load extends SubCommand { if (!PS.get().isPlotWorld(world)) { return !sendMessage(plr, C.NOT_IN_PLOT_WORLD); } - final Plot plot = MainUtil.getPlot(plr.getLocation()); + final Plot plot = MainUtil.getPlotAbs(plr.getLocation()); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -51,14 +51,13 @@ public class Load extends SubCommand { MainUtil.sendMessage(plr, C.NO_PLOT_PERMS); return false; } - if (MainUtil.runners.containsKey(plot)) { + if (plot.getRunning() > 0) { MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); return false; } if (args.length != 0) { if (args.length == 1) { - // TODO load save here final List schematics = (List) plr.getMeta("plot_schematics"); if (schematics == null) { // No schematics found: diff --git a/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java b/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java index ab2267f01..3c346b986 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java @@ -72,13 +72,11 @@ public class MainCommand extends CommandManager { createCommand(new Update()); createCommand(new Template()); createCommand(new Setup()); - createCommand(new DebugFill()); createCommand(new DebugSaveTest()); createCommand(new DebugLoadTest()); createCommand(new CreateRoadSchematic()); createCommand(new DebugAllowUnsafe()); createCommand(new RegenAllRoads()); - createCommand(new DebugClear()); createCommand(new Claim()); createCommand(new Auto()); createCommand(new Home()); @@ -294,9 +292,9 @@ public class MainCommand extends CommandManager { world = null; } if ((id != null) && PS.get().isPlotWorld(world)) { - final Plot plot = MainUtil.getPlot(world, id); + final Plot plot = MainUtil.getPlotAbs(world, id); if (plot != null) { - player.teleport(MainUtil.getPlotCenter(plot)); + player.teleport(plot.getBottomAbs()); args = Arrays.copyOfRange(args, 1, args.length); } } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Merge.java b/src/main/java/com/intellectualcrafters/plot/commands/Merge.java index 651da06e8..a7373f17f 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Merge.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Merge.java @@ -50,8 +50,8 @@ usage = "/plot merge [direction]", category = CommandCategory.ACTIONS, requiredType = RequiredType.NONE) public class Merge extends SubCommand { - public final static String[] values = new String[] { "north", "east", "south", "west" }; - public final static String[] aliases = new String[] { "n", "e", "s", "w" }; + public final static String[] values = new String[] { "north", "east", "south", "west", "auto" }; + public final static String[] aliases = new String[] { "n", "e", "s", "w", "all" }; public static String direction(float yaw) { yaw = yaw / 90; @@ -77,9 +77,8 @@ public class Merge extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { - final Location loc = plr.getLocationFull(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -92,27 +91,46 @@ public class Merge extends SubCommand { MainUtil.sendMessage(plr, C.NO_PLOT_PERMS); return false; } + final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); + if ((EconHandler.manager != null) && plotworld.USE_ECONOMY && plotworld.MERGE_PRICE > 0d && EconHandler.manager.getMoney(plr) < plotworld.MERGE_PRICE) { + sendMessage(plr, C.CANNOT_AFFORD_MERGE, plotworld.MERGE_PRICE + ""); + return false; + } int direction = -1; + final int size = plot.getConnectedPlots().size(); + final int maxSize = Permissions.hasPermissionRange(plr, "plots.merge", Settings.MAX_PLOTS); + if (size >= maxSize) { + MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.merge." + size); + return false; + } if (args.length == 0) { - switch (direction(plr.getLocationFull().getYaw())) { - case "NORTH": - direction = 0; - break; - case "EAST": - direction = 1; - break; - case "SOUTH": - direction = 2; - break; - case "WEST": - direction = 3; - break; - } +// switch (direction(plr.getLocationFull().getYaw())) { +// case "NORTH": +// direction = 0; +// break; +// case "EAST": +// direction = 1; +// break; +// case "SOUTH": +// direction = 2; +// break; +// case "WEST": +// direction = 3; +// break; +// } } else { - if (args[0].equalsIgnoreCase("all")) { - plot.autoMerge((args.length != 2) || !args[1].equalsIgnoreCase("false")); - MainUtil.sendMessage(plr, C.SUCCESS_MERGE); - return true; + if (args[0].equalsIgnoreCase("all") || args[0].equalsIgnoreCase("auto")) { + if (MainUtil.autoMerge(plot, -1, maxSize - size, plr.getUUID(), (args.length != 2) || !args[1].equalsIgnoreCase("false"))) { + if ((EconHandler.manager != null) && plotworld.USE_ECONOMY && plotworld.MERGE_PRICE > 0d) { + EconHandler.manager.withdrawMoney(plr, plotworld.MERGE_PRICE); + sendMessage(plr, C.REMOVED_BALANCE, plotworld.MERGE_PRICE + ""); + } + MainUtil.sendMessage(plr, C.SUCCESS_MERGE); + return true; + } + MainUtil.sendMessage(plr, C.NO_AVAILABLE_AUTOMERGE); + return false; + } for (int i = 0; i < values.length; i++) { if (args[0].equalsIgnoreCase(values[i]) || args[0].equalsIgnoreCase(aliases[i])) { @@ -122,135 +140,63 @@ public class Merge extends SubCommand { } } if (direction == -1) { - MainUtil.sendMessage(plr, C.SUBCOMMAND_SET_OPTIONS_HEADER.s() + StringMan.join(values, C.BLOCK_LIST_SEPARATER.s())); + MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot merge <" + StringMan.join(values, "|") + ">"); MainUtil.sendMessage(plr, C.DIRECTION.s().replaceAll("%dir%", direction(loc.getYaw()))); return false; } - PlotId bot = MainUtil.getBottomPlot(plot).id; - PlotId top = MainUtil.getTopPlot(plot).id; - ArrayList selPlots; - final String world = loc.getWorld(); - switch (direction) { - case 0: // north = -y - selPlots = MainUtil.getMaxPlotSelectionIds(world, new PlotId(bot.x, bot.y - 1), new PlotId(top.x, top.y)); - break; - case 1: // east = +x - selPlots = MainUtil.getMaxPlotSelectionIds(world, new PlotId(bot.x, bot.y), new PlotId(top.x + 1, top.y)); - break; - case 2: // south = +y - selPlots = MainUtil.getMaxPlotSelectionIds(world, new PlotId(bot.x, bot.y), new PlotId(top.x, top.y + 1)); - break; - case 3: // west = -x - selPlots = MainUtil.getMaxPlotSelectionIds(world, new PlotId(bot.x - 1, bot.y), new PlotId(top.x, top.y)); - break; - default: - return false; - } - final int size = selPlots.size(); - if (Permissions.hasPermissionRange(plr, "plots.merge", Settings.MAX_PLOTS) < size) { - MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.merge." + size); - return false; - } - final PlotId botId = selPlots.get(0); - final PlotId topId = selPlots.get(selPlots.size() - 1); - final PlotId bot1 = MainUtil.getBottomPlot(MainUtil.getPlot(world, botId)).id; - final PlotId bot2 = MainUtil.getBottomPlot(MainUtil.getPlot(world, topId)).id; - final PlotId top1 = MainUtil.getTopPlot(MainUtil.getPlot(world, topId)).id; - final PlotId top2 = MainUtil.getTopPlot(MainUtil.getPlot(world, botId)).id; - bot = new PlotId(Math.min(bot1.x, bot2.x), Math.min(bot1.y, bot2.y)); - top = new PlotId(Math.max(top1.x, top2.x), Math.max(top1.y, top2.y)); - final ArrayList plots = MainUtil.getMaxPlotSelectionIds(world, bot, top); - boolean multiMerge = false; - final HashSet multiUUID = new HashSet(); - final HashSet multiPlots = new HashSet<>(); - final UUID u1 = plot.owner; - for (final PlotId myid : plots) { - final Plot myplot = PS.get().getPlot(world, myid); - if ((myplot == null) || (myplot.owner == null)) { - MainUtil.sendMessage(plr, C.NO_PERM_MERGE.s().replaceAll("%plot%", myid.toString())); - return false; + if (MainUtil.autoMerge(plot, direction, maxSize - size, plot.owner, (args.length != 2) || !args[1].equalsIgnoreCase("false"))) { + if ((EconHandler.manager != null) && plotworld.USE_ECONOMY && plotworld.MERGE_PRICE > 0d) { + EconHandler.manager.withdrawMoney(plr, plotworld.MERGE_PRICE); + sendMessage(plr, C.REMOVED_BALANCE, plotworld.MERGE_PRICE + ""); } - final UUID u2 = myplot.owner; - if (u2.equals(u1)) { - continue; - } - final PlotPlayer p2 = UUIDHandler.getPlayer(u2); - if (p2 == null) { - MainUtil.sendMessage(plr, C.NO_PERM_MERGE.s().replaceAll("%plot%", myid.toString())); - return false; - } - multiMerge = true; - multiPlots.add(myid); - multiUUID.add(u2); - } - if (multiMerge) { - if (!Permissions.hasPermission(plr, C.PERMISSION_MERGE_OTHER)) { - MainUtil.sendMessage(plr, C.NO_PERMISSION, C.PERMISSION_MERGE_OTHER.s()); - return false; - } - for (final UUID uuid : multiUUID) { - final PlotPlayer accepter = UUIDHandler.getPlayer(uuid); - CmdConfirm.addPending(accepter, C.MERGE_REQUEST_CONFIRM.s().replaceAll("%s", plr.getName()), new Runnable() { - @Override - public void run() { - final PlotPlayer accepter = UUIDHandler.getPlayer(uuid); - multiUUID.remove(uuid); - if (multiUUID.size() == 0) { - final PlotPlayer pp = UUIDHandler.getPlayer(u1); - if (pp == null) { - sendMessage(accepter, C.MERGE_NOT_VALID); - return; - } - final PlotWorld plotWorld = PS.get().getPlotWorld(world); - if ((EconHandler.manager != null) && plotWorld.USE_ECONOMY) { - double cost = plotWorld.MERGE_PRICE; - cost = plots.size() * cost; - if (cost > 0d) { - if (EconHandler.manager.getMoney(plr) < cost) { - sendMessage(plr, C.CANNOT_AFFORD_MERGE, cost + ""); - return; - } - EconHandler.manager.withdrawMoney(plr, cost); - sendMessage(plr, C.REMOVED_BALANCE, cost + ""); - } - } - final boolean result = EventUtil.manager.callMerge(world, plot, plots); - if (!result) { - MainUtil.sendMessage(plr, "&cMerge has been cancelled"); - return; - } - MainUtil.sendMessage(plr, C.SUCCESS_MERGE); - MainUtil.mergePlots(world, plots, true, true); - MainUtil.setSign(UUIDHandler.getName(plot.owner), plot); - } - MainUtil.sendMessage(accepter, C.MERGE_ACCEPTED); - } - }); - } - MainUtil.sendMessage(plr, C.MERGE_REQUESTED); + MainUtil.sendMessage(plr, C.SUCCESS_MERGE); return true; } - final PlotWorld plotWorld = PS.get().getPlotWorld(world); - if ((EconHandler.manager != null) && plotWorld.USE_ECONOMY) { - double cost = plotWorld.MERGE_PRICE; - cost = plots.size() * cost; - if (cost > 0d) { - if (EconHandler.manager.getMoney(plr) < cost) { - sendMessage(plr, C.CANNOT_AFFORD_MERGE, cost + ""); - return false; - } - EconHandler.manager.withdrawMoney(plr, cost); - sendMessage(plr, C.REMOVED_BALANCE, cost + ""); - } - } - final boolean result = EventUtil.manager.callMerge(world, plot, plots); - if (!result) { - MainUtil.sendMessage(plr, "&cMerge has been cancelled"); + Plot adjacent = MainUtil.getPlotAbs(plot.world, MainUtil.getPlotIdRelative(plot.id, direction)); + if (adjacent == null || !adjacent.hasOwner() || adjacent.getMerged((direction + 2) % 4)) { + MainUtil.sendMessage(plr, C.NO_AVAILABLE_AUTOMERGE); return false; } - MainUtil.sendMessage(plr, C.SUCCESS_MERGE); - MainUtil.mergePlots(world, plots, true, true); - MainUtil.setSign(UUIDHandler.getName(plot.owner), plot); + if (!Permissions.hasPermission(plr, C.PERMISSION_MERGE_OTHER)) { + MainUtil.sendMessage(plr, C.NO_PERMISSION, C.PERMISSION_MERGE_OTHER.s()); + return false; + } + HashSet uuids = adjacent.getOwners(); + boolean isOnline = false; + for (final UUID uuid : uuids) { + final PlotPlayer accepter = UUIDHandler.getPlayer(uuid); + if (accepter == null) { + continue; + } + isOnline = true; + final int dir = direction; + CmdConfirm.addPending(accepter, C.MERGE_REQUEST_CONFIRM.s().replaceAll("%s", plr.getName()), new Runnable() { + @Override + public void run() { + MainUtil.sendMessage(accepter, C.MERGE_ACCEPTED); + MainUtil.autoMerge(plot, dir, maxSize - size, uuid, true); + final PlotPlayer pp = UUIDHandler.getPlayer(plr.getUUID()); + if (pp == null) { + sendMessage(accepter, C.MERGE_NOT_VALID); + return; + } + if ((EconHandler.manager != null) && plotworld.USE_ECONOMY && plotworld.MERGE_PRICE > 0d) { + if (EconHandler.manager.getMoney(plr) < plotworld.MERGE_PRICE) { + sendMessage(plr, C.CANNOT_AFFORD_MERGE, plotworld.MERGE_PRICE + ""); + return; + } + EconHandler.manager.withdrawMoney(plr, plotworld.MERGE_PRICE); + sendMessage(plr, C.REMOVED_BALANCE, plotworld.MERGE_PRICE + ""); + } + MainUtil.sendMessage(plr, C.SUCCESS_MERGE); + } + }); + } + if (isOnline == false) { + MainUtil.sendMessage(plr, C.NO_AVAILABLE_AUTOMERGE); + return false; + } + MainUtil.sendMessage(plr, C.MERGE_REQUESTED); return true; } } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Move.java b/src/main/java/com/intellectualcrafters/plot/commands/Move.java index d4bacfb05..97d9b3e37 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Move.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Move.java @@ -41,40 +41,26 @@ public class Move extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { - final Location loc = plr.getLocation(); - final Plot plot1 = MainUtil.getPlot(loc); + final Plot plot1 = MainUtil.getPlotAbs(loc); if (plot1 == null) { - return !sendMessage(plr, C.NOT_IN_PLOT); + return !MainUtil.sendMessage(plr, C.NOT_IN_PLOT); } - if (!plot1.isAdded(plr.getUUID()) && !Permissions.hasPermission(plr, C.PERMISSION_ADMIN.s())) { + if (!plot1.isOwner(plr.getUUID()) && !Permissions.hasPermission(plr, C.PERMISSION_ADMIN.s())) { MainUtil.sendMessage(plr, C.NO_PLOT_PERMS); return false; } - final String world = loc.getWorld(); - final PlotId plot2id = MainUtil.parseId(args[0]); - if ((plot2id == null)) { - MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID); - MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot move "); + final Plot plot2 = MainUtil.getPlotFromString(plr, args[0], true); + if ((plot2 == null)) { return false; } - String world2; - if (args.length == 2) { - final PlotWorld other = PS.get().getPlotWorld(args[1]); - final PlotWorld current = PS.get().getPlotWorld(loc.getWorld()); - if ((other == null) || (current == null) || !other.equals(current)) { - MainUtil.sendMessage(plr, C.PLOTWORLD_INCOMPATIBLE); - return false; - } - world2 = other.worldname; - } else { - world2 = world; - } - final Plot plot2 = MainUtil.getPlot(world2, plot2id); - if (plot1.equals(plot2)) { MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID); - MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot move "); + MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot copy "); + return false; + } + if (!plot1.getWorld().equals(plot2.getWorld())) { + C.PLOTWORLD_INCOMPATIBLE.send(plr); return false; } if (MainUtil.move(plot1, plot2, new Runnable() { @@ -82,11 +68,12 @@ public class Move extends SubCommand { public void run() { MainUtil.sendMessage(plr, C.MOVE_SUCCESS); } - })) { + }, false)) { return true; } else { MainUtil.sendMessage(plr, C.REQUIRES_UNOWNED); return false; } } + } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/MusicSubcommand.java b/src/main/java/com/intellectualcrafters/plot/commands/MusicSubcommand.java index 69de9a966..95f72784d 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/MusicSubcommand.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/MusicSubcommand.java @@ -39,7 +39,7 @@ public class MusicSubcommand extends SubCommand { @Override public boolean onCommand(final PlotPlayer player, final String[] args) { final Location loc = player.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(player, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Purge.java b/src/main/java/com/intellectualcrafters/plot/commands/Purge.java index 5636e4b2a..a5bf5f8d8 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Purge.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Purge.java @@ -93,7 +93,7 @@ public class Purge extends SubCommand { final PlotId id = getId(arg); if (id != null) { final HashSet ids = new HashSet(); - final int DBid = DBFunc.getId(MainUtil.getPlot(worldname, id)); + final int DBid = DBFunc.getId(MainUtil.getPlotAbs(worldname, id)); if (DBid != Integer.MAX_VALUE) { ids.add(DBid); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Rate.java b/src/main/java/com/intellectualcrafters/plot/commands/Rate.java index 91440033d..0e8148183 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Rate.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Rate.java @@ -82,7 +82,7 @@ public class Rate extends SubCommand { }); final UUID uuid = player.getUUID(); for (final Plot p : plots) { - if ((!Settings.REQUIRE_DONE || p.getSettings().flags.containsKey("done")) + if ((!Settings.REQUIRE_DONE || p.getFlags().containsKey("done")) && p.isBasePlot() && ((p.getSettings().ratings == null) || !p.getSettings().ratings.containsKey(uuid)) && !p.isAdded(uuid)) { @@ -96,7 +96,7 @@ public class Rate extends SubCommand { } } final Location loc = player.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(player, C.NOT_IN_PLOT); } @@ -108,7 +108,7 @@ public class Rate extends SubCommand { sendMessage(player, C.RATING_NOT_YOUR_OWN); return false; } - if (Settings.REQUIRE_DONE && !plot.getSettings().flags.containsKey("done")) { + if (Settings.REQUIRE_DONE && !plot.getFlags().containsKey("done")) { sendMessage(player, C.RATING_NOT_DONE); return false; } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/RegenAllRoads.java b/src/main/java/com/intellectualcrafters/plot/commands/RegenAllRoads.java index 9ff8e0258..1d2c84e9d 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/RegenAllRoads.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/RegenAllRoads.java @@ -21,6 +21,7 @@ package com.intellectualcrafters.plot.commands; import java.util.List; +import java.util.Set; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; @@ -66,7 +67,7 @@ public class RegenAllRoads extends SubCommand { MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_WORLD); return false; } - final List chunks = ChunkManager.manager.getChunkChunks(name); + final Set chunks = ChunkManager.manager.getChunkChunks(name); MainUtil.sendMessage(plr, "&cIf no schematic is set, the following will not do anything"); MainUtil.sendMessage(plr, "&7 - To set a schematic, stand in a plot and use &c/plot createroadschematic"); MainUtil.sendMessage(plr, "&6Potential chunks to update: &7" + (chunks.size() * 1024)); diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Remove.java b/src/main/java/com/intellectualcrafters/plot/commands/Remove.java index 1022de28c..d74296187 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Remove.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Remove.java @@ -56,7 +56,7 @@ public class Remove extends SubCommand { return true; } final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Save.java b/src/main/java/com/intellectualcrafters/plot/commands/Save.java index b72b06d59..ad21d2737 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Save.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Save.java @@ -8,6 +8,7 @@ import com.intellectualcrafters.jnbt.CompoundTag; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.Settings; +import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotPlayer; @@ -32,7 +33,7 @@ public class Save extends SubCommand { if (!PS.get().isPlotWorld(world)) { return !sendMessage(plr, C.NOT_IN_PLOT_WORLD); } - final Plot plot = MainUtil.getPlot(plr.getLocation()); + final Plot plot = MainUtil.getPlotAbs(plr.getLocation()); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -44,7 +45,7 @@ public class Save extends SubCommand { MainUtil.sendMessage(plr, C.NO_PLOT_PERMS); return false; } - if (MainUtil.runners.containsKey(plot)) { + if (plot.getRunning() > 0) { MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); return false; } @@ -57,7 +58,8 @@ public class Save extends SubCommand { public void run() { final String time = (System.currentTimeMillis() / 1000) + ""; final String name = PS.get().IMP.getServerName().replaceAll("[^A-Za-z0-9]", ""); - final int size = (plot.getTop().getX() - plot.getBottom().getX()) + 1; + Location[] corners = MainUtil.getCorners(plot); + final int size = (corners[1].getX() - corners[0].getX()) + 1; final PlotId id = plot.id; final String world = plot.world.replaceAll("[^A-Za-z0-9]", ""); final String file = time + "_" + world + "_" + id.x + "_" + id.y + "_" + size + "_" + name; diff --git a/src/main/java/com/intellectualcrafters/plot/commands/SchematicCmd.java b/src/main/java/com/intellectualcrafters/plot/commands/SchematicCmd.java index 77bd5ad1e..ff60d1fc8 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/SchematicCmd.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/SchematicCmd.java @@ -40,8 +40,6 @@ import com.intellectualcrafters.plot.util.SchematicHandler.Schematic; import com.intellectualcrafters.plot.util.TaskManager; import com.plotsquared.general.commands.CommandDeclaration; -// TODO Add sub-subcommands - @CommandDeclaration( command = "schematic", permission = "plots.schematic", @@ -73,7 +71,7 @@ public class SchematicCmd extends SubCommand { break; } final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -130,37 +128,38 @@ public class SchematicCmd extends SubCommand { }); break; } - case "test": { - if (!Permissions.hasPermission(plr, "plots.schematic.test")) { - MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.schematic.test"); - return false; - } - if (args.length < 2) { - sendMessage(plr, C.SCHEMATIC_MISSING_ARG); - return false; - } - final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); - if (plot == null) { - sendMessage(plr, C.NOT_IN_PLOT); - return false; - } - file = args[1]; - schematic = SchematicHandler.manager.getSchematic(file); - if (schematic == null) { - sendMessage(plr, C.SCHEMATIC_INVALID, "non-existent"); - return false; - } - final int l1 = schematic.getSchematicDimension().getX(); - final int l2 = schematic.getSchematicDimension().getZ(); - final int length = MainUtil.getPlotWidth(loc.getWorld(), plot.id); - if ((l1 < length) || (l2 < length)) { - sendMessage(plr, C.SCHEMATIC_INVALID, String.format("Wrong size (x: %s, z: %d) vs %d ", l1, l2, length)); - break; - } - sendMessage(plr, C.SCHEMATIC_VALID); - break; - } +// TODO test +// case "test": { +// if (!Permissions.hasPermission(plr, "plots.schematic.test")) { +// MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.schematic.test"); +// return false; +// } +// if (args.length < 2) { +// sendMessage(plr, C.SCHEMATIC_MISSING_ARG); +// return false; +// } +// final Location loc = plr.getLocation(); +// final Plot plot = MainUtil.getPlot(loc); +// if (plot == null) { +// sendMessage(plr, C.NOT_IN_PLOT); +// return false; +// } +// file = args[1]; +// schematic = SchematicHandler.manager.getSchematic(file); +// if (schematic == null) { +// sendMessage(plr, C.SCHEMATIC_INVALID, "non-existent"); +// return false; +// } +// final int l1 = schematic.getSchematicDimension().getX(); +// final int l2 = schematic.getSchematicDimension().getZ(); +// final int length = MainUtil.getPlotWidth(loc.getWorld(), plot.id); +// if ((l1 < length) || (l2 < length)) { +// sendMessage(plr, C.SCHEMATIC_INVALID, String.format("Wrong size (x: %s, z: %d) vs %d ", l1, l2, length)); +// break; +// } +// sendMessage(plr, C.SCHEMATIC_VALID); +// break; +// } case "saveall": case "exportall": { if (!ConsolePlayer.isConsole(plr)) { @@ -203,7 +202,7 @@ public class SchematicCmd extends SubCommand { } final Plot p2; final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Set.java b/src/main/java/com/intellectualcrafters/plot/commands/Set.java index 5db19f04b..61e9ceeb0 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Set.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Set.java @@ -47,7 +47,6 @@ import com.intellectualcrafters.plot.util.StringMan; import com.intellectualcrafters.plot.util.UUIDHandler; import com.plotsquared.general.commands.CommandDeclaration; -// TODO Make sub-subcommands @CommandDeclaration( command = "set", description = "Set a plot value", @@ -62,9 +61,8 @@ public class Set extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String... args) { - final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } @@ -93,7 +91,7 @@ public class Set extends SubCommand { } } if (args[0].equalsIgnoreCase("flag")) { - List arglist = Arrays.asList("flag", "set"); + List arglist = new ArrayList<>(Arrays.asList("flag", "set")); for (String arg : Arrays.copyOfRange(args, 1, args.length)) { arglist.add(arg); } @@ -113,7 +111,7 @@ public class Set extends SubCommand { } //set to current location final String world = plr.getLocation().getWorld(); - final Location base = MainUtil.getPlotBottomLoc(world, plot.id); + final Location base = MainUtil.getPlotBottomLocAbs(world, plot.id).subtract(1, 0, 1); base.setY(0); final Location relative = plr.getLocation().subtract(base.getX(), base.getY(), base.getZ()); final BlockLoc blockloc = new BlockLoc(relative.getX(), relative.getY(), relative.getZ(), relative.getYaw(), relative.getPitch()); @@ -159,7 +157,7 @@ public class Set extends SubCommand { return false; } for (final Plot p : PS.get().getPlotsInWorld(plr.getLocation().getWorld())) { - if (p.getSettings().getAlias().equalsIgnoreCase(alias)) { + if (p.getAlias().equalsIgnoreCase(alias)) { MainUtil.sendMessage(plr, C.ALIAS_IS_TAKEN); return false; } @@ -179,26 +177,26 @@ public class Set extends SubCommand { } if (args.length < 2) { MainUtil.sendMessage(plr, C.NEED_BIOME); - return true; + return false; } if (args[1].length() < 2) { sendMessage(plr, C.NAME_LITTLE, "Biome", args[1].length() + "", "2"); - return true; + return false; } final int biome = BlockManager.manager.getBiomeFromString(args[1]); if (biome == -1) { MainUtil.sendMessage(plr, getBiomeList(BlockManager.manager.getBiomeList())); - return true; + return false; } - if (MainUtil.runners.containsKey(plot)) { + if (plot.getRunning() > 0) { MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); return false; } - MainUtil.runners.put(plot, 1); + plot.addRunning(); plot.setBiome(args[1].toUpperCase(), new Runnable() { @Override public void run() { - MainUtil.runners.remove(plot); + plot.removeRunning(); MainUtil.sendMessage(plr, C.BIOME_SET_TO.s() + args[1].toLowerCase()); } }); @@ -265,17 +263,19 @@ public class Set extends SubCommand { MainUtil.sendMessage(plr, C.NOT_VALID_BLOCK, args[1]); return false; } - if (MainUtil.runners.containsKey(plot)) { + if (plot.getRunning() > 0) { MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER); return false; } - MainUtil.runners.put(plot, 1); - manager.setComponent(plotworld, plot.id, component, blocks); + plot.addRunning(); + for (Plot current : MainUtil.getConnectedPlots(plot)) { + manager.setComponent(plotworld, current.id, component, blocks); + } MainUtil.sendMessage(plr, C.GENERATING_COMPONENT); SetBlockQueue.addNotify(new Runnable() { @Override public void run() { - MainUtil.runners.remove(plot); + plot.removeRunning(); } }); return true; diff --git a/src/main/java/com/intellectualcrafters/plot/commands/SetOwner.java b/src/main/java/com/intellectualcrafters/plot/commands/SetOwner.java index 9c3425c3e..0f62ed5c4 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/SetOwner.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/SetOwner.java @@ -21,6 +21,7 @@ package com.intellectualcrafters.plot.commands; import java.util.ArrayList; +import java.util.HashSet; import java.util.UUID; import com.intellectualcrafters.plot.PS; @@ -58,7 +59,7 @@ public class SetOwner extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if ((plot == null) || ((plot.owner == null) && !Permissions.hasPermission(plr, "plots.admin.command.setowner"))) { MainUtil.sendMessage(plr, C.NOT_IN_PLOT); return false; @@ -67,14 +68,11 @@ public class SetOwner extends SubCommand { MainUtil.sendMessage(plr, C.NEED_USER); return false; } - - final PlotId bot = MainUtil.getBottomPlot(plot).id; - final PlotId top = MainUtil.getTopPlot(plot).id; - final ArrayList plots = MainUtil.getPlotSelectionIds(bot, top); - + HashSet plots = MainUtil.getConnectedPlots(plot); + UUID uuid = UUIDHandler.getUUID(args[0], null); final PlotPlayer other = UUIDHandler.getPlayer(args[0]); if (other == null) { - if (!Permissions.hasPermission(plr, "plots.admin.command.setowner")) { + if (uuid == null || !Permissions.hasPermission(plr, "plots.admin.command.setowner")) { MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[0]); return false; } @@ -88,32 +86,13 @@ public class SetOwner extends SubCommand { } } } - if (!plot.isOwner(plr.getUUID())) { if (!Permissions.hasPermission(plr, "plots.admin.command.setowner")) { MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.admin.command.setowner"); return false; } } - - final String world = loc.getWorld(); - final UUID uuid = getUUID(args[0]); - if (uuid == null) { - MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[0]); - return false; - } - for (final PlotId id : plots) { - Plot current = PS.get().getPlot(world, id); - if (current == null) { - current = MainUtil.getPlot(world, id); - current.owner = uuid; - current.create(); - } else { - current.owner = uuid; - DBFunc.setOwner(current, current.owner); - } - PS.get().updatePlot(current); - } + plot.setOwner(uuid); MainUtil.setSign(args[0], plot); MainUtil.sendMessage(plr, C.SET_OWNER); if (other != null) { diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Swap.java b/src/main/java/com/intellectualcrafters/plot/commands/Swap.java index 5e6e1d8d1..cef1bcbfe 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Swap.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Swap.java @@ -40,91 +40,38 @@ public class Swap extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { - - MainUtil.sendMessage(plr, "&cThis command has not been optimized for large selections yet. Please bug me if this becomes an issue."); - if (args.length < 1) { - MainUtil.sendMessage(plr, C.NEED_PLOT_ID); - MainUtil.sendMessage(plr, C.SWAP_SYNTAX); - return false; - } final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); - if (plot == null) { - return !sendMessage(plr, C.NOT_IN_PLOT); + final Plot plot1 = MainUtil.getPlotAbs(loc); + if (plot1 == null) { + return !MainUtil.sendMessage(plr, C.NOT_IN_PLOT); } - if ((!plot.hasOwner() || !plot.isOwner(plr.getUUID())) && !Permissions.hasPermission(plr, "plots.admin.command.swap")) { + if (!plot1.isOwner(plr.getUUID()) && !Permissions.hasPermission(plr, C.PERMISSION_ADMIN.s())) { MainUtil.sendMessage(plr, C.NO_PLOT_PERMS); return false; } - - final Plot bot1 = MainUtil.getBottomPlot(plot); - final Plot top1 = MainUtil.getTopPlot(plot); - - final PlotId id2 = PlotId.fromString(args[0]); - if (id2 == null) { - MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID); - MainUtil.sendMessage(plr, C.SWAP_SYNTAX); + final Plot plot2 = MainUtil.getPlotFromString(plr, args[0], true); + if ((plot2 == null)) { return false; } - final String world = loc.getWorld(); - final Plot plot2 = MainUtil.getPlot(world, id2); - final PlotId id3 = new PlotId((id2.x + top1.id.x) - bot1.id.x, (id2.y + top1.id.y) - bot1.id.y); - final Plot plot3 = MainUtil.getPlot(world, id3); - - // Getting secon selection - final Plot bot2 = MainUtil.getBottomPlot(plot2); - final Plot top2 = MainUtil.getTopPlot(plot3); - - // cancel swap if intersection - final PlotCluster cluster1 = new PlotCluster(world, bot1.id, top1.id, null); - final PlotClusterId cluster2id = new PlotClusterId(bot2.id, top2.id); - if (ClusterManager.intersects(cluster1, cluster2id)) { + if (plot1.equals(plot2)) { + MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID); + MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot copy "); + return false; + } + if (!plot1.getWorld().equals(plot2.getWorld())) { + C.PLOTWORLD_INCOMPATIBLE.send(plr); + return false; + } + if (MainUtil.move(plot1, plot2, new Runnable() { + @Override + public void run() { + MainUtil.sendMessage(plr, C.SWAP_SUCCESS); + } + }, true)) { + return true; + } else { MainUtil.sendMessage(plr, C.SWAP_OVERLAP); return false; } - - // Check dimensions - if (((top1.id.x - bot1.id.x) != (top2.id.x - bot2.id.x)) || ((top1.id.y - bot1.id.y) != (top2.id.y - bot2.id.y))) { - MainUtil.sendMessage(plr, C.SWAP_DIMENSIONS, "1"); - MainUtil.sendMessage(plr, C.SWAP_SYNTAX); - return false; - } - - // Getting selections as ids - final ArrayList selection1 = MainUtil.getPlotSelectionIds(bot1.id, top1.id); - final ArrayList selection2 = MainUtil.getPlotSelectionIds(bot2.id, top2.id); - - // Getting selections as location coordinates - final Location pos1 = MainUtil.getPlotBottomLocAbs(world, bot1.id); - final Location pos2 = MainUtil.getPlotTopLocAbs(world, top1.id).subtract(1, 0, 1); - final Location pos3 = MainUtil.getPlotBottomLocAbs(world, bot2.id); - final Location pos4 = MainUtil.getPlotTopLocAbs(world, top2.id).subtract(1, 0, 1); - - if (MainUtil.getPlot(pos2) != null) { - pos1.add(1, 0, 1); - pos2.add(1, 0, 1); - pos3.add(1, 0, 1); - pos4.add(1, 0, 1); - } - - // Swapping the blocks, states and entites - ChunkManager.manager.swap(world, pos1, pos2, pos3, pos4); - - // Swapping the plot data - for (int i = 0; i < selection1.size(); i++) { - final boolean last = i == (selection1.size() - 1); - final PlotId swaper = selection1.get(i); - final PlotId swapee = selection2.get(i); - MainUtil.swapData(world, swaper, swapee, new Runnable() { - @Override - public void run() { - if (last) { - MainUtil.sendMessage(plr, C.SWAP_SUCCESS); - } - } - }); - } - MainUtil.sendMessage(plr, C.STARTED_SWAP); - return true; } } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/TP.java b/src/main/java/com/intellectualcrafters/plot/commands/TP.java index 72557396c..bd35c6e4e 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/TP.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/TP.java @@ -63,7 +63,7 @@ public class TP extends SubCommand { } try { plotid = new PlotId(Integer.parseInt(id.split(";")[0]), Integer.parseInt(id.split(";")[1])); - MainUtil.teleportPlayer(plr, plr.getLocation(), MainUtil.getPlot(world, plotid)); + MainUtil.teleportPlayer(plr, plr.getLocation(), MainUtil.getPlotAbs(world, plotid)); return true; } catch (final Exception e) { MainUtil.sendMessage(plr, C.NOT_VALID_PLOT_ID); @@ -90,7 +90,7 @@ public class TP extends SubCommand { return null; } for (final Plot p : PS.get().getPlotsInWorld(world)) { - if ((p.getSettings().getAlias().length() > 0) && p.getSettings().getAlias().equalsIgnoreCase(a)) { + if ((p.getAlias().length() > 0) && p.getAlias().equalsIgnoreCase(a)) { return p; } } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Target.java b/src/main/java/com/intellectualcrafters/plot/commands/Target.java index 37a9e7c33..78e482786 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Target.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Target.java @@ -52,7 +52,7 @@ public class Target extends SubCommand { Plot closest = null; int distance = Integer.MAX_VALUE; for (final Plot plot : PS.get().getPlotsInWorld(ploc.getWorld())) { - final double current = plot.getBottom().getEuclideanDistanceSquared(ploc); + final double current = plot.getBottomAbs().getEuclideanDistanceSquared(ploc); if (current < distance) { distance = (int) current; closest = plot; diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Trim.java b/src/main/java/com/intellectualcrafters/plot/commands/Trim.java index 45c15d9c2..21fd15867 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Trim.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Trim.java @@ -133,8 +133,8 @@ public class Trim extends SubCommand { } final Plot plot = plots.remove(0); - final Location pos1 = MainUtil.getPlotBottomLoc(world, plot.id); - final Location pos2 = MainUtil.getPlotTopLoc(world, plot.id); + final Location pos1 = MainUtil.getPlotBottomLocAbs(world, plot.id); + final Location pos2 = MainUtil.getPlotTopLocAbs(world, plot.id); final int ccx1 = (pos1.getX() >> 9); final int ccz1 = (pos1.getZ() >> 9); @@ -204,7 +204,7 @@ public class Trim extends SubCommand { sendMessage(C.TRIM_IN_PROGRESS.s()); return false; } - sendMessage(C.TRIM_START.s()); + sendMessage(C.TASK_START.s()); final ArrayList empty = new ArrayList<>(); getTrimRegions(empty, world, new Runnable() { public void run() { diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Trust.java b/src/main/java/com/intellectualcrafters/plot/commands/Trust.java index b11e954e8..5bb022371 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Trust.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Trust.java @@ -53,7 +53,7 @@ public class Trust extends SubCommand { public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Unclaim.java b/src/main/java/com/intellectualcrafters/plot/commands/Unclaim.java index 10d203f87..8732ff782 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Unclaim.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Unclaim.java @@ -31,33 +31,25 @@ import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.Permissions; import com.plotsquared.general.commands.CommandDeclaration; -@CommandDeclaration(command = "unclaim", usage = "/plot unclaim", requiredType = RequiredType.NONE, description = "Unclaim a plot", category = CommandCategory.ACTIONS) +/** + * Unclaiming a plot makes no changes to the terrain or plot border and only removes the owner and should be regarded as an admin command. + */ +@CommandDeclaration(command = "unclaim", usage = "/plot unclaim", requiredType = RequiredType.NONE, description = "Unclaim a plot (admin command)", category = CommandCategory.ACTIONS) public class Unclaim extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } if (!plot.hasOwner()) { return !sendMessage(plr, C.PLOT_NOT_CLAIMED); } - if (!MainUtil.getTopPlot(plot).equals(MainUtil.getBottomPlot(plot))) { - return !sendMessage(plr, C.UNLINK_REQUIRED); - } if (((!plot.hasOwner() || !plot.isOwner(plr.getUUID()))) && !Permissions.hasPermission(plr, "plots.admin.command.unclaim")) { return !sendMessage(plr, C.NO_PLOT_PERMS); } - final PlotWorld pWorld = PS.get().getPlotWorld(plot.world); - if ((EconHandler.manager != null) && pWorld.USE_ECONOMY) { - final double c = pWorld.SELL_PRICE; - if (c > 0d) { - EconHandler.manager.depositMoney(plr, c); - sendMessage(plr, C.ADDED_BALANCE, c + ""); - } - } if (plot.unclaim()) { MainUtil.sendMessage(plr, C.UNCLAIM_SUCCESS); } else { diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Undeny.java b/src/main/java/com/intellectualcrafters/plot/commands/Undeny.java index 09719a7b4..c8ca206a1 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Undeny.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Undeny.java @@ -51,7 +51,7 @@ public class Undeny extends SubCommand { public boolean onCommand(final PlotPlayer plr, final String... args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Unlink.java b/src/main/java/com/intellectualcrafters/plot/commands/Unlink.java index 8257d4bfe..f7a5c031d 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Unlink.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Unlink.java @@ -38,20 +38,23 @@ public class Unlink extends SubCommand { public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } - if ((!plot.hasOwner() || !plot.isOwner(plr.getUUID())) && !Permissions.hasPermission(plr, "plots.admin.command.unlink")) { + if (!plot.hasOwner()) { + return !sendMessage(plr, C.PLOT_UNOWNED); + } + if (!plot.isOwner(plr.getUUID()) && !Permissions.hasPermission(plr, "plots.admin.command.unlink")) { return sendMessage(plr, C.NO_PLOT_PERMS); } - if (MainUtil.getTopPlot(plot).equals(MainUtil.getBottomPlot(plot))) { + if (!plot.isMerged()) { return sendMessage(plr, C.UNLINK_IMPOSSIBLE); } final Runnable runnable = new Runnable() { @Override public void run() { - if (!MainUtil.unlinkPlot(plot, true)) { + if (!MainUtil.unlinkPlot(plot, true, true)) { MainUtil.sendMessage(plr, "&cUnlink has been cancelled"); return; } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/Untrust.java b/src/main/java/com/intellectualcrafters/plot/commands/Untrust.java index 3b0357f67..83e7c08d2 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/Untrust.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/Untrust.java @@ -52,7 +52,7 @@ public class Untrust extends SubCommand { @Override public boolean onCommand(final PlotPlayer plr, final String[] args) { final Location loc = plr.getLocation(); - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot == null) { return !sendMessage(plr, C.NOT_IN_PLOT); } diff --git a/src/main/java/com/intellectualcrafters/plot/commands/list.java b/src/main/java/com/intellectualcrafters/plot/commands/list.java index 30425adef..b031ba780 100644 --- a/src/main/java/com/intellectualcrafters/plot/commands/list.java +++ b/src/main/java/com/intellectualcrafters/plot/commands/list.java @@ -23,6 +23,7 @@ package com.intellectualcrafters.plot.commands; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.UUID; @@ -170,7 +171,7 @@ public class list extends SubCommand { match = null; } for (final Plot plot : PS.get().getPlots()) { - final Flag flag = plot.getSettings().flags.get("done"); + final Flag flag = plot.getFlags().get("done"); if (flag == null) { continue; } @@ -189,8 +190,8 @@ public class list extends SubCommand { Collections.sort(plots, new Comparator() { @Override public int compare(final Plot a, final Plot b) { - final String va = a.getSettings().flags.get("done").getValueString(); - final String vb = b.getSettings().flags.get("done").getValueString(); + final String va = a.getFlags().get("done").getValueString(); + final String vb = b.getFlags().get("done").getValueString(); if (MathMan.isInteger(va)) { if (MathMan.isInteger(vb)) { return Integer.parseInt(vb) - Integer.parseInt(va); @@ -332,6 +333,13 @@ public class list extends SubCommand { } public void displayPlots(final PlotPlayer player, List plots, final int pageSize, int page, final String world, final String[] args, final boolean sort) { + int rawSize = plots.size(); + Iterator iter = plots.iterator(); + while (iter.hasNext()) { + if (!iter.next().isBasePlot()) { + iter.remove(); + } + } if (sort) { plots = PS.get().sortPlots(plots, SortType.DISTANCE_FROM_ORIGIN, world); } @@ -351,17 +359,12 @@ public class list extends SubCommand { final List subList = plots.subList(page * pageSize, max); // Header - final String header = C.PLOT_LIST_HEADER_PAGED.s().replaceAll("%cur", page + 1 + "").replaceAll("%max", totalPages + 1 + "").replaceAll("%amount%", plots.size() + "") + final String header = C.PLOT_LIST_HEADER_PAGED.s().replaceAll("%cur", page + 1 + "").replaceAll("%max", totalPages + 1 + "").replaceAll("%amount%", plots.size() + "/" + rawSize) .replaceAll("%word%", "all"); MainUtil.sendMessage(player, header); int i = page * pageSize; for (final Plot plot : subList) { - if (plot.getSettings().isMerged()) { - if (!MainUtil.getBottomPlot(plot).equals(plot)) { - continue; - } - } i++; String color; if (plot.owner == null) { @@ -379,7 +382,7 @@ public class list extends SubCommand { final PlotMessage members = new PlotMessage().text(C.color(C.PLOT_INFO_MEMBERS.s().replaceAll("%members%", Info.getPlayerList(plot.getMembers())))).color("$1"); - String strFlags = StringMan.join(plot.getSettings().flags.values(), ","); + String strFlags = StringMan.join(plot.getFlags().values(), ","); if (strFlags.length() == 0) { strFlags = C.NONE.s(); } diff --git a/src/main/java/com/intellectualcrafters/plot/config/C.java b/src/main/java/com/intellectualcrafters/plot/config/C.java index c431ac7af..5ea8a5ce0 100644 --- a/src/main/java/com/intellectualcrafters/plot/config/C.java +++ b/src/main/java/com/intellectualcrafters/plot/config/C.java @@ -283,6 +283,7 @@ public enum C { /* * Core Stuff */ + TASK_START("Starting task...", "Core"), PREFIX("$3[$1P2$3] $2", "Core"), ENABLED("$1PlotSquared is now enabled", "Core"), EXAMPLE_MESSAGE("$2This is an example message &k!!!", "Core"), @@ -328,16 +329,20 @@ public enum C { CANT_TRANSFER_MORE_PLOTS("$2You can't send more plots to that user", "Permission"), CANT_CLAIM_MORE_PLOTS_NUM("$2You can't claim more than $1%s $2plots at once", "Permission"), YOU_BE_DENIED("$2You are not allowed to enter this plot", "Permission"), - NO_PERM_MERGE("$2You are not the owner of the plot: $1%plot%", "Permission"), - UNLINK_REQUIRED("$2An unlink is required to do this.", "Permission"), - UNLINK_IMPOSSIBLE("$2You can only unlink a mega-plot", "Permission"), - UNLINK_SUCCESS("$2Successfully unlinked plots.", "Permission"), - NO_MERGE_TO_MEGA("$2Mega plots cannot be merged into. Please merge from the desired mega plot.", "Permission"), - MERGE_NOT_VALID("$2This merge request is no longer valid.", "Permission"), - MERGE_ACCEPTED("$2The merge request has been accepted", "Permission"), - SUCCESS_MERGE("$2Plots have been merged!", "Permission"), - MERGE_REQUESTED("$2Successfully sent a merge request", "Permission"), + + /* + * Merge + */ + MERGE_NOT_VALID("$2This merge request is no longer valid.", "Merge"), + MERGE_ACCEPTED("$2The merge request has been accepted", "Merge"), + SUCCESS_MERGE("$2Plots have been merged!", "Merge"), + MERGE_REQUESTED("$2Successfully sent a merge request", "Merge"), MERGE_REQUEST_CONFIRM("merge request from %s", "Permission"), + NO_PERM_MERGE("$2You are not the owner of the plot: $1%plot%", "Merge"), + NO_AVAILABLE_AUTOMERGE("$2You do not own any adjacent plots in the specified direction.", "Merge"), + UNLINK_REQUIRED("$2An unlink is required to do this.", "Merge"), + UNLINK_IMPOSSIBLE("$2You can only unlink a mega-plot", "Merge"), + UNLINK_SUCCESS("$2Successfully unlinked plots.", "Merge"), /* * Commands */ @@ -368,7 +373,6 @@ public enum C { * trim */ TRIM_SYNTAX("Use /plot trim ", "Trim"), - TRIM_START("Starting a world trim task...", "Trim"), TRIM_IN_PROGRESS("A world trim task is already in progress!", "Trim"), NOT_VALID_HYBRID_PLOT_WORLD("The hybrid plot manager is required to perform this action", "Trim"), /* diff --git a/src/main/java/com/intellectualcrafters/plot/config/Settings.java b/src/main/java/com/intellectualcrafters/plot/config/Settings.java index 1b2118b8d..c30449535 100644 --- a/src/main/java/com/intellectualcrafters/plot/config/Settings.java +++ b/src/main/java/com/intellectualcrafters/plot/config/Settings.java @@ -212,10 +212,7 @@ public class Settings { /** * MongoDB enabled? */ - public static boolean USE_MONGO = false; /* - * TODO: Implement Mongo - * @Brandon - */ + public static boolean USE_MONGO = false; /** * SQLite enabled? */ diff --git a/src/main/java/com/intellectualcrafters/plot/database/DBFunc.java b/src/main/java/com/intellectualcrafters/plot/database/DBFunc.java index 8f3c0ce7f..796d16172 100644 --- a/src/main/java/com/intellectualcrafters/plot/database/DBFunc.java +++ b/src/main/java/com/intellectualcrafters/plot/database/DBFunc.java @@ -151,6 +151,7 @@ public class DBFunc { return; } dbManager.delete(plot); + plot.temp = -1; } public static void delete(final PlotCluster toDelete) { @@ -399,7 +400,7 @@ public class DBFunc { public static HashMap getRatings(final Plot plot) { if (plot.temp == -1) { - return new HashMap<>(); + return new HashMap<>(0); } return dbManager.getRatings(plot); } diff --git a/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java b/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java index 817b2c196..c2608fbbc 100644 --- a/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java +++ b/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java @@ -763,11 +763,8 @@ public class SQLManager implements AbstractDB { stmt.setString((i * 10) + 8, flag_string.toString()); } final boolean[] merged = pair.settings.getMerged(); - int n = 0; - for (int j = 0; j < 4; ++j) { - n = (n << 1) + (merged[j] ? 1 : 0); - } - stmt.setInt((i * 10) + 9, n); + int hash = MainUtil.hash(merged); + stmt.setInt((i * 10) + 9, hash); final BlockLoc loc = pair.settings.getPosition(); String position; if (loc.y == 0) { @@ -1311,9 +1308,6 @@ public class SQLManager implements AbstractDB { } public void updateTables() { - - // TODO task - if (PS.get().getVersion().equals(PS.get().getLastVersion()) || (PS.get().getLastVersion() == null)) { return; } @@ -1646,11 +1640,8 @@ public class SQLManager implements AbstractDB { addPlotTask(plot, new UniqueStatement("setMerged") { @Override public void set(final PreparedStatement stmt) throws SQLException { - int n = 0; - for (int i = 0; i < 4; ++i) { - n = (n << 1) + (merged[i] ? 1 : 0); - } - stmt.setInt(1, n); + int hash = MainUtil.hash(merged); + stmt.setInt(1, hash); stmt.setInt(2, getId(plot)); } @@ -1702,12 +1693,13 @@ public class SQLManager implements AbstractDB { public void set(final PreparedStatement stmt) throws SQLException { stmt.setInt(1, newPlot.id.x); stmt.setInt(2, newPlot.id.y); - stmt.setInt(3, getId(original)); + stmt.setString(3, newPlot.world); + stmt.setInt(4, getId(original)); } @Override public PreparedStatement get() throws SQLException { - return connection.prepareStatement("UPDATE `" + prefix + "plot` SET `plot_id_x` = ?, `plot_id_z` = ? WHERE `id` = ?"); + return connection.prepareStatement("UPDATE `" + prefix + "plot` SET `plot_id_x` = ?, `plot_id_z` = ?, `world` = ? WHERE `id` = ?"); } }); addPlotTask(newPlot, null); diff --git a/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java b/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java index f63a2a9e1..f6e075f07 100644 --- a/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java +++ b/src/main/java/com/intellectualcrafters/plot/flag/FlagManager.java @@ -45,10 +45,6 @@ import com.intellectualcrafters.plot.util.Permissions; */ @SuppressWarnings("unused") public class FlagManager { - // TODO add some flags - // - Plot clear interval - // - Mob cap - // - customized plot composition private final static HashSet reserved = new HashSet<>(); @@ -108,7 +104,7 @@ public class FlagManager { } if (PS.get().getAllPlotsRaw() != null) { for (final Plot plot : PS.get().getPlotsRaw()) { - final Flag flag = plot.getSettings().flags.get(af.getKey()); + final Flag flag = plot.getFlags().get(af.getKey()); if (flag != null) { flag.setKey(af); } @@ -204,14 +200,16 @@ public class FlagManager { * @param plot * @param flag */ - public static boolean addPlotFlag(final Plot plot, final Flag flag) { - final boolean result = EventUtil.manager.callFlagAdd(flag, plot); + public static boolean addPlotFlag(final Plot origin, final Flag flag) { + final boolean result = EventUtil.manager.callFlagAdd(flag, origin); if (!result) { return false; } - plot.getSettings().flags.put(flag.getKey(), flag); - MainUtil.reEnterPlot(plot); - DBFunc.setFlags(plot, plot.getSettings().flags.values()); + for (Plot plot : MainUtil.getConnectedPlots(origin)) { + plot.getFlags().put(flag.getKey(), flag); + MainUtil.reEnterPlot(plot); + DBFunc.setFlags(plot, plot.getFlags().values()); + } return true; } @@ -220,7 +218,7 @@ public class FlagManager { if (!result) { return false; } - plot.getSettings().flags.put(flag.getKey(), flag); + plot.getFlags().put(flag.getKey(), flag); return true; } @@ -270,17 +268,17 @@ public class FlagManager { } public static boolean removePlotFlag(final Plot plot, final String id) { - final Flag flag = plot.getSettings().flags.remove(id); + final Flag flag = plot.getFlags().remove(id); if (flag == null) { return false; } final boolean result = EventUtil.manager.callFlagRemove(flag, plot); if (!result) { - plot.getSettings().flags.put(id, flag); + plot.getFlags().put(id, flag); return false; } MainUtil.reEnterPlot(plot); - DBFunc.setFlags(plot, plot.getSettings().flags.values()); + DBFunc.setFlags(plot, plot.getFlags().values()); return true; } @@ -298,19 +296,21 @@ public class FlagManager { return true; } - public static void setPlotFlags(final Plot plot, final Set flags) { - if ((flags != null) && (flags.size() != 0)) { - plot.getSettings().flags.clear(); - for (final Flag flag : flags) { - plot.getSettings().flags.put(flag.getKey(), flag); + public static void setPlotFlags(final Plot origin, final Set flags) { + for (Plot plot : origin.getConnectedPlots()) { + if ((flags != null) && (flags.size() != 0)) { + plot.getFlags().clear(); + for (final Flag flag : flags) { + plot.getFlags().put(flag.getKey(), flag); + } + } else if (plot.getFlags().size() == 0) { + return; + } else { + plot.getFlags().clear(); } - } else if (plot.getSettings().flags.size() == 0) { - return; - } else { - plot.getSettings().flags.clear(); + MainUtil.reEnterPlot(plot); + DBFunc.setFlags(plot, plot.getFlags().values()); } - MainUtil.reEnterPlot(plot); - DBFunc.setFlags(plot, plot.getSettings().flags.values()); } public static void setClusterFlags(final PlotCluster cluster, final Set flags) { diff --git a/src/main/java/com/intellectualcrafters/plot/generator/ClassicPlotManager.java b/src/main/java/com/intellectualcrafters/plot/generator/ClassicPlotManager.java index 196bd5cd6..b5a358d46 100644 --- a/src/main/java/com/intellectualcrafters/plot/generator/ClassicPlotManager.java +++ b/src/main/java/com/intellectualcrafters/plot/generator/ClassicPlotManager.java @@ -8,6 +8,7 @@ import com.intellectualcrafters.plot.object.PlotBlock; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotWorld; import com.intellectualcrafters.plot.object.PseudoRandom; +import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.SetBlockQueue; @@ -26,6 +27,14 @@ public class ClassicPlotManager extends SquarePlotManager { setWallFilling(plotworld, plotid, blocks); return true; } + case "all": { + setAir(plotworld, plotid, blocks); + return true; + } + case "outline": { + setOutline(plotworld, plotid, blocks); + return true; + } case "border": { setWall(plotworld, plotid, blocks); return true; @@ -46,12 +55,81 @@ public class ClassicPlotManager extends SquarePlotManager { } public boolean setFloor(final PlotWorld plotworld, final PlotId plotid, final PlotBlock[] blocks) { + Plot plot = MainUtil.getPlotAbs(plotworld.worldname, plotid); + if (plot.isBasePlot()) { + final ClassicPlotWorld dpw = (ClassicPlotWorld) plotworld; + for (RegionWrapper region : MainUtil.getRegions(plot)) { + Location pos1 = new Location(plot.world, region.minX, dpw.PLOT_HEIGHT, region.minZ); + Location pos2 = new Location(plot.world, region.maxX, dpw.PLOT_HEIGHT, region.maxZ); + MainUtil.setCuboidAsync(plotworld.worldname, pos1, pos2, blocks); + } + } + return true; + } + + public boolean setAir(final PlotWorld plotworld, final PlotId plotid, final PlotBlock[] blocks) { + Plot plot = MainUtil.getPlotAbs(plotworld.worldname, plotid); + if (!plot.isBasePlot()) { + return false; + } final ClassicPlotWorld dpw = (ClassicPlotWorld) plotworld; - final Location pos1 = MainUtil.getPlotBottomLoc(plotworld.worldname, plotid).add(1, 0, 1); - final Location pos2 = MainUtil.getPlotTopLoc(plotworld.worldname, plotid).add(1, 0, 1); - pos1.setY(dpw.PLOT_HEIGHT); - pos2.setY(dpw.PLOT_HEIGHT + 1); - MainUtil.setCuboidAsync(plotworld.worldname, pos1, pos2, blocks); + for (RegionWrapper region : MainUtil.getRegions(plot)) { + Location pos1 = new Location(plot.world, region.minX, dpw.PLOT_HEIGHT + 1, region.minZ); + Location pos2 = new Location(plot.world, region.maxX, 255, region.maxZ); + MainUtil.setCuboidAsync(plotworld.worldname, pos1, pos2, blocks); + } + return true; + } + + public boolean setOutline(final PlotWorld plotworld, final PlotId plotid, final PlotBlock[] blocks) { + final ClassicPlotWorld dpw = (ClassicPlotWorld) plotworld; + if (dpw.ROAD_WIDTH == 0) { + return false; + } + Plot plot = MainUtil.getPlotAbs(plotworld.worldname, plotid); + final Location bottom = MainUtil.getPlotBottomLocAbs(plotworld.worldname, plotid); + final Location top = MainUtil.getPlotTopLoc_(plot); + final PseudoRandom random = new PseudoRandom(); + if (!plot.getMerged(0)) { + int z = bottom.getZ(); + for (int x = bottom.getX(); x <= (top.getX()); x++) { + for (int y = dpw.PLOT_HEIGHT; y <= 255; y++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } + } + } + if (!plot.getMerged(3)) { + int x = bottom.getX(); + for (int z = bottom.getZ(); z <= (top.getZ()); z++) { + for (int y = dpw.PLOT_HEIGHT; y <= 255; y++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } + } + } + + if (!plot.getMerged(2)) { + int z = top.getZ(); + for (int x = bottom.getX(); x <= (top.getX()); x++) { + for (int y = dpw.PLOT_HEIGHT; y <= 255; y++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } + } + } + if (!plot.getMerged(1)) { + int x = top.getX(); + for (int z = bottom.getZ(); z <= (top.getZ()); z++) { + for (int y = dpw.PLOT_HEIGHT; y <= 255; y++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } + } + } + if (plot.isBasePlot()) { + for (RegionWrapper region : MainUtil.getRegions(plot)) { + Location pos1 = new Location(plot.world, region.minX, 255, region.minZ); + Location pos2 = new Location(plot.world, region.maxX, 255, region.maxZ); + MainUtil.setCuboidAsync(plotworld.worldname, pos1, pos2, blocks); + } + } return true; } @@ -60,32 +138,40 @@ public class ClassicPlotManager extends SquarePlotManager { if (dpw.ROAD_WIDTH == 0) { return false; } - final Location bottom = MainUtil.getPlotBottomLoc(plotworld.worldname, plotid); - final Location top = MainUtil.getPlotTopLoc(plotworld.worldname, plotid).add(1, 0, 1); - int x, z; - z = bottom.getZ(); + Plot plot = MainUtil.getPlotAbs(plotworld.worldname, plotid); + final Location bot = MainUtil.getPlotBottomLoc_(plot).subtract(plot.getMerged(3) ? 0 : 1, 0, plot.getMerged(0) ? 0 : 1); + final Location top = MainUtil.getPlotTopLoc_(plot).add(1, 0, 1); final PseudoRandom random = new PseudoRandom(); - for (x = bottom.getX(); x <= (top.getX() - 1); x++) { - for (int y = 1; y <= dpw.WALL_HEIGHT; y++) { - SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + if (!plot.getMerged(0)) { + int z = bot.getZ(); + for (int x = bot.getX(); x < (top.getX()); x++) { + for (int y = 1; y <= dpw.WALL_HEIGHT; y++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } } } - x = top.getX(); - for (z = bottom.getZ(); z <= (top.getZ() - 1); z++) { - for (int y = 1; y <= dpw.WALL_HEIGHT; y++) { - SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + if (!plot.getMerged(3)) { + int x = bot.getX(); + for (int z = bot.getZ(); z < (top.getZ()); z++) { + for (int y = 1; y <= dpw.WALL_HEIGHT; y++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } } } - z = top.getZ(); - for (x = top.getX(); x >= (bottom.getX() + 1); x--) { - for (int y = 1; y <= dpw.WALL_HEIGHT; y++) { - SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + if (!plot.getMerged(2)) { + int z = top.getZ(); + for (int x = bot.getX(); x < (top.getX() + (plot.getMerged(1) ? 0 : 1)); x++) { + for (int y = 1; y <= dpw.WALL_HEIGHT; y++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } } } - x = bottom.getX(); - for (z = top.getZ(); z >= (bottom.getZ() + 1); z--) { - for (int y = 1; y <= dpw.WALL_HEIGHT; y++) { - SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + if (!plot.getMerged(1)) { + int x = top.getX(); + for (int z = bot.getZ(); z < (top.getZ() + (plot.getMerged(2) ? 0 : 1)); z++) { + for (int y = 1; y <= dpw.WALL_HEIGHT; y++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } } } return true; @@ -96,26 +182,34 @@ public class ClassicPlotManager extends SquarePlotManager { if (dpw.ROAD_WIDTH == 0) { return false; } - final Location bottom = MainUtil.getPlotBottomLoc(plotworld.worldname, plotid); - final Location top = MainUtil.getPlotTopLoc(plotworld.worldname, plotid).add(1, 0, 1); - int x, z; - z = bottom.getZ(); + Plot plot = MainUtil.getPlotAbs(plotworld.worldname, plotid); + final Location bot = MainUtil.getPlotBottomLoc_(plot).subtract(plot.getMerged(3) ? 0 : 1, 0, plot.getMerged(0) ? 0 : 1); + final Location top = MainUtil.getPlotTopLoc_(plot).add(1, 0, 1); final PseudoRandom random = new PseudoRandom(); final int y = dpw.WALL_HEIGHT + 1; - for (x = bottom.getX(); x <= (top.getX() - 1); x++) { - SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + if (!plot.getMerged(0)) { + int z = bot.getZ(); + for (int x = bot.getX(); x < (top.getX()); x++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } } - x = top.getX(); - for (z = bottom.getZ(); z <= (top.getZ() - 1); z++) { - SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + if (!plot.getMerged(3)) { + int x = bot.getX(); + for (int z = bot.getZ(); z < (top.getZ()); z++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } } - z = top.getZ(); - for (x = top.getX(); x >= (bottom.getX() + 1); x--) { - SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + if (!plot.getMerged(2)) { + int z = top.getZ(); + for (int x = bot.getX(); x < (top.getX() + (plot.getMerged(1) ? 0 : 1)); x++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } } - x = bottom.getX(); - for (z = top.getZ(); z >= (bottom.getZ() + 1); z--) { - SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + if (!plot.getMerged(1)) { + int x = top.getX(); + for (int z = bot.getZ(); z < (top.getZ() + (plot.getMerged(2) ? 0 : 1)); z++) { + SetBlockQueue.setBlock(plotworld.worldname, x, y, z, blocks[random.random(blocks.length)]); + } } return true; } @@ -130,19 +224,18 @@ public class ClassicPlotManager extends SquarePlotManager { final Location pos2 = getPlotTopLocAbs(plotworld, plot.id); final int sx = pos2.getX() + 1; final int ex = (sx + dpw.ROAD_WIDTH) - 1; - final int sz = pos1.getZ() - 1; + final int sz = pos1.getZ() - 2; final int ez = pos2.getZ() + 2; - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, Math.min(dpw.WALL_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz + 1), new Location(plotworld.worldname, ex + 1, - 257, ez), new PlotBlock((short) 0, (byte) 0)); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, 1, sz + 1), new Location(plotworld.worldname, ex + 1, dpw.PLOT_HEIGHT, ez), new PlotBlock((short) 7, + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, Math.min(dpw.WALL_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz + 1), new Location(plotworld.worldname, ex, 255, ez - 1), new PlotBlock((short) 0, (byte) 0)); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, 1, sz + 1), new Location(plotworld.worldname, ex, dpw.PLOT_HEIGHT, ez - 1), new PlotBlock((short) 7, (byte) 0)); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, 1, sz + 1), new Location(plotworld.worldname, sx + 1, dpw.WALL_HEIGHT + 1, ez), dpw.WALL_FILLING); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, dpw.WALL_HEIGHT + 1, sz + 1), new Location(plotworld.worldname, sx + 1, dpw.WALL_HEIGHT + 2, ez), + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, 1, sz + 1), new Location(plotworld.worldname, sx, dpw.WALL_HEIGHT, ez - 1), dpw.WALL_FILLING); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, dpw.WALL_HEIGHT + 1, sz + 1), new Location(plotworld.worldname, sx, dpw.WALL_HEIGHT + 1, ez - 1), dpw.WALL_BLOCK); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, ex, 1, sz + 1), new Location(plotworld.worldname, ex + 1, dpw.WALL_HEIGHT + 1, ez), dpw.WALL_FILLING); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, ex, dpw.WALL_HEIGHT + 1, sz + 1), new Location(plotworld.worldname, ex + 1, dpw.WALL_HEIGHT + 2, ez), + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, ex, 1, sz + 1), new Location(plotworld.worldname, ex, dpw.WALL_HEIGHT, ez - 1), dpw.WALL_FILLING); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, ex, dpw.WALL_HEIGHT + 1, sz + 1), new Location(plotworld.worldname, ex, dpw.WALL_HEIGHT + 1, ez - 1), dpw.WALL_BLOCK); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz + 1), new Location(plotworld.worldname, ex, dpw.ROAD_HEIGHT + 1, ez), dpw.ROAD_BLOCK); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz + 1), new Location(plotworld.worldname, ex - 1, dpw.ROAD_HEIGHT, ez - 1), dpw.ROAD_BLOCK); return true; } @@ -153,18 +246,17 @@ public class ClassicPlotManager extends SquarePlotManager { final Location pos2 = getPlotTopLocAbs(plotworld, plot.id); final int sz = pos2.getZ() + 1; final int ez = (sz + dpw.ROAD_WIDTH) - 1; - final int sx = pos1.getX() - 1; + final int sx = pos1.getX() - 2; final int ex = pos2.getX() + 2; - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, Math.min(dpw.WALL_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz), new Location(plotworld.worldname, ex, 257, - ez + 1), new PlotBlock((short) 0, (byte) 0)); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 0, sz), new Location(plotworld.worldname, ex, 1, ez + 1), new PlotBlock((short) 7, (byte) 0)); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz), new Location(plotworld.worldname, ex, dpw.WALL_HEIGHT + 1, sz + 1), dpw.WALL_FILLING); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, dpw.WALL_HEIGHT + 1, sz), new Location(plotworld.worldname, ex, dpw.WALL_HEIGHT + 2, sz + 1), + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, Math.min(dpw.WALL_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz), new Location(plotworld.worldname, ex - 1, 255, ez), new PlotBlock((short) 0, (byte) 0)); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 0, sz), new Location(plotworld.worldname, ex - 1, 0, ez), new PlotBlock((short) 7, (byte) 0)); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz), new Location(plotworld.worldname, ex - 1, dpw.WALL_HEIGHT, sz), dpw.WALL_FILLING); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, dpw.WALL_HEIGHT + 1, sz), new Location(plotworld.worldname, ex - 1, dpw.WALL_HEIGHT + 1, sz), dpw.WALL_BLOCK); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, ez), new Location(plotworld.worldname, ex, dpw.WALL_HEIGHT + 1, ez + 1), dpw.WALL_FILLING); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, dpw.WALL_HEIGHT + 1, ez), new Location(plotworld.worldname, ex, dpw.WALL_HEIGHT + 2, ez + 1), + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, ez), new Location(plotworld.worldname, ex - 1, dpw.WALL_HEIGHT, ez), dpw.WALL_FILLING); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, dpw.WALL_HEIGHT + 1, ez), new Location(plotworld.worldname, ex - 1, dpw.WALL_HEIGHT + 1, ez), dpw.WALL_BLOCK); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz + 1), new Location(plotworld.worldname, ex, dpw.ROAD_HEIGHT + 1, ez), dpw.ROAD_BLOCK); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz + 1), new Location(plotworld.worldname, ex - 1, dpw.ROAD_HEIGHT, ez - 1), dpw.ROAD_BLOCK); return true; } @@ -176,10 +268,10 @@ public class ClassicPlotManager extends SquarePlotManager { final int ex = (sx + dpw.ROAD_WIDTH) - 1; final int sz = pos2.getZ() + 1; final int ez = (sz + dpw.ROAD_WIDTH) - 1; - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, dpw.ROAD_HEIGHT + 1, sz + 1), new Location(plotworld.worldname, ex, 257, ez), new PlotBlock( + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, dpw.ROAD_HEIGHT + 1, sz + 1), new Location(plotworld.worldname, ex - 1, 255, ez - 1), new PlotBlock( (short) 0, (byte) 0)); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 0, sz + 1), new Location(plotworld.worldname, ex, 1, ez), new PlotBlock((short) 7, (byte) 0)); - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz + 1), new Location(plotworld.worldname, ex, dpw.ROAD_HEIGHT + 1, ez), dpw.ROAD_BLOCK); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 0, sz + 1), new Location(plotworld.worldname, ex - 1, 0, ez - 1), new PlotBlock((short) 7, (byte) 0)); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz + 1), new Location(plotworld.worldname, ex - 1, dpw.ROAD_HEIGHT, ez - 1), dpw.ROAD_BLOCK); return true; } @@ -190,12 +282,11 @@ public class ClassicPlotManager extends SquarePlotManager { final Location pos2 = getPlotTopLocAbs(plotworld, plot.id); final int sx = pos2.getX() + 1; final int ex = (sx + dpw.ROAD_WIDTH) - 1; - final int sz = pos1.getZ(); + final int sz = pos1.getZ() - 1; final int ez = pos2.getZ() + 1; - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, Math.min(dpw.PLOT_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz), new Location(plotworld.worldname, ex + 1, 257, - ez + 1), new PlotBlock((short) 0, (byte) 0)); - MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, 1, sz + 1), new Location(plotworld.worldname, ex + 1, dpw.PLOT_HEIGHT, ez), dpw.MAIN_BLOCK); - MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, dpw.PLOT_HEIGHT, sz + 1), new Location(plotworld.worldname, ex + 1, dpw.PLOT_HEIGHT + 1, ez), dpw.TOP_BLOCK); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, Math.min(dpw.PLOT_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz), new Location(plotworld.worldname, ex, 255, ez), new PlotBlock((short) 0, (byte) 0)); + MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, 1, sz + 1), new Location(plotworld.worldname, ex, dpw.PLOT_HEIGHT - 1, ez - 1), dpw.MAIN_BLOCK); + MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, dpw.PLOT_HEIGHT, sz + 1), new Location(plotworld.worldname, ex, dpw.PLOT_HEIGHT, ez - 1), dpw.TOP_BLOCK); return true; } @@ -206,12 +297,11 @@ public class ClassicPlotManager extends SquarePlotManager { final Location pos2 = getPlotTopLocAbs(plotworld, plot.id); final int sz = pos2.getZ() + 1; final int ez = (sz + dpw.ROAD_WIDTH) - 1; - final int sx = pos1.getX(); + final int sx = pos1.getX() - 1; final int ex = pos2.getX() + 1; - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, Math.min(dpw.PLOT_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz), new Location(plotworld.worldname, ex + 1, 257, - ez + 1), new PlotBlock((short) 0, (byte) 0)); - MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz), new Location(plotworld.worldname, ex, dpw.PLOT_HEIGHT, ez + 1), dpw.MAIN_BLOCK); - MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, dpw.PLOT_HEIGHT, sz), new Location(plotworld.worldname, ex, dpw.PLOT_HEIGHT + 1, ez + 1), dpw.TOP_BLOCK); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, Math.min(dpw.PLOT_HEIGHT, dpw.ROAD_HEIGHT) + 1, sz), new Location(plotworld.worldname, ex, 255, ez), new PlotBlock((short) 0, (byte) 0)); + MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, 1, sz), new Location(plotworld.worldname, ex - 1, dpw.PLOT_HEIGHT - 1, ez), dpw.MAIN_BLOCK); + MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx + 1, dpw.PLOT_HEIGHT, sz), new Location(plotworld.worldname, ex - 1, dpw.PLOT_HEIGHT, ez), dpw.TOP_BLOCK); return true; } @@ -223,10 +313,9 @@ public class ClassicPlotManager extends SquarePlotManager { final int ex = (sx + dpw.ROAD_WIDTH) - 1; final int sz = loc.getZ() + 1; final int ez = (sz + dpw.ROAD_WIDTH) - 1; - MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, dpw.ROAD_HEIGHT + 1, sz), new Location(plotworld.worldname, ex + 1, 257, ez + 1), new PlotBlock( - (short) 0, (byte) 0)); - MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, 1, sz), new Location(plotworld.worldname, ex + 1, dpw.ROAD_HEIGHT, ez + 1), dpw.MAIN_BLOCK); - MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, dpw.ROAD_HEIGHT, sz), new Location(plotworld.worldname, ex + 1, dpw.ROAD_HEIGHT + 1, ez + 1), dpw.TOP_BLOCK); + MainUtil.setSimpleCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, dpw.ROAD_HEIGHT + 1, sz), new Location(plotworld.worldname, ex, 255, ez), new PlotBlock((short) 0, (byte) 0)); + MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, 1, sz), new Location(plotworld.worldname, ex, dpw.ROAD_HEIGHT - 1, ez), dpw.MAIN_BLOCK); + MainUtil.setCuboidAsync(plotworld.worldname, new Location(plotworld.worldname, sx, dpw.ROAD_HEIGHT, sz), new Location(plotworld.worldname, ex, dpw.ROAD_HEIGHT, ez), dpw.TOP_BLOCK); return true; } @@ -235,11 +324,12 @@ public class ClassicPlotManager extends SquarePlotManager { */ @Override public boolean finishPlotMerge(final PlotWorld plotworld, final ArrayList plotIds) { - final PlotId pos1 = plotIds.get(0); final PlotBlock block = ((ClassicPlotWorld) plotworld).CLAIMED_WALL_BLOCK; final PlotBlock unclaim = ((ClassicPlotWorld) plotworld).WALL_BLOCK; if ((block.id != 0) || !block.equals(unclaim)) { - setWall(plotworld, pos1, new PlotBlock[] { block }); + for (final PlotId id : plotIds) { + setWall(plotworld, id, new PlotBlock[] { block }); + } } return true; } @@ -278,16 +368,17 @@ public class ClassicPlotManager extends SquarePlotManager { @Override public String[] getPlotComponents(final PlotWorld plotworld, final PlotId plotid) { - return new String[] { "floor", "wall", "border" }; + return new String[] { "floor", "wall", "border", "all", "outline" }; } /** * Remove sign for a plot */ @Override - public Location getSignLoc(final PlotWorld plotworld, final Plot plot) { + public Location getSignLoc(final PlotWorld plotworld, Plot plot) { final ClassicPlotWorld dpw = (ClassicPlotWorld) plotworld; - final Location bot = MainUtil.getPlotBottomLoc(plotworld.worldname, plot.id); - return new com.intellectualcrafters.plot.object.Location(plotworld.worldname, bot.getX(), dpw.ROAD_HEIGHT + 1, bot.getZ() - 1); + plot = plot.getBasePlot(false); + final Location bot = plot.getBottomAbs(); + return new com.intellectualcrafters.plot.object.Location(plotworld.worldname, bot.getX() - 1, dpw.ROAD_HEIGHT + 1, bot.getZ() - 2); } } diff --git a/src/main/java/com/intellectualcrafters/plot/generator/HybridPlotManager.java b/src/main/java/com/intellectualcrafters/plot/generator/HybridPlotManager.java index f7f8c59df..52a215aee 100644 --- a/src/main/java/com/intellectualcrafters/plot/generator/HybridPlotManager.java +++ b/src/main/java/com/intellectualcrafters/plot/generator/HybridPlotManager.java @@ -171,8 +171,8 @@ public class HybridPlotManager extends ClassicPlotManager { final String world = plotworld.worldname; final HybridPlotWorld dpw = ((HybridPlotWorld) plotworld); - final Location pos1 = MainUtil.getPlotBottomLoc(world, plot.id).add(1, 0, 1); - final Location pos2 = MainUtil.getPlotTopLoc(world, plot.id); + final Location pos1 = MainUtil.getPlotBottomLocAbs(world, plot.id); + final Location pos2 = MainUtil.getPlotTopLoc_(plot); // If augmented final boolean canRegen = (plotworld.TYPE == 0) && (plotworld.TERRAIN == 0); // The component blocks @@ -198,7 +198,7 @@ public class HybridPlotManager extends ClassicPlotManager { MainUtil.setBiome(world, value[2], value[3], value[4], value[5], dpw.PLOT_BIOME); // These two locations are for each component (e.g. bedrock, main block, floor, air) final Location bot = new Location(world, value[2], 0, value[3]); - final Location top = new Location(world, value[4] + 1, 1, value[5] + 1); + final Location top = new Location(world, value[4], 1, value[5]); MainUtil.setCuboidAsync(world, bot, top, bedrock); // Each component has a different layer bot.setY(1); diff --git a/src/main/java/com/intellectualcrafters/plot/generator/HybridUtils.java b/src/main/java/com/intellectualcrafters/plot/generator/HybridUtils.java index fa7045a12..c1eea7c9f 100644 --- a/src/main/java/com/intellectualcrafters/plot/generator/HybridUtils.java +++ b/src/main/java/com/intellectualcrafters/plot/generator/HybridUtils.java @@ -1,14 +1,21 @@ package com.intellectualcrafters.plot.generator; import java.io.File; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import com.intellectualcrafters.jnbt.CompoundTag; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; +import com.intellectualcrafters.plot.flag.Flag; +import com.intellectualcrafters.plot.flag.FlagManager; import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; @@ -18,6 +25,7 @@ import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotLoc; import com.intellectualcrafters.plot.object.PlotManager; import com.intellectualcrafters.plot.object.PlotWorld; +import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.object.RunnableVal; import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.MainUtil; @@ -29,12 +37,78 @@ public abstract class HybridUtils { public static HybridUtils manager; - public abstract void analyzePlot(final Plot plot, final RunnableVal whenDone); + public abstract void analyzeRegion(final String world, final RegionWrapper region, final RunnableVal whenDone); + + public void analyzePlot(final Plot origin, final RunnableVal whenDone) { + final ArrayDeque zones = new ArrayDeque<>(MainUtil.getRegions(origin)); + final ArrayList analysis = new ArrayList<>(); + Runnable run = new Runnable() { + @Override + public void run() { + if (zones.size() == 0) { + if (analysis.size() > 0) { + whenDone.value = new PlotAnalysis(); + for (PlotAnalysis data : analysis) { + whenDone.value.air += data.air; + whenDone.value.air_sd += data.air_sd; + whenDone.value.changes += data.changes; + whenDone.value.changes_sd += data.changes_sd; + whenDone.value.data += data.data; + whenDone.value.data_sd += data.data_sd; + whenDone.value.faces += data.faces; + whenDone.value.faces_sd += data.faces_sd; + whenDone.value.variety += data.variety; + whenDone.value.variety_sd += data.variety_sd; + } + whenDone.value.air /= analysis.size(); + whenDone.value.air_sd /= analysis.size(); + whenDone.value.changes /= analysis.size(); + whenDone.value.changes_sd /= analysis.size(); + whenDone.value.data /= analysis.size(); + whenDone.value.data_sd /= analysis.size(); + whenDone.value.faces /= analysis.size(); + whenDone.value.faces_sd /= analysis.size(); + whenDone.value.variety /= analysis.size(); + whenDone.value.variety_sd /= analysis.size(); + } + else { + whenDone.value = analysis.get(0); + } + final List result = new ArrayList<>(); + result.add(whenDone.value.changes); + result.add(whenDone.value.faces); + result.add(whenDone.value.data); + result.add(whenDone.value.air); + result.add(whenDone.value.variety); + + result.add(whenDone.value.changes_sd); + result.add(whenDone.value.faces_sd); + result.add(whenDone.value.data_sd); + result.add(whenDone.value.air_sd); + result.add(whenDone.value.variety_sd); + final Flag flag = new Flag(FlagManager.getFlag("analysis"), result); + FlagManager.addPlotFlag(origin, flag); + TaskManager.runTask(whenDone); + return; + } + RegionWrapper region = zones.poll(); + final Runnable task = this; + analyzeRegion(origin.world, region, new RunnableVal() { + @Override + public void run() { + analysis.add(value); + TaskManager.runTaskLater(task, 1); + } + }); + } + }; + run.run(); + } public abstract int checkModified(final String world, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2, final PlotBlock[] blocks); - public static List regions; - public static List chunks = new ArrayList<>(); + public static Set regions; + public static Set chunks = new HashSet<>(); public static String world; public static boolean UPDATE = false; @@ -50,12 +124,15 @@ public abstract class HybridUtils { return chunks; } + /** + * Checks all connected plots + * @param plot + * @param whenDone + */ public void checkModified(final Plot plot, final RunnableVal whenDone) { if (whenDone == null) { return; } - final Location pos1 = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); - final Location pos2 = MainUtil.getPlotTopLoc(plot.world, plot.id); final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); if (!(plotworld instanceof ClassicPlotWorld)) { whenDone.value = -1; @@ -64,25 +141,36 @@ public abstract class HybridUtils { } whenDone.value = 0; final ClassicPlotWorld cpw = (ClassicPlotWorld) plotworld; - ChunkManager.chunkTask(pos1, pos2, new RunnableVal() { + final ArrayDeque zones = new ArrayDeque<>(MainUtil.getRegions(plot)); + Runnable run = new Runnable() { @Override public void run() { - final ChunkLoc loc = new ChunkLoc(value[0], value[1]); - ChunkManager.manager.loadChunk(plot.world, loc, false); - final int bx = value[2]; - final int bz = value[3]; - final int ex = value[4]; - final int ez = value[5]; - whenDone.value += checkModified(plot.world, bx, ex, 1, cpw.PLOT_HEIGHT - 1, bz, ez, cpw.MAIN_BLOCK); - whenDone.value += checkModified(plot.world, bx, ex, cpw.PLOT_HEIGHT, cpw.PLOT_HEIGHT, bz, ez, cpw.TOP_BLOCK); - whenDone.value += checkModified(plot.world, bx, ex, cpw.PLOT_HEIGHT + 1, 255, bz, ez, new PlotBlock[] { new PlotBlock((short) 0, (byte) 0) }); + if (zones.size() == 0) { + + TaskManager.runTask(whenDone); + return; + } + RegionWrapper region = zones.poll(); + Location pos1 = new Location(plot.world, region.minX, region.minY, region.minZ); + Location pos2 = new Location(plot.world, region.maxX, region.maxY, region.maxZ); + ChunkManager.chunkTask(pos1, pos2, new RunnableVal() { + @Override + public void run() { + final ChunkLoc loc = new ChunkLoc(value[0], value[1]); + ChunkManager.manager.loadChunk(plot.world, loc, false); + final int bx = value[2]; + final int bz = value[3]; + final int ex = value[4]; + final int ez = value[5]; + whenDone.value += checkModified(plot.world, bx, ex, 1, cpw.PLOT_HEIGHT - 1, bz, ez, cpw.MAIN_BLOCK); + whenDone.value += checkModified(plot.world, bx, ex, cpw.PLOT_HEIGHT, cpw.PLOT_HEIGHT, bz, ez, cpw.TOP_BLOCK); + whenDone.value += checkModified(plot.world, bx, ex, cpw.PLOT_HEIGHT + 1, 255, bz, ez, new PlotBlock[] { new PlotBlock((short) 0, (byte) 0) }); + } + }, this, 5); + } - }, new Runnable() { - @Override - public void run() { - TaskManager.runTask(whenDone); - } - }, 5); + }; + run.run(); } public boolean scheduleRoadUpdate(final String world, final int extend) { @@ -90,14 +178,14 @@ public abstract class HybridUtils { return false; } HybridUtils.UPDATE = true; - final List regions = ChunkManager.manager.getChunkChunks(world); + final Set regions = ChunkManager.manager.getChunkChunks(world); return scheduleRoadUpdate(world, regions, extend); } - public boolean scheduleRoadUpdate(final String world, final List rgs, final int extend) { + public boolean scheduleRoadUpdate(final String world, final Set rgs, final int extend) { HybridUtils.regions = rgs; HybridUtils.world = world; - chunks = new ArrayList(); + chunks = new HashSet(); final AtomicInteger count = new AtomicInteger(0); final long baseTime = System.currentTimeMillis(); final AtomicInteger last = new AtomicInteger(); @@ -106,9 +194,10 @@ public abstract class HybridUtils { public void run() { if (UPDATE == false) { last.set(0); - while (chunks.size() > 0) { - final ChunkLoc chunk = chunks.get(0); - chunks.remove(0); + Iterator iter = chunks.iterator(); + while (iter.hasNext()) { + final ChunkLoc chunk = iter.next(); + iter.remove(); regenerateRoad(world, chunk, extend); ChunkManager.manager.unloadChunk(world, chunk, true, true); } @@ -135,11 +224,12 @@ public abstract class HybridUtils { } if (chunks.size() < 1024) { if (regions.size() > 0) { - final ChunkLoc loc = regions.get(0); + Iterator iter = regions.iterator(); + final ChunkLoc loc = iter.next(); + iter.remove(); PS.debug("&3Updating .mcr: " + loc.x + ", " + loc.z + " (aprrox 1024 chunks)"); PS.debug(" - Remaining: " + regions.size()); chunks.addAll(getChunks(loc)); - regions.remove(0); System.gc(); } } @@ -148,8 +238,9 @@ public abstract class HybridUtils { if (((System.currentTimeMillis() - baseTime - last.get()) > 2000) && (last.get() != 0)) { last.set(0); PS.debug(C.PREFIX.s() + "Detected low TPS. Rescheduling in 30s"); - final ChunkLoc chunk = chunks.get(0); - chunks.remove(0); + Iterator iter = chunks.iterator(); + final ChunkLoc chunk = iter.next(); + iter.remove(); TaskManager.runTask(new Runnable() { @Override public void run() { @@ -162,8 +253,9 @@ public abstract class HybridUtils { } if ((((System.currentTimeMillis() - baseTime) - last.get()) < 1500) && (last.get() != 0)) { while ((System.currentTimeMillis() < diff) && (chunks.size() > 0)) { - final ChunkLoc chunk = chunks.get(0); - chunks.remove(0); + Iterator iter = chunks.iterator(); + final ChunkLoc chunk = iter.next(); + iter.remove(); TaskManager.runTask(new Runnable() { @Override public void run() { @@ -176,7 +268,9 @@ public abstract class HybridUtils { } } catch (final Exception e) { e.printStackTrace(); - final ChunkLoc loc = regions.get(0); + Iterator iter = regions.iterator(); + final ChunkLoc loc = iter.next(); + iter.remove(); PS.debug("&c[ERROR]&7 Could not update '" + world + "/region/r." + loc.x + "." + loc.z + ".mca' (Corrupt chunk?)"); final int sx = loc.x << 5; final int sz = loc.z << 5; @@ -204,8 +298,8 @@ public abstract class HybridUtils { public boolean setupRoadSchematic(final Plot plot) { final String world = plot.world; - final Location bot = MainUtil.getPlotBottomLoc(world, plot.id); - final Location top = MainUtil.getPlotTopLoc(world, plot.id); + final Location bot = MainUtil.getPlotBottomLocAbs(world, plot.id).subtract(1, 0, 1); + final Location top = MainUtil.getPlotTopLocAbs(world, plot.id); final HybridPlotWorld plotworld = (HybridPlotWorld) PS.get().getPlotWorld(world); final int sx = (bot.getX() - plotworld.ROAD_WIDTH) + 1; final int sz = bot.getZ() + 1; @@ -221,14 +315,18 @@ public abstract class HybridUtils { final int tx = ex; final int tz = sz - 1; final int ty = get_ey(world, bx, tx, bz, tz, by); + + final Set sideroad = new HashSet<>(Arrays.asList(new RegionWrapper(sx, ex, sz, ez))); + final Set intersection = new HashSet<>(Arrays.asList(new RegionWrapper(bx, tx, bz, tz))); + final Location pos3 = new Location(world, bx, by, bz); final Location pos4 = new Location(world, tx, ty, tz); final String dir = PS.get().IMP.getDirectory() + File.separator + "schematics" + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + plot.world + File.separator; - SchematicHandler.manager.getCompoundTag(world, pos1, pos2, new RunnableVal() { + SchematicHandler.manager.getCompoundTag(world, sideroad, new RunnableVal() { @Override public void run() { SchematicHandler.manager.save(value, dir + "sideroad.schematic"); - SchematicHandler.manager.getCompoundTag(world, pos3, pos4, new RunnableVal() { + SchematicHandler.manager.getCompoundTag(world, intersection, new RunnableVal() { @Override public void run() { SchematicHandler.manager.save(value, dir + "intersection.schematic"); @@ -272,14 +370,14 @@ public abstract class HybridUtils { final boolean result = ChunkManager.manager.loadChunk(world, chunk, false); if (result) { if (id1 != null) { - final Plot p1 = MainUtil.getPlot(world, id1); - if ((p1 != null) && p1.hasOwner() && p1.getSettings().isMerged()) { + final Plot p1 = MainUtil.getPlotAbs(world, id1); + if ((p1 != null) && p1.hasOwner() && p1.isMerged()) { toCheck = true; } } if ((id2 != null) && !toCheck) { - final Plot p2 = MainUtil.getPlot(world, id2); - if ((p2 != null) && p2.hasOwner() && p2.getSettings().isMerged()) { + final Plot p2 = MainUtil.getPlotAbs(world, id2); + if ((p2 != null) && p2.hasOwner() && p2.isMerged()) { toCheck = true; } } diff --git a/src/main/java/com/intellectualcrafters/plot/generator/SquarePlotManager.java b/src/main/java/com/intellectualcrafters/plot/generator/SquarePlotManager.java index 25eebf62c..7db5fc771 100644 --- a/src/main/java/com/intellectualcrafters/plot/generator/SquarePlotManager.java +++ b/src/main/java/com/intellectualcrafters/plot/generator/SquarePlotManager.java @@ -1,12 +1,17 @@ package com.intellectualcrafters.plot.generator; +import java.util.HashSet; +import java.util.Iterator; + import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotWorld; +import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.MainUtil; +import com.intellectualcrafters.plot.util.StringMan; /** * A plot manager with a square grid layout, with square shaped plots @@ -14,9 +19,23 @@ import com.intellectualcrafters.plot.util.MainUtil; public abstract class SquarePlotManager extends GridPlotManager { @Override public boolean clearPlot(final PlotWorld plotworld, final Plot plot, final Runnable whenDone) { - final Location pos1 = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); - final Location pos2 = MainUtil.getPlotTopLoc(plot.world, plot.id); - ChunkManager.manager.regenerateRegion(pos1, pos2, whenDone); + final HashSet regions = MainUtil.getRegions(plot); + Runnable run = new Runnable() { + @Override + public void run() { + if (regions.size() == 0) { + whenDone.run(); + return; + } + Iterator iter = regions.iterator(); + RegionWrapper region = iter.next(); + iter.remove(); + Location pos1 = new Location(plot.world, region.minX, region.minY, region.minZ); + Location pos2 = new Location(plot.world, region.maxX, region.maxY, region.maxZ); + ChunkManager.manager.regenerateRegion(pos1, pos2, this); + } + }; + run.run(); return true; } @@ -33,8 +52,12 @@ public abstract class SquarePlotManager extends GridPlotManager { @Override public PlotId getPlotIdAbs(final PlotWorld plotworld, int x, final int y, int z) { final SquarePlotWorld dpw = ((SquarePlotWorld) plotworld); - x -= dpw.ROAD_OFFSET_X; - z -= dpw.ROAD_OFFSET_Z; + if (dpw.ROAD_OFFSET_X != 0) { + x -= dpw.ROAD_OFFSET_X; + } + if (dpw.ROAD_OFFSET_Z != 0) { + z -= dpw.ROAD_OFFSET_Z; + } int pathWidthLower; int end; if (dpw.ROAD_WIDTH == 0) { @@ -65,12 +88,7 @@ public abstract class SquarePlotManager extends GridPlotManager { idz = (z / size) + 1; z = (z % size); } - final boolean northSouth = (z <= pathWidthLower) || (z > end); - final boolean eastWest = (x <= pathWidthLower) || (x > end); - if (northSouth || eastWest) { - return null; - } - return new PlotId(idx, idz); + return ((z <= pathWidthLower) || (z > end) || (x <= pathWidthLower) || (x > end)) ? null : new PlotId(idx, idz); } @Override @@ -113,53 +131,46 @@ public abstract class SquarePlotManager extends GridPlotManager { dz = (z / size) + 1; rz = (z % size); } - final boolean northSouth = (rz <= pathWidthLower) || (rz > end); - final boolean eastWest = (rx <= pathWidthLower) || (rx > end); - if (northSouth && eastWest) { - // This means you are in the intersection - final Location loc = new Location(plotworld.worldname, x + dpw.ROAD_WIDTH + dpw.ROAD_OFFSET_X, 0, z + dpw.ROAD_WIDTH + dpw.ROAD_OFFSET_Z); - final PlotId id = MainUtil.getPlotAbs(loc); - final Plot plot = PS.get().getPlot(plotworld.worldname, id); - if (plot == null) { - return null; - } - if ((plot.getMerged(0) && plot.getMerged(3))) { - return MainUtil.getBottomPlot(plot).id; - } - return null; - } - if (northSouth) { - // You are on a road running West to East (yeah, I named the var poorly) - final Location loc = new Location(plotworld.worldname, x + dpw.ROAD_OFFSET_X, 0, z + dpw.ROAD_WIDTH + dpw.ROAD_OFFSET_Z); - final PlotId id = MainUtil.getPlotAbs(loc); - final Plot plot = PS.get().getPlot(plotworld.worldname, id); - if (plot == null) { - return null; - } - if (plot.getMerged(0)) { - return MainUtil.getBottomPlot(plot).id; - } - return null; - } - if (eastWest) { - // This is the road separating an Eastern and Western plot - final Location loc = new Location(plotworld.worldname, x + dpw.ROAD_WIDTH + dpw.ROAD_OFFSET_X, 0, z + dpw.ROAD_OFFSET_Z); - final PlotId id = MainUtil.getPlotAbs(loc); - final Plot plot = PS.get().getPlot(plotworld.worldname, id); - if (plot == null) { - return null; - } - if (plot.getMerged(3)) { - return MainUtil.getBottomPlot(plot).id; - } - return null; - } - final PlotId id = new PlotId(dx, dz); - final Plot plot = PS.get().getPlot(plotworld.worldname, id); - if (plot == null) { + PlotId id = new PlotId(dx, dz); + boolean[] merged = new boolean[] {(rz <= pathWidthLower), (rx > end), (rz > end), (rx <= pathWidthLower)}; + int hash = MainUtil.hash(merged); + // Not merged, and no need to check if it is + if (hash == 0) { return id; } - return MainUtil.getBottomPlot(plot).id; + Plot plot = PS.get().getPlot(plotworld.worldname, id); + // Not merged, and standing on road + if (plot == null) { + return null; + } + switch (hash) { + case 8: + // north + return plot.getMerged(0) ? id : null; + case 4: + // east + return plot.getMerged(1) ? id : null; + case 2: + // south + return plot.getMerged(2) ? id : null; + case 1: + // west + return plot.getMerged(3) ? id : null; + case 12: + // northest + return plot.getMerged(4) ? id : null; + case 6: + // southeast + return plot.getMerged(5) ? id : null; + case 3: + // southwest + return plot.getMerged(6) ? id : null; + case 9: + // northwest + return plot.getMerged(7) ? id : null; + } + PS.debug("invalid location: " + merged); + return null; } /** @@ -170,8 +181,8 @@ public abstract class SquarePlotManager extends GridPlotManager { final SquarePlotWorld dpw = ((SquarePlotWorld) plotworld); final int px = plotid.x; final int pz = plotid.y; - final int x = (dpw.ROAD_OFFSET_X + (px * (dpw.ROAD_WIDTH + dpw.PLOT_WIDTH))) - dpw.PLOT_WIDTH - ((int) Math.floor(dpw.ROAD_WIDTH / 2)) - 1; - final int z = (dpw.ROAD_OFFSET_Z + (pz * (dpw.ROAD_WIDTH + dpw.PLOT_WIDTH))) - dpw.PLOT_WIDTH - ((int) Math.floor(dpw.ROAD_WIDTH / 2)) - 1; + final int x = (dpw.ROAD_OFFSET_X + (px * (dpw.ROAD_WIDTH + dpw.PLOT_WIDTH))) - dpw.PLOT_WIDTH - ((int) Math.floor(dpw.ROAD_WIDTH / 2)); + final int z = (dpw.ROAD_OFFSET_Z + (pz * (dpw.ROAD_WIDTH + dpw.PLOT_WIDTH))) - dpw.PLOT_WIDTH - ((int) Math.floor(dpw.ROAD_WIDTH / 2)); return new Location(plotworld.worldname, x, plotworld.MIN_BUILD_HEIGHT, z); } } diff --git a/src/main/java/com/intellectualcrafters/plot/object/ChunkLoc.java b/src/main/java/com/intellectualcrafters/plot/object/ChunkLoc.java index e4093ba22..9d891b540 100644 --- a/src/main/java/com/intellectualcrafters/plot/object/ChunkLoc.java +++ b/src/main/java/com/intellectualcrafters/plot/object/ChunkLoc.java @@ -32,4 +32,9 @@ public class ChunkLoc { final ChunkLoc other = (ChunkLoc) obj; return ((x == other.x) && (z == other.z)); } + + @Override + public String toString() { + return x + "," + z; + } } diff --git a/src/main/java/com/intellectualcrafters/plot/object/Plot.java b/src/main/java/com/intellectualcrafters/plot/object/Plot.java index 8f9b2e0db..6fc57bdb7 100644 --- a/src/main/java/com/intellectualcrafters/plot/object/Plot.java +++ b/src/main/java/com/intellectualcrafters/plot/object/Plot.java @@ -22,6 +22,7 @@ package com.intellectualcrafters.plot.object; import java.io.File; import java.net.URL; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -38,6 +39,7 @@ import com.intellectualcrafters.plot.config.Settings; import com.intellectualcrafters.plot.database.DBFunc; import com.intellectualcrafters.plot.flag.Flag; import com.intellectualcrafters.plot.flag.FlagManager; +import com.intellectualcrafters.plot.object.comment.PlotComment; import com.intellectualcrafters.plot.util.BO3Handler; import com.intellectualcrafters.plot.util.BlockManager; import com.intellectualcrafters.plot.util.ChunkManager; @@ -131,7 +133,8 @@ public class Plot { * Constructor for a new plot
* (Only changes after plot.create() will be properly set in the database) * - *@see MainUtil#getPlot(String, PlotId) for existing plots + * @see Plot#getPlot(String, PlotId) for existing plots + * @see Plot#getPlot(Location) for existing plots * * @param world * @param id @@ -143,6 +146,20 @@ public class Plot { this.owner = owner; } + /** + * Constructor for an unowned plot
+ * (Only changes after plot.create() will be properly set in the database) + * + * @see Plot#getPlot(String, PlotId) for existing plots + * + * @param world + * @param id + */ + public Plot(final String world, final PlotId id) { + this.world = world; + this.id = id; + } + /** * Return a new/cached plot object at a given world/plot id * @@ -173,7 +190,7 @@ public class Plot { * The database will ignore any queries regarding temporary plots. * Please note that some bulk plot management functions may still affect temporary plots (TODO: fix this) * - * @see MainUtil#getPlot(String, PlotId) for existing plots + * @see Plot#getPlot(String, PlotId) for existing plots * * @param world * @param id @@ -190,7 +207,7 @@ public class Plot { /** * Constructor for a saved plots (Used by the database manager when plots are fetched) * - * @see MainUtil#getPlot(String, PlotId) for existing plots + * @see Plot#getPlot(String, PlotId) for existing plots * * @param id * @param owner @@ -203,7 +220,7 @@ public class Plot { this.id = id; this.world = world; this.owner = owner; - settings = new PlotSettings(this); + settings = new PlotSettings(); this.members = members; this.trusted = trusted; this.denied = denied; @@ -354,20 +371,32 @@ public class Plot { } /** - * Get the world - * @return + * Get the plot world object for this plot
+ * - The generic PlotWorld object can be casted to it's respective class for more control + * @return PlotWorld */ - public String getWorld() { - return world; + public PlotWorld getWorld() { + return PS.get().getPlotWorld(world); + } + + /** + * Get the plot manager object for this plot
+ * - The generic PlotManager object can be casted to it's respective class for more control + * @return PlotManager + */ + public PlotManager getManager() { + return PS.get().getPlotManager(world); } /** * Get or create plot settings * @return PlotSettings + * @deprecated use equivalent plot method; */ + @Deprecated public PlotSettings getSettings() { if (settings == null) { - settings = new PlotSettings(this); + settings = new PlotSettings(); } return settings; } @@ -377,10 +406,54 @@ public class Plot { * @return */ public boolean isBasePlot() { - if (settings == null) { + if (settings == null || !isMerged()) { return true; } - return !settings.getMerged(0) && !settings.getMerged(3); + return equals(getBasePlot(false)); + } + + /** + * The cached origin plot
+ * - The origin plot is used for plot grouping and relational data + */ + private Plot origin; + + + /** + * The base plot is an arbitrary but specific connected plot. It is useful for the following:
+ * - Merged plots need to be treated as a single plot for most purposes
+ * - Some data such as home location needs to be associated with the group rather than each plot
+ * - If the plot is not merged it will return itself.
+ * - The result is cached locally + * @return base Plot + */ + public Plot getBasePlot(boolean recalculate) { + if ((origin != null && !recalculate)) { + return origin; + } + if (!isMerged()) { + origin = this; + return origin; + } + int min = Integer.MAX_VALUE; + for (Plot plot : MainUtil.getConnectedPlots(this)) { + if (plot.temp != -1) { + if (plot.temp < min) { + min = plot.temp; + origin = plot; + } + } + else { + if (plot.hashCode() < min) { + origin = plot; + min = plot.hashCode(); + } + } + } + for (Plot plot : MainUtil.getConnectedPlots(this)) { + plot.origin = origin; + } + return origin; } /** @@ -414,7 +487,25 @@ public class Plot { if (settings == null) { return false; } - return settings.getMerged(direction); + switch (direction) { + case 0: + case 1: + case 2: + case 3: + return settings.getMerged(direction); + case 7: + int i = direction - 4; + int i2 = 0; + return settings.getMerged(i2) && settings.getMerged(i) && MainUtil.getPlotAbs(world, MainUtil.getPlotIdRelative(id, i)).getMerged(i2) && settings.getMerged(i) && settings.getMerged(i2) && MainUtil.getPlotAbs(world, MainUtil.getPlotIdRelative(id, i2)).getMerged(i); + case 4: + case 5: + case 6: + i = direction - 4; + i2 = direction - 3; + return settings.getMerged(i2) && settings.getMerged(i) && MainUtil.getPlotAbs(world, MainUtil.getPlotIdRelative(id, i)).getMerged(i2) && settings.getMerged(i) && settings.getMerged(i2) && MainUtil.getPlotAbs(world, MainUtil.getPlotIdRelative(id, i2)).getMerged(i); + + } + return false; } /** @@ -456,9 +547,7 @@ public class Plot { * @param uuid */ public void addDenied(final UUID uuid) { - if (getDenied().add(uuid)) { - DBFunc.setDenied(this, uuid); - } + PlotHandler.addDenied(this, uuid); } /** @@ -467,9 +556,7 @@ public class Plot { * @param uuid */ public void addTrusted(final UUID uuid) { - if (getTrusted().add(uuid)) { - DBFunc.setTrusted(this, uuid); - } + PlotHandler.addTrusted(this, uuid); } /** @@ -478,9 +565,7 @@ public class Plot { * @param uuid */ public void addMember(final UUID uuid) { - if (getMembers().add(uuid)) { - DBFunc.setMember(this, uuid); - } + PlotHandler.addMember(this, uuid); } /** @@ -488,10 +573,7 @@ public class Plot { * @param owner */ public void setOwner(final UUID owner) { - if (!this.owner.equals(owner)) { - this.owner = owner; - DBFunc.setOwner(this, owner); - } + PlotHandler.setOwner(this, owner); } /** @@ -499,19 +581,7 @@ public class Plot { * @param uuids */ public void setTrusted(final Set uuids) { - if (uuids.size() == 0) { - return; - } - if ((trusted != null) && (trusted.size() > 0)) { - trusted.removeAll(uuids); - for (final UUID uuid : trusted) { - DBFunc.removeTrusted(this, uuid); - } - trusted.clear(); - } - for (final UUID uuid : uuids) { - addTrusted(uuid); - } + PlotHandler.setTrusted(this, uuids); } /** @@ -519,19 +589,7 @@ public class Plot { * @param uuids */ public void setMembers(final Set uuids) { - if (uuids.size() == 0) { - return; - } - if ((members != null) && (members.size() > 0)) { - members.removeAll(uuids); - for (final UUID uuid : members) { - DBFunc.removeMember(this, uuid); - } - members.clear(); - } - for (final UUID uuid : uuids) { - addMember(uuid); - } + PlotHandler.setMembers(this, uuids); } /** @@ -539,19 +597,7 @@ public class Plot { * @param uuids */ public void setDenied(final Set uuids) { - if (uuids.size() == 0) { - return; - } - if ((denied != null) && (denied.size() > 0)) { - denied.removeAll(uuids); - for (final UUID uuid : denied) { - DBFunc.removeDenied(this, uuid); - } - denied.clear(); - } - for (final UUID uuid : uuids) { - addDenied(uuid); - } + PlotHandler.setDenied(this, uuids); } /** @@ -586,6 +632,15 @@ public class Plot { FlagManager.addPlotFlag(this, new Flag(FlagManager.getFlag(flag), value)); } + /** + * Set a flag for this plot + * @param flag + * @param value + */ + public void setFlags(Set flags) { + FlagManager.setPlotFlags(this, flags); + } + /** * Remove a flag from this plot * @param flag @@ -607,25 +662,45 @@ public class Plot { * @see PS#removePlot(String, PlotId, boolean) * @see #clear(Runnable) to simply clear a plot */ - public void deletePlot(final Runnable whenDone) { - MainUtil.removeSign(this); - MainUtil.clear(this, true, new Runnable() { - @Override - public void run() { - if (PS.get().removePlot(world, id, true)) { - DBFunc.delete(Plot.this); - TaskManager.runTask(whenDone); - } + public boolean deletePlot(final Runnable whenDone) { + boolean result = MainUtil.delete(this, whenDone); + return result; + } + + /** + * Returns true if a previous task was running + * @return + */ + public int addRunning() { + int value = getRunning(); + for (Plot plot : getConnectedPlots()) { + MainUtil.runners.put(plot, value + 1); + } + return value; + } + + public int removeRunning() { + int value = getRunning(); + if (value < 2) { + for (Plot plot : getConnectedPlots()) { + MainUtil.runners.remove(plot); } - }); + } + else { + for (Plot plot : getConnectedPlots()) { + MainUtil.runners.put(plot, value - 1); + } + } + return value; + } + + public int getRunning() { + Integer value = MainUtil.runners.get(this); + return value == null ? 0 : value; } public boolean unclaim() { - if (PS.get().removePlot(world, id, true)) { - DBFunc.delete(Plot.this); - return true; - } - return false; + return PlotHandler.unclaim(this); } /** @@ -634,7 +709,7 @@ public class Plot { * @return true if plot was linked */ public boolean unlink() { - return MainUtil.unlinkPlot(this, true); + return MainUtil.unlinkPlot(this, true, true); } /** @@ -681,7 +756,7 @@ public class Plot { */ public void setHome(final BlockLoc loc) { final BlockLoc pos = getSettings().getPosition(); - if (((pos == null) && (loc == null)) || ((pos != null) && pos.equals(loc))) { + if (((pos == null || pos.equals(new BlockLoc(0, 0, 0))) && (loc == null)) || ((pos != null) && pos.equals(loc))) { return; } getSettings().setPosition(loc); @@ -746,8 +821,8 @@ public class Plot { * @see MainUtil#autoMerge(Plot, UUID) to specify the owner * @param removeRoads If to remove roads when merging */ - public void autoMerge(final boolean removeRoads) { - MainUtil.autoMerge(this, owner, removeRoads); + public boolean autoMerge(final boolean removeRoads) { + return MainUtil.autoMerge(this, -1, Integer.MAX_VALUE, owner, removeRoads); } /** @@ -761,23 +836,27 @@ public class Plot { * Set components such as border, wall, floor * (components are generator specific) */ - public void setComponent(final String component, final PlotBlock... blocks) { - MainUtil.setComponent(this, component, blocks); + public boolean setComponent(final String component, final PlotBlock... blocks) { + return MainUtil.setComponent(this, component, blocks); } /** * Set components such as border, wall, floor * (components are generator specific) */ - public void setComponent(final String component, final String blocks) { - MainUtil.setComponent(this, component, Configuration.BLOCKLIST.parseString(blocks)); + public boolean setComponent(final String component, final String blocks) { + PlotBlock[] parsed = Configuration.BLOCKLIST.parseString(blocks); + if (parsed == null || parsed.length == 0) { + return false; + } + return MainUtil.setComponent(this, component, parsed); } /** * Get the biome (String) */ public String getBiome() { - final Location loc = getBottom(); + final Location loc = getBottomAbs(); return BlockManager.manager.getBiome(loc.getWorld(), loc.getX(), loc.getZ()); } @@ -785,32 +864,68 @@ public class Plot { * Return the top location for the plot * @return */ - public Location getTop() { - return MainUtil.getPlotTopLoc(world, id); + public Location getTopAbs() { + return MainUtil.getPlotTopLocAbs(world, id); } /** * Return the bottom location for the plot * @return */ + public Location getBottomAbs() { + return MainUtil.getPlotBottomLocAbs(world, id); + } + + /** + * Returns the top and bottom connected plot.
+ * - If the plot is not connected, it will return itself for the top/bottom
+ * - the returned IDs will not necessarily correspond to claimed plots if the connected plots do not form a rectangular shape + * @deprecated as merged plots no longer need to be rectangular + * @param plot + * @return new PlotId[] { bottom, top } + * @see MainUtil#getCornerIds(Plot) + */ + @Deprecated + public Location[] getCorners() { + return MainUtil.getCorners(this); + } + + /** + * @deprecated in favor of getCorners()[0]; + * @return + */ + @Deprecated public Location getBottom() { - return MainUtil.getPlotBottomLoc(world, id).add(1, 0, 1); + return getCorners()[0]; } /** - * Get the top plot, or this plot if it is not part of a mega plot - * @return The bottom plot + * @deprecated in favor of getCorners()[1]; + * @return */ - public Plot getTopPlot() { - return MainUtil.getTopPlot(this); + @Deprecated + public Location getTop() { + return getCorners()[0]; } /** - * Get the bottom plot, or this plot if it is not part of a mega plot - * @return The bottom plot + * Get a set of plots connected (and including) this plot
+ * - This result is cached globally + * @see MainUtil#getConnectedPlots(Plot) + * @return */ - public Plot getBottomPlot() { - return MainUtil.getBottomPlot(this); + public Set getConnectedPlots() { + return MainUtil.getConnectedPlots(this); + } + + /** + * This will combine each plot into effective rectangular regions + * - This result is cached globally + * @see MainUtil#getRegions(Plot) + * @return + */ + public Set getRegions() { + return MainUtil.getRegions(this); } /** @@ -819,13 +934,13 @@ public class Plot { * @see ChunkManager#swap(String, bot1, top1, bot2, top2) to swap terrain * @see MainUtil#getPlotSelectionIds(PlotId, PlotId) to get the plots inside a selection * @see MainUtil#swapData(String, PlotId, PlotId, Runnable) to swap plot settings - * @param other The other plot id to swap with + * @param other The other plot to swap with * @param whenDone A task to run when finished, or null * @see MainUtil#swapData(String, PlotId, PlotId, Runnable) * @return boolean if swap was successful */ - public boolean swap(final PlotId destination, final Runnable whenDone) { - return MainUtil.swap(world, id, destination, whenDone); + public boolean swap(final Plot destination, final Runnable whenDone) { + return MainUtil.move(this, destination, whenDone, true); } /** @@ -836,7 +951,7 @@ public class Plot { * @return if the move was successful */ public boolean move(final Plot destination, final Runnable whenDone) { - return MainUtil.move(this, destination, whenDone); + return MainUtil.move(this, destination, whenDone, false); } /** @@ -846,8 +961,8 @@ public class Plot { * @param whenDone The task to run when done * @return If the copy was successful */ - public boolean copy(final PlotId destination, final Runnable whenDone) { - return MainUtil.copy(world, id, destination, whenDone); + public boolean copy(final Plot destination, final Runnable whenDone) { + return MainUtil.copy(this, destination, whenDone); } /** @@ -996,4 +1111,56 @@ public class Plot { public int hashCode() { return id.hashCode(); } + + public HashMap getFlags() { + if (settings == null) { + return new HashMap<>(0); + } + return settings.flags; + } + + public String getAlias() { + return getSettings().getAlias(); + } + + /** + * Set the raw merge data
+ * - Updates DB + * - Does not modify terrain + * @param merged + */ + public void setMerged(boolean[] merged) { + getSettings().merged = merged; + DBFunc.setMerged(this, merged); + MainUtil.connected_cache = null; + MainUtil.regions_cache = null; + } + + /** + * Set the raw merge data
+ * - Updates DB + * - Does not modify terrain + * @param merged + */ + public void setMerged(int direction, boolean value) { + if (getSettings().setMerged(direction, value)) { + DBFunc.setMerged(this, getSettings().getMerged()); + MainUtil.connected_cache = null; + MainUtil.regions_cache = null; + } + } + + public boolean[] getMerged() { + if (settings == null) { + return new boolean[] {false, false, false, false }; + } + return settings.getMerged(); + } + + public BlockLoc getPosition() { + if (settings == null) { + return new BlockLoc(0, 0, 0); + } + return settings.getPosition(); + } } diff --git a/src/main/java/com/intellectualcrafters/plot/object/PlotCluster.java b/src/main/java/com/intellectualcrafters/plot/object/PlotCluster.java index 5c5ab9496..b8b85513c 100644 --- a/src/main/java/com/intellectualcrafters/plot/object/PlotCluster.java +++ b/src/main/java/com/intellectualcrafters/plot/object/PlotCluster.java @@ -35,7 +35,7 @@ public class PlotCluster { this.pos1 = pos1; this.pos2 = pos2; this.owner = owner; - settings = new PlotSettings(null); + settings = new PlotSettings(); } public boolean isAdded(final UUID uuid) { diff --git a/src/main/java/com/intellectualcrafters/plot/object/PlotHandler.java b/src/main/java/com/intellectualcrafters/plot/object/PlotHandler.java index 4cca12155..e2095af8f 100644 --- a/src/main/java/com/intellectualcrafters/plot/object/PlotHandler.java +++ b/src/main/java/com/intellectualcrafters/plot/object/PlotHandler.java @@ -3,8 +3,10 @@ package com.intellectualcrafters.plot.object; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.Set; import java.util.UUID; +import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.database.DBFunc; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.UUIDHandler; @@ -15,13 +17,14 @@ public class PlotHandler { return new HashSet(); } if (plot.isMerged()) { - final HashSet owners = new HashSet(); - final Plot top = MainUtil.getTopPlot(plot); - final ArrayList ids = MainUtil.getPlotSelectionIds(plot.id, top.id); - for (final PlotId id : ids) { - final UUID owner = MainUtil.getPlot(plot.world, id).owner; - if (owner != null) { - owners.add(owner); + HashSet plots = MainUtil.getConnectedPlots(plot); + final HashSet owners = new HashSet(2); + UUID last = plot.owner; + owners.add(plot.owner); + for (Plot current : plots) { + if (last == null || current.owner.getMostSignificantBits() != last.getMostSignificantBits()) { + owners.add(current.owner); + last = current.owner; } } return owners; @@ -33,37 +36,49 @@ public class PlotHandler { if (plot.owner == null) { return false; } - if (plot.isMerged()) { - final Plot top = MainUtil.getTopPlot(plot); - final ArrayList ids = MainUtil.getPlotSelectionIds(plot.id, top.id); - for (final PlotId id : ids) { - final UUID owner = MainUtil.getPlot(plot.world, id).owner; - if ((owner != null) && owner.equals(uuid)) { - return true; - } + if (plot.owner.equals(uuid)) { + return true; + } + if (!plot.isMerged()) { + return false; + } + for (Plot current : MainUtil.getConnectedPlots(plot)) { + if (current.owner.equals(uuid)) { + return true; } } - return plot.owner.equals(uuid); + return false; } public static boolean isOnline(final Plot plot) { if (plot.owner == null) { return false; } - if (plot.isMerged()) { - final Plot top = MainUtil.getTopPlot(plot); - final ArrayList ids = MainUtil.getPlotSelectionIds(plot.id, top.id); - for (final PlotId id : ids) { - final UUID owner = MainUtil.getPlot(plot.world, id).owner; - if (owner != null) { - if (UUIDHandler.getPlayer(owner) != null) { - return true; - } - } - } - return false; + if (!plot.isMerged()) { + return UUIDHandler.getPlayer(plot.owner) != null; + } + for (Plot current : MainUtil.getConnectedPlots(plot)) { + if (current.owner != null && UUIDHandler.getPlayer(current.owner) != null) { + return true; + } + } + return false; + } + + public static void setOwner(Plot plot, UUID owner) { + if (!plot.isMerged()) { + if (!plot.owner.equals(owner)) { + plot.owner = owner; + DBFunc.setOwner(plot, owner); + } + return; + } + for (Plot current : MainUtil.getConnectedPlots(plot)) { + if (!owner.equals(current.owner)) { + current.owner = owner; + DBFunc.setOwner(current, owner); + } } - return UUIDHandler.getPlayer(plot.owner) != null; } public static boolean sameOwners(final Plot plot1, final Plot plot2) { @@ -79,30 +94,116 @@ public class PlotHandler { if (plot.owner == null) { return false; } - if (isOwner(plot, uuid)) { - return true; - } if (plot.getDenied().contains(uuid)) { return false; } if (plot.getTrusted().contains(uuid) || plot.getTrusted().contains(DBFunc.everyone)) { return true; } + if (isOwner(plot, uuid)) { + return true; + } if (plot.getMembers().contains(uuid) || plot.getMembers().contains(DBFunc.everyone)) { if (PlotHandler.isOnline(plot)) { return true; } } - if (plot.isMerged()) { - final Plot top = MainUtil.getTopPlot(plot); - final ArrayList ids = MainUtil.getPlotSelectionIds(plot.id, top.id); - for (final PlotId id : ids) { - final UUID owner = MainUtil.getPlot(plot.world, id).owner; - if ((owner != null) && owner.equals(uuid)) { - return true; - } - } - } return false; } + + public static void setDenied(Plot plot, Set uuids) { + boolean larger = uuids.size() > plot.getDenied().size(); + HashSet intersection = new HashSet<>(larger ? plot.getDenied() : uuids); + intersection.retainAll(larger ? uuids : plot.getDenied()); + uuids.removeAll(intersection); + HashSet toRemove = new HashSet<>(plot.getDenied()); + toRemove.removeAll(intersection); + for (UUID uuid : toRemove) { + plot.removeDenied(uuid); + } + for (UUID uuid : uuids) { + plot.addDenied(uuid); + } + } + + public static void setTrusted(Plot plot, Set uuids) { + boolean larger = uuids.size() > plot.getTrusted().size(); + HashSet intersection = new HashSet<>(larger ? plot.getTrusted() : uuids); + intersection.retainAll(larger ? uuids : plot.getTrusted()); + uuids.removeAll(intersection); + HashSet toRemove = new HashSet<>(plot.getTrusted()); + toRemove.removeAll(intersection); + for (UUID uuid : toRemove) { + plot.removeTrusted(uuid); + } + for (UUID uuid : uuids) { + plot.addTrusted(uuid); + } + } + + public static void setMembers(Plot plot, Set uuids) { + boolean larger = uuids.size() > plot.getMembers().size(); + HashSet intersection = new HashSet<>(larger ? plot.getMembers() : uuids); + intersection.retainAll(larger ? uuids : plot.getMembers()); + uuids.removeAll(intersection); + HashSet toRemove = new HashSet<>(plot.getMembers()); + toRemove.removeAll(intersection); + for (UUID uuid : toRemove) { + plot.removeMember(uuid); + } + for (UUID uuid : uuids) { + plot.addMember(uuid); + } + } + + public static void set(Plot plot, Set uuids) { + boolean larger = uuids.size() > plot.getDenied().size(); + HashSet intersection = new HashSet<>(larger ? plot.getDenied() : uuids); + intersection.retainAll(larger ? uuids : plot.getDenied()); + uuids.removeAll(intersection); + HashSet toRemove = new HashSet<>(plot.getDenied()); + toRemove.removeAll(intersection); + for (UUID uuid : toRemove) { + plot.removeDenied(uuid); + } + for (UUID uuid : uuids) { + plot.addDenied(uuid); + } + } + + public static void addDenied(Plot plot, UUID uuid) { + for (Plot current : MainUtil.getConnectedPlots(plot)) { + if (current.getDenied().add(uuid)) { + DBFunc.setDenied(current, uuid); + } + } + } + + public static void addMember(Plot plot, UUID uuid) { + for (Plot current : MainUtil.getConnectedPlots(plot)) { + if (current.getMembers().add(uuid)) { + DBFunc.setMember(current, uuid); + } + } + } + + public static void addTrusted(Plot plot, UUID uuid) { + for (Plot current : MainUtil.getConnectedPlots(plot)) { + if (current.getTrusted().add(uuid)) { + DBFunc.setTrusted(current, uuid); + } + } + } + + public static boolean unclaim(Plot plot) { + if (plot.owner == null) { + return false; + } + for (Plot current : MainUtil.getConnectedPlots(plot)) { + current.settings = null; + PS.get().removePlot(current.world, current.id, true); + DBFunc.delete(current); + } + return true; + } } diff --git a/src/main/java/com/intellectualcrafters/plot/object/PlotSettings.java b/src/main/java/com/intellectualcrafters/plot/object/PlotSettings.java index 1671a2abe..533329c89 100644 --- a/src/main/java/com/intellectualcrafters/plot/object/PlotSettings.java +++ b/src/main/java/com/intellectualcrafters/plot/object/PlotSettings.java @@ -33,24 +33,19 @@ import com.intellectualcrafters.plot.object.comment.PlotComment; * plot settings * */ -@SuppressWarnings("unused") public class PlotSettings { - /** - * Plot - */ - private final Plot plot; /** * merged plots */ - private boolean[] merged = new boolean[] { false, false, false, false }; + public boolean[] merged = new boolean[] { false, false, false, false }; /** * plot alias */ - private String alias; + public String alias = ""; /** * Comments */ - private List comments = null; + public List comments = null; /** * The ratings for a plot @@ -71,9 +66,7 @@ public class PlotSettings { * * @param plot object */ - public PlotSettings(final Plot plot) { - alias = ""; - this.plot = plot; + public PlotSettings() { flags = new HashMap<>(); } @@ -103,8 +96,12 @@ public class PlotSettings { this.merged = merged; } - public void setMerged(final int direction, final boolean merged) { - this.merged[direction] = merged; + public boolean setMerged(final int direction, final boolean merged) { + if (this.merged[direction] != merged) { + this.merged[direction] = merged; + return true; + } + return false; } public BlockLoc getPosition() { @@ -131,8 +128,8 @@ public class PlotSettings { this.alias = alias; } - public String getJoinMessage() { - final Flag greeting = FlagManager.getPlotFlag(plot, "greeting"); + public String getJoinMessage(String world) { + final Flag greeting = FlagManager.getSettingFlag(world, this, "greeting"); if (greeting != null) { return greeting.getValueString(); } @@ -144,8 +141,8 @@ public class PlotSettings { * * @return Farewell flag */ - public String getLeaveMessage() { - final Flag farewell = FlagManager.getPlotFlag(plot, "farewell"); + public String getLeaveMessage(String world) { + final Flag farewell = FlagManager.getSettingFlag(world, this, "farewell"); if (farewell != null) { return farewell.getValueString(); } diff --git a/src/main/java/com/intellectualcrafters/plot/object/PlotWorld.java b/src/main/java/com/intellectualcrafters/plot/object/PlotWorld.java index 9072527d5..d5f4e58b7 100644 --- a/src/main/java/com/intellectualcrafters/plot/object/PlotWorld.java +++ b/src/main/java/com/intellectualcrafters/plot/object/PlotWorld.java @@ -63,80 +63,7 @@ public abstract class PlotWorld { public final static int MAX_BUILD_HEIGHT_DEFAULT = 256; public final static int MIN_BUILD_HEIGHT_DEFAULT = 1; public final static PlotGamemode GAMEMODE_DEFAULT = PlotGamemode.CREATIVE; - // are plot clusters enabled - // require claim in cluster - // TODO make this configurable - // make non static and static_default_valu + add config option - public static int[] BLOCKS; - static { - BLOCKS = new int[] { - 1, - 2, - 3, - 4, - 5, - 7, - 14, - 15, - 16, - 17, - 19, - 21, - 22, - 23, - 24, - 25, - 35, - 41, - 42, - 43, - 45, - 47, - 48, - 49, - 52, - 56, - 57, - 58, - 61, - 62, - 73, - 74, - 80, - 82, - 84, - 86, - 87, - 88, - 91, - 97, - 98, - 99, - 100, - 103, - 110, - 112, - 120, - 121, - 123, - 124, - 125, - 129, - 133, - 153, - 155, - 159, - 162, - 165, - 166, - 168, - 170, - 172, - 173, - 174, - 179, - 181 }; - } + public final String worldname; public int MAX_PLOT_MEMBERS; public boolean AUTO_MERGE; @@ -183,6 +110,9 @@ public abstract class PlotWorld { return false; } final PlotWorld plotworld = (PlotWorld) obj; + if (this.worldname.equals(plotworld.worldname)) { + return true; + } final ConfigurationSection section = PS.get().config.getConfigurationSection("worlds"); for (final ConfigurationNode setting : plotworld.getSettingNodes()) { final Object constant = section.get(plotworld.worldname + "." + setting.getConstant()); diff --git a/src/main/java/com/intellectualcrafters/plot/object/Rating.java b/src/main/java/com/intellectualcrafters/plot/object/Rating.java index f09c0ffcc..270fa6def 100644 --- a/src/main/java/com/intellectualcrafters/plot/object/Rating.java +++ b/src/main/java/com/intellectualcrafters/plot/object/Rating.java @@ -39,7 +39,7 @@ public class Rating { public List getCategories() { if (ratingMap.size() == 1) { - return new ArrayList<>(); + return new ArrayList<>(0); } return new ArrayList<>(ratingMap.keySet()); } diff --git a/src/main/java/com/intellectualcrafters/plot/object/RegionWrapper.java b/src/main/java/com/intellectualcrafters/plot/object/RegionWrapper.java index deb1d3ce8..b39ddda30 100644 --- a/src/main/java/com/intellectualcrafters/plot/object/RegionWrapper.java +++ b/src/main/java/com/intellectualcrafters/plot/object/RegionWrapper.java @@ -33,4 +33,29 @@ public class RegionWrapper { public boolean isIn(final int x, final int z) { return ((x >= minX) && (x <= maxX) && (z >= minZ) && (z <= maxZ)); } + + @Override + public int hashCode() { + return minX + 13 * maxX + 23 * minZ + 39 * maxZ; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (obj instanceof RegionWrapper) { + RegionWrapper other = (RegionWrapper) obj; + return minX == other.minX && minZ == other.minZ && minY == other.minY && maxX == other.maxX && maxZ == other.maxZ && maxY == other.maxY; + } + return false; + } + + @Override + public String toString() { + return minX + "->" + maxX + "," + minZ + "->" + maxZ; + } } diff --git a/src/main/java/com/intellectualcrafters/plot/util/BO3Handler.java b/src/main/java/com/intellectualcrafters/plot/util/BO3Handler.java index 9b2cb340f..eb23f983e 100644 --- a/src/main/java/com/intellectualcrafters/plot/util/BO3Handler.java +++ b/src/main/java/com/intellectualcrafters/plot/util/BO3Handler.java @@ -5,6 +5,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.StandardOpenOption; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map.Entry; @@ -17,8 +18,10 @@ import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotBlock; +import com.intellectualcrafters.plot.object.PlotId; import com.intellectualcrafters.plot.object.PlotPlayer; import com.intellectualcrafters.plot.object.PlotWorld; +import com.intellectualcrafters.plot.object.RegionWrapper; public class BO3Handler { @@ -54,54 +57,60 @@ public class BO3Handler { return false; } final String alias = plot.toString(); - final Location pos1 = plot.getBottom(); - final Location pos2 = plot.getTop(); + Location[] corners = MainUtil.getCorners(plot); + Location bot = corners[0]; + Location top = corners[1]; final ClassicPlotWorld cpw = (ClassicPlotWorld) plotworld; final int height = cpw.PLOT_HEIGHT; - final int cx = (pos1.getX() + pos2.getX()) / 2; - final int cz = (pos1.getZ() + pos2.getZ()) / 2; + final int cx = (bot.getX() + top.getX()) / 2; + final int cz = (bot.getZ() + top.getZ()) / 2; final HashMap map = new HashMap<>(); + HashSet regions = MainUtil.getRegions(plot); boolean content = false; - for (int x = pos1.getX(); x <= pos2.getX(); x++) { - final int X = ((x + 7) - cx) >> 4; - final int xx = (x - cx) % 16; - for (int z = pos1.getZ(); z <= pos2.getZ(); z++) { - final int Z = ((z + 7) - cz) >> 4; - final int zz = (z - cz) % 16; - final ChunkLoc loc = new ChunkLoc(X, Z); - BO3 bo3 = map.get(loc); - for (int y = 1; y < height; y++) { - final PlotBlock block = BlockManager.manager.getBlock(new Location(plot.world, x, y, z)); - if ((block != null) && !contains(cpw.MAIN_BLOCK, block)) { + for (RegionWrapper region : regions) { + Location pos1 = new Location(plot.world, region.minX, region.minY, region.minZ); + Location pos2 = new Location(plot.world, region.maxX, region.maxY, region.maxZ); + for (int x = pos1.getX(); x <= pos2.getX(); x++) { + final int X = ((x + 7) - cx) >> 4; + final int xx = (x - cx) % 16; + for (int z = pos1.getZ(); z <= pos2.getZ(); z++) { + final int Z = ((z + 7) - cz) >> 4; + final int zz = (z - cz) % 16; + final ChunkLoc loc = new ChunkLoc(X, Z); + BO3 bo3 = map.get(loc); + for (int y = 1; y < height; y++) { + final PlotBlock block = BlockManager.manager.getBlock(new Location(plot.world, x, y, z)); + if ((block != null) && !contains(cpw.MAIN_BLOCK, block)) { + if (bo3 == null) { + bo3 = new BO3(alias, loc); + map.put(loc, bo3); + content = true; + } + bo3.addBlock(xx, y - height - 1, zz, block); + } + } + final PlotBlock floor = BlockManager.manager.getBlock(new Location(plot.world, x, height, z)); + if ((floor != null) && !contains(cpw.TOP_BLOCK, floor)) { if (bo3 == null) { bo3 = new BO3(alias, loc); map.put(loc, bo3); content = true; } - bo3.addBlock(xx, y - height - 1, zz, block); + bo3.addBlock(xx, -1, zz, floor); } - } - final PlotBlock floor = BlockManager.manager.getBlock(new Location(plot.world, x, height, z)); - if ((floor != null) && !contains(cpw.TOP_BLOCK, floor)) { - if (bo3 == null) { - bo3 = new BO3(alias, loc); - map.put(loc, bo3); - content = true; - } - bo3.addBlock(xx, -1, zz, floor); - } - for (int y = height + 1; y < 256; y++) { - final PlotBlock block = BlockManager.manager.getBlock(new Location(plot.world, x, y, z)); - if ((block != null) && (block.id != 0)) { - if (bo3 == null) { - bo3 = new BO3(alias, loc); - map.put(loc, bo3); - content = true; + for (int y = height + 1; y < 256; y++) { + final PlotBlock block = BlockManager.manager.getBlock(new Location(plot.world, x, y, z)); + if ((block != null) && (block.id != 0)) { + if (bo3 == null) { + bo3 = new BO3(alias, loc); + map.put(loc, bo3); + content = true; + } + bo3.addBlock(xx, y - height - 1, zz, block); } - bo3.addBlock(xx, y - height - 1, zz, block); } } } diff --git a/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java b/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java index d7358b824..df813c5ab 100644 --- a/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java +++ b/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java @@ -3,6 +3,7 @@ package com.intellectualcrafters.plot.util; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Set; import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.Location; @@ -102,7 +103,7 @@ public abstract class ChunkManager { public abstract boolean unloadChunk(final String world, final ChunkLoc loc, final boolean save, final boolean safe); - public abstract List getChunkChunks(final String world); + public abstract Set getChunkChunks(final String world); public abstract void regenerateChunk(final String world, final ChunkLoc loc); @@ -114,6 +115,9 @@ public abstract class ChunkManager { public abstract Plot hasPlot(String world, ChunkLoc chunk); + /** + * Copy a region to a new location (in the same world) + */ public abstract boolean copyRegion(final Location pos1, final Location pos2, final Location newPos, final Runnable whenDone); /** @@ -129,7 +133,5 @@ public abstract class ChunkManager { public abstract void clearAllEntities(final Location pos1, final Location pos2); - public abstract void swap(final String world, final PlotId id, final PlotId plotid); - - public abstract void swap(final String worldname, final Location bot1, final Location top1, final Location bot2, final Location top2); + public abstract void swap(final Location bot1, final Location top1, final Location bot2, final Location top2, Runnable whenDone); } diff --git a/src/main/java/com/intellectualcrafters/plot/util/ClusterManager.java b/src/main/java/com/intellectualcrafters/plot/util/ClusterManager.java index 51f89f29e..d58db1126 100644 --- a/src/main/java/com/intellectualcrafters/plot/util/ClusterManager.java +++ b/src/main/java/com/intellectualcrafters/plot/util/ClusterManager.java @@ -42,7 +42,7 @@ public class ClusterManager { if (clusters.containsKey(world)) { return clusters.get(world); } - return new HashSet<>(); + return new HashSet<>(0); } public static int getPlayerClusterCount(final String world, final PlotPlayer player) { @@ -74,7 +74,7 @@ public class ClusterManager { if (toReturn.getY() == 0) { final PlotManager manager = PS.get().getPlotManager(cluster.world); final PlotWorld plotworld = PS.get().getPlotWorld(cluster.world); - final Location loc = manager.getSignLoc(plotworld, MainUtil.getPlot(cluster.world, center)); + final Location loc = manager.getSignLoc(plotworld, MainUtil.getPlotAbs(cluster.world, center)); toReturn.setY(loc.getY()); } } else { @@ -124,13 +124,13 @@ public class ClusterManager { final PlotManager manager = PS.get().getPlotManager(world); final PlotWorld plotworld = PS.get().getPlotWorld(world); final Location bot = manager.getPlotBottomLocAbs(plotworld, cluster.getP1()); - final Location top = manager.getPlotTopLocAbs(plotworld, cluster.getP2()).add(1, 0, 1); - return (bot.getX() < loc.getX()) && (bot.getZ() < loc.getZ()) && (top.getX() > loc.getX()) && (top.getZ() > loc.getZ()); + final Location top = manager.getPlotTopLocAbs(plotworld, cluster.getP2()); + return (bot.getX() <= loc.getX()) && (bot.getZ() <= loc.getZ()) && (top.getX() >= loc.getX()) && (top.getZ() >= loc.getZ()); } public static HashSet getIntersects(final String world, final PlotClusterId id) { if (!clusters.containsKey(world)) { - return new HashSet<>(); + return new HashSet<>(0); } final HashSet list = new HashSet(); for (final PlotCluster cluster : clusters.get(world)) { @@ -236,7 +236,7 @@ public class ClusterManager { } public static PlotId estimatePlotId(final Location loc) { - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if (plot != null) { return plot.id; } diff --git a/src/main/java/com/intellectualcrafters/plot/util/EventUtil.java b/src/main/java/com/intellectualcrafters/plot/util/EventUtil.java index 45d691f2e..beca331a6 100644 --- a/src/main/java/com/intellectualcrafters/plot/util/EventUtil.java +++ b/src/main/java/com/intellectualcrafters/plot/util/EventUtil.java @@ -62,7 +62,7 @@ public abstract class EventUtil { public abstract void callMember(final PlotPlayer initiator, final Plot plot, final UUID player, final boolean added); public boolean checkPlayerBlockEvent(final PlotPlayer pp, final PlayerBlockEventType type, final Location loc, final LazyBlock block, final boolean notifyPerms) { - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); final UUID uuid = pp.getUUID(); if (plot == null) { if (!MainUtil.isPlotAreaAbs(loc)) { diff --git a/src/main/java/com/intellectualcrafters/plot/util/ExpireManager.java b/src/main/java/com/intellectualcrafters/plot/util/ExpireManager.java index 5bcb5ea07..d23096a9b 100644 --- a/src/main/java/com/intellectualcrafters/plot/util/ExpireManager.java +++ b/src/main/java/com/intellectualcrafters/plot/util/ExpireManager.java @@ -129,7 +129,7 @@ public class ExpireManager { } } if (plot.isMerged()) { - MainUtil.unlinkPlot(plot, true); + MainUtil.unlinkPlot(plot, true, false); } plot.deletePlot(null); expiredPlots.get(world).remove(plot); @@ -144,7 +144,7 @@ public class ExpireManager { } } }; - if (MainUtil.runners.containsKey(plot)) { + if (plot.getRunning() > 0) { PS.debug("$2[&5Expire&dManager$2] &bSkipping plot in use: " + plot); expiredPlots.get(world).remove(plot); run(); diff --git a/src/main/java/com/intellectualcrafters/plot/util/MainUtil.java b/src/main/java/com/intellectualcrafters/plot/util/MainUtil.java index 09bc229dd..249cd0bee 100644 --- a/src/main/java/com/intellectualcrafters/plot/util/MainUtil.java +++ b/src/main/java/com/intellectualcrafters/plot/util/MainUtil.java @@ -20,20 +20,26 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// package com.intellectualcrafters.plot.util; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.Settings; import com.intellectualcrafters.plot.database.DBFunc; +import com.intellectualcrafters.plot.flag.Flag; import com.intellectualcrafters.plot.object.BlockLoc; import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.Location; @@ -45,6 +51,7 @@ import com.intellectualcrafters.plot.object.PlotManager; import com.intellectualcrafters.plot.object.PlotPlayer; import com.intellectualcrafters.plot.object.PlotWorld; import com.intellectualcrafters.plot.object.PseudoRandom; +import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.object.RunnableVal; import com.plotsquared.listener.PlotListener; @@ -88,6 +95,166 @@ public class MainUtil { } } + /** + * Attempt to find the largest rectangular region in a plot (as plots can form non rectangular shapes) + * @param plot + * @return + */ + public static RegionWrapper getLargestRegion(Plot plot) { + HashSet regions = getRegions(plot); + RegionWrapper max = null; + int area = 0; + for (RegionWrapper region : regions) { + int current = (region.maxX - region.minX + 1) * (region.maxZ - region.minZ + 1); + if (current > area) { + max = region; + area = current; + } + } + return max; + } + + /** + * This will combine each plot into effective rectangular regions + * @param plot + * @return + */ + public static HashSet getRegions(Plot origin) { + if (regions_cache != null && connected_cache != null && connected_cache.contains(origin)) { + return regions_cache; + } + if (!origin.isMerged()) { + final Location pos1 = MainUtil.getPlotBottomLocAbs(origin.world, origin.id); + final Location pos2 = MainUtil.getPlotTopLocAbs(origin.world, origin.id); + connected_cache = new HashSet<>(Arrays.asList(origin)); + regions_cache = new HashSet<>(1); + regions_cache.add(new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getY(), pos2.getY(), pos1.getZ(), pos2.getZ())); + return regions_cache; + } + +// Create a list of ALL edges from your rectangles. One rectangle has 4 edges. +// Let the Edge be a class with properly defined compareTo() and equals(). +// Sort the edges list (uses comapreTo). +// Iterate through the list. If the same edge is present in the list TWICE, remove them both from the list. +// The remaining edges are the edges of your polygon. + + + HashSet plots = getConnectedPlots(origin); + regions_cache = new HashSet<>(); + HashSet visited = new HashSet<>(); + ArrayList ids; + for (Plot current : plots) { + if (visited.contains(current.id)) { + continue; + } + boolean merge = true; + boolean tmp = true; + PlotId bot = new PlotId(current.id.x, current.id.y); + PlotId top = new PlotId(current.id.x, current.id.y); + while (merge) { + merge = false; + ids = getPlotSelectionIds(new PlotId(bot.x, bot.y - 1), new PlotId(top.x, bot.y - 1)); + tmp = true; + for (PlotId id : ids) { + Plot plot = MainUtil.getPlotAbs(origin.world, id); + if (plot == null || !plot.getMerged(2) || (visited.contains(plot.id))) { + tmp = false; + } + } + if (tmp) { + merge = true; + bot.y--; + } + ids = getPlotSelectionIds(new PlotId(top.x + 1, bot.y), new PlotId(top.x + 1, top.y)); + tmp = true; + for (PlotId id : ids) { + Plot plot = MainUtil.getPlotAbs(origin.world, id); + if (plot == null || !plot.getMerged(3) || (visited.contains(plot.id))) { + tmp = false; + } + } + if (tmp) { + merge = true; + top.x++; + } + ids = getPlotSelectionIds(new PlotId(bot.x, top.y + 1), new PlotId(top.x, top.y + 1)); + tmp = true; + for (PlotId id : ids) { + Plot plot = MainUtil.getPlotAbs(origin.world, id); + if (plot == null || !plot.getMerged(0) || (visited.contains(plot.id))) { + tmp = false; + } + } + if (tmp) { + merge = true; + top.y++; + } + ids = getPlotSelectionIds(new PlotId(bot.x - 1, bot.y), new PlotId(bot.x - 1, top.y)); + tmp = true; + for (PlotId id : ids) { + Plot plot = MainUtil.getPlotAbs(origin.world, id); + if (plot == null || !plot.getMerged(1) || (visited.contains(plot.id))) { + tmp = false; + } + } + if (tmp) { + merge = true; + bot.x--; + } + } + Location gtopabs = getPlotAbs(origin.world, top).getTopAbs(); + Location gbotabs = getPlotAbs(origin.world, bot).getBottomAbs(); + for (PlotId id : getPlotSelectionIds(bot, top)) { + visited.add(id); + } + for (int x = bot.x; x <= top.x; x++) { + Plot plot = getPlotAbs(current.world, new PlotId(x, top.y)); + if (plot.getMerged(2)) { + // south wedge + Location toploc = getPlotTopLoc_(plot); + Location botabs = plot.getBottomAbs(); + Location topabs = plot.getTopAbs(); + regions_cache.add(new RegionWrapper(botabs.getX(), topabs.getX(), topabs.getZ() + 1, toploc.getZ())); + if (plot.getMerged(5)) { + regions_cache.add(new RegionWrapper(topabs.getX() + 1, toploc.getX(), topabs.getZ() + 1, toploc.getZ())); + // intersection + } + } + } + + for (int y = bot.y; y <= top.y; y++) { + Plot plot = getPlotAbs(current.world, new PlotId(top.x, y)); + if (plot.getMerged(1)) { + // east wedge + Location toploc = getPlotTopLoc_(plot); + Location botabs = plot.getBottomAbs(); + Location topabs = plot.getTopAbs(); + regions_cache.add(new RegionWrapper(topabs.getX() + 1, toploc.getX(), botabs.getZ(), topabs.getZ())); + if (plot.getMerged(5)) { + regions_cache.add(new RegionWrapper(topabs.getX() + 1, toploc.getX(), topabs.getZ() + 1, toploc.getZ())); + // intersection + } + } + } + regions_cache.add(new RegionWrapper(gbotabs.getX(), gtopabs.getX(), gbotabs.getZ(), gtopabs.getZ())); + } + return regions_cache; + } + + public static int hash(boolean[] array) { + if (array.length == 4) { + if (!array[0] && !array[1] && !array[2] && !array[3]) { + return 0; + } + return ((array[0] ? 1 : 0) << 3) + ((array[1] ? 1 : 0) << 2) + ((array[2] ? 1 : 0) << 1) + (array[3] ? 1 : 0); + } + int n = 0; + for (int j = 0; j < array.length; ++j) { + n = (n << 1) + (array[j] ? 1 : 0); + } + return n; + } + public static boolean isPlotArea(final Location location) { final PlotWorld plotworld = PS.get().getPlotWorld(location.getWorld()); if (plotworld == null) { @@ -132,10 +299,19 @@ public class MainUtil { }, 1); } - public static Location getPlotCenter(final Plot plot) { - final Location bot = getPlotBottomLoc(plot.world, plot.id); - final Location top = getPlotTopLoc(plot.world, plot.id).add(1, 0, 1); - return new Location(plot.world, bot.getX() + ((top.getX() - bot.getX()) / 2), 0, bot.getZ() + ((top.getZ() - bot.getZ()) / 2)); + public static void plotTask(Plot plot, RunnableVal run) { + if (!plot.isMerged()) { + run.value = plot; + run.run(); + return; + } + for (Plot current : getConnectedPlots(plot)) { + run.value = current; + run.run(); + if (run.value == null) { + break; + } + } } public static List getPlotsBySearch(final String search) { @@ -198,7 +374,7 @@ public class MainUtil { if ((world != null) && plot.world.equals(world)) { count++; } - if ((alias != null) && alias.equals(plot.getSettings().getAlias())) { + if ((alias != null) && alias.equals(plot.getAlias())) { count += 2; } if (count != 0) { @@ -223,7 +399,7 @@ public class MainUtil { } return null; } - return getPlot(player.getLocation()); + return getPlotAbs(player.getLocation()); } String worldname = null; PlotId id = null; @@ -247,7 +423,7 @@ public class MainUtil { worldname = PS.get().getPlotWorlds().iterator().next(); } for (final Plot p : PS.get().getPlotsInWorld(worldname)) { - final String name = p.getSettings().getAlias(); + final String name = p.getAlias(); if ((name.length() != 0) && name.equalsIgnoreCase(arg)) { return p; } @@ -255,7 +431,7 @@ public class MainUtil { for (final String world : PS.get().getPlotWorlds()) { if (!world.endsWith(worldname)) { for (final Plot p : PS.get().getPlotsInWorld(world)) { - final String name = p.getSettings().getAlias(); + final String name = p.getAlias(); if ((name.length() != 0) && name.equalsIgnoreCase(arg)) { return p; } @@ -275,7 +451,7 @@ public class MainUtil { } return null; } - return getPlot(worldname, id); + return getPlotAbs(worldname, id); } /** @@ -302,61 +478,54 @@ public class MainUtil { return MainUtil.mergePlots(world, plotIds, true, true); } - public static boolean unlinkPlot(final Plot plot, final boolean createRoad) { - final String world = plot.world; - final PlotId pos1 = MainUtil.getBottomPlot(plot).id; - final PlotId pos2 = MainUtil.getTopPlot(plot).id; - final ArrayList ids = MainUtil.getPlotSelectionIds(pos1, pos2); - final boolean result = EventUtil.manager.callUnlink(world, ids); + /** + * Unlink the plot and all connected plots + * @param plot + * @param createRoad + * @return + */ + public static boolean unlinkPlot(final Plot plot, final boolean createRoad, boolean createSign) { + if (!plot.isMerged()) { + return false; + } + HashSet plots = getConnectedPlots(plot); + ArrayList ids = new ArrayList<>(plots.size()); + for (Plot current : plots) { + current.setHome(null); + ids.add(current.id); + } + final boolean result = EventUtil.manager.callUnlink(plot.world, ids); if (!result) { return false; } - final PlotManager manager = PS.get().getPlotManager(world); - final PlotWorld plotworld = PS.get().getPlotWorld(world); + plot.removeSign(); + final PlotManager manager = PS.get().getPlotManager(plot.world); + final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); manager.startPlotUnlink(plotworld, ids); - for (final PlotId id : ids) { - final Plot myplot = PS.get().getPlot(world, id); - if (plot == null) { - continue; - } - if (plot.trusted != null) { - myplot.trusted = plot.trusted; - } - if (plot.denied != null) { - myplot.denied = plot.denied; - } - myplot.getSettings().setMerged(new boolean[] { false, false, false, false }); - DBFunc.setMerged(myplot, myplot.getSettings().getMerged()); - } if ((plotworld.TERRAIN != 3) && createRoad) { - for (int x = pos1.x; x <= pos2.x; x++) { - for (int y = pos1.y; y <= pos2.y; y++) { - final boolean lx = x < pos2.x; - final boolean ly = y < pos2.y; - final Plot p = MainUtil.getPlot(world, new PlotId(x, y)); - if (lx) { - manager.createRoadEast(plotworld, p); - if (ly) { - manager.createRoadSouthEast(plotworld, p); + for (Plot current : plots) { + if (current.getMerged(1)) { + manager.createRoadEast(plotworld, current); + if (current.getMerged(2)) { + manager.createRoadSouth(plotworld, current); + if (current.getMerged(5)) { + manager.createRoadSouthEast(plotworld, current); } } - if (ly) { - manager.createRoadSouth(plotworld, p); - } - MainUtil.setSign(UUIDHandler.getName(plot.owner), plot); } + else if (current.getMerged(2)) { + manager.createRoadSouth(plotworld, current); + } + } + } + for (Plot current : plots) { + boolean[] merged = new boolean[] { false, false, false, false }; + current.setMerged(merged); + if (createSign) { + MainUtil.setSign(getName(current.owner), current); } } manager.finishPlotUnlink(plotworld, ids); - for (final PlotId id : ids) { - final Plot myPlot = MainUtil.getPlot(world, id); - if (plot.hasOwner()) { - final String name = UUIDHandler.getName(myPlot.owner); - if (name != null) { - MainUtil.setSign(name, myPlot); - } - } - } return true; } @@ -403,28 +572,6 @@ public class MainUtil { return (p1 != null) && ((p2 == null) || !p1.equals(p2)); } - public static ArrayList getMaxPlotSelectionIds(final String world, PlotId pos1, PlotId pos2) { - - final Plot plot1 = PS.get().getPlot(world, pos1); - final Plot plot2 = PS.get().getPlot(world, pos2); - - if (plot1 != null) { - pos1 = getBottomPlot(plot1).id; - } - - if (plot2 != null) { - pos2 = getTopPlot(plot2).id; - } - - final ArrayList myplots = new ArrayList<>(); - for (int x = pos1.x; x <= pos2.x; x++) { - for (int y = pos1.y; y <= pos2.y; y++) { - myplots.add(new PlotId(x, y)); - } - } - return myplots; - } - /** * Get the number of plots for a player * @@ -436,7 +583,7 @@ public class MainUtil { final UUID uuid = plr.getUUID(); int count = 0; for (final Plot plot : PS.get().getPlotsInWorld(world)) { - if (plot.hasOwner() && plot.owner.equals(uuid) && (!Settings.DONE_COUNTS_TOWARDS_LIMIT || !plot.getSettings().flags.containsKey("done"))) { + if (plot.hasOwner() && plot.owner.equals(uuid) && (!Settings.DONE_COUNTS_TOWARDS_LIMIT || !plot.getFlags().containsKey("done"))) { count++; } } @@ -449,6 +596,9 @@ public class MainUtil { * @return */ public static int getPlayerPlotCount(final PlotPlayer plr) { + if (!Settings.GLOBAL_LIMIT) { + return getPlayerPlotCount(plr.getLocation().getWorld(), plr); + } int count = 0; for (final String world : PS.get().getPlotWorldsString()) { count += getPlayerPlotCount(world, plr); @@ -456,15 +606,34 @@ public class MainUtil { return count; } - public static Location getDefaultHome(final Plot plot) { + public static Plot getPlot(Plot plot) { + if (plot == null) { + return null; + } + return plot.getBasePlot(false); + } + + public static Plot getPlot(Location loc) { + return getPlot(getPlotAbs(loc)); + } + + public static Plot getPlot(String world, PlotId id) { + if (id == null) { + return null; + } + return getPlot(getPlotAbs(world, id)); + } + + public static Location getDefaultHome(Plot plot) { + plot = plot.getBasePlot(false); final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); if (plotworld.DEFAULT_HOME != null) { - final Location bot = getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); final PlotManager manager = PS.get().getPlotManager(plot.world); final int x; final int z; + Location bot = plot.getBottomAbs(); if ((plotworld.DEFAULT_HOME.x == Integer.MAX_VALUE) && (plotworld.DEFAULT_HOME.z == Integer.MAX_VALUE)) { - final Location top = getPlotTopLoc(plot.world, plot.id); + Location top = plot.getTopAbs(); x = ((top.getX() - bot.getX()) / 2) + bot.getX(); z = ((top.getZ() - bot.getZ()) / 2) + bot.getZ(); } else { @@ -474,8 +643,8 @@ public class MainUtil { final int y = Math.max(getHeighestBlock(plot.world, x, z), manager.getSignLoc(PS.get().getPlotWorld(plot.world), plot).getY()); return new Location(plot.world, x, y + 1, z); } - final Location top = getPlotTopLoc(plot.world, plot.id); - final Location bot = getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); + Location bot = plot.getBottomAbs(); + Location top = plot.getTopAbs(); final int x = ((top.getX() - bot.getX()) / 2) + bot.getX(); final int z = bot.getZ() - 1; final PlotManager manager = PS.get().getPlotManager(plot.world); @@ -483,14 +652,14 @@ public class MainUtil { return new Location(plot.world, x, y + 1, z); } - public static boolean teleportPlayer(final PlotPlayer player, final Location from, final Plot plot) { - final Plot bot = MainUtil.getBottomPlot(plot); + public static boolean teleportPlayer(final PlotPlayer player, final Location from, Plot plot) { + plot = plot.getBasePlot(false); final boolean result = EventUtil.manager.callTeleport(player, from, plot); if (result) { final Location location; if (PS.get().getPlotWorld(plot.world).HOME_ALLOW_NONMEMBER || plot.isAdded(player.getUUID())) { - location = MainUtil.getPlotHome(bot); + location = MainUtil.getPlotHome(plot); } else { location = getDefaultHome(plot); } @@ -552,23 +721,20 @@ public class MainUtil { } public static void update(final Plot plot) { - final Location bot = getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); - final Location top = getPlotTopLoc(plot.world, plot.id); - - final int bx = bot.getX() >> 4; - final int bz = bot.getZ() >> 4; - - final int tx = (top.getX() >> 4); - final int tz = (top.getZ() >> 4); - - final ArrayList chunks = new ArrayList<>(); - - for (int x = bx; x <= tx; x++) { - for (int z = bz; z <= tz; z++) { - chunks.add(new ChunkLoc(x, z)); + TaskManager.runTaskAsync(new Runnable() { + @Override + public void run() { + final HashSet chunks = new HashSet<>(); + for (RegionWrapper region : getRegions(plot)) { + for (int x = region.minX >> 4; x <= region.maxX >> 4; x++) { + for (int z = region.minZ >> 4; z <= region.maxZ >> 4; z++) { + chunks.add(new ChunkLoc(x, z)); + } + } + } + BlockUpdateUtil.setBlockManager.update(plot.world, chunks); } - } - BlockUpdateUtil.setBlockManager.update(plot.world, chunks); + }); } public static void createWorld(final String world, final String generator) {} @@ -631,9 +797,9 @@ public class MainUtil { final int size = ((1 + pos2.x) - pos1.x) * ((1 + pos2.y) - pos1.y); final HashSet result = new HashSet<>(); if (PS.get().isPlotWorld(world)) { - if (size < PS.get().getAllPlotsRaw().get(world).size()) { + if (size < 16 || size < PS.get().getAllPlotsRaw().get(world).size()) { for (final PlotId pid : MainUtil.getPlotSelectionIds(pos1, pos2)) { - final Plot plot = MainUtil.getPlot(world, pid); + final Plot plot = MainUtil.getPlotAbs(world, pid); if (plot.hasOwner()) { if ((plot.id.x > pos1.x) || (plot.id.y > pos1.y) || (plot.id.x < pos2.x) || (plot.id.y < pos2.y)) { result.add(plot); @@ -666,15 +832,12 @@ public class MainUtil { if (plotIds.size() < 2) { return false; } - - // merged plots set db before finished merging - final PlotId pos1 = plotIds.get(0); final PlotId pos2 = plotIds.get(plotIds.size() - 1); final PlotManager manager = PS.get().getPlotManager(world); final PlotWorld plotworld = PS.get().getPlotWorld(world); - final boolean result = EventUtil.manager.callMerge(world, getPlot(world, pos1), plotIds); + final boolean result = EventUtil.manager.callMerge(world, getPlotAbs(world, pos1), plotIds); if (!result) { return false; } @@ -711,39 +874,26 @@ public class MainUtil { Plot plot2 = null; if (lx) { if (ly) { - if (!plot.getSettings().getMerged(1) || !plot.getSettings().getMerged(2)) { + if (!plot.getMerged(1) || !plot.getMerged(2)) { if (removeRoads) { MainUtil.removeRoadSouthEast(plotworld, plot); } } } - if (!plot.getSettings().getMerged(1)) { + if (!plot.getMerged(1)) { plot2 = PS.get().getPlot(world, new PlotId(x + 1, y)); mergePlot(world, plot, plot2, removeRoads); - plot.getSettings().setMerged(1, true); - plot2.getSettings().setMerged(3, true); } } if (ly) { - if (!plot.getSettings().getMerged(2)) { + if (!plot.getMerged(2)) { plot2 = PS.get().getPlot(world, new PlotId(x, y + 1)); mergePlot(world, plot, plot2, removeRoads); - plot.getSettings().setMerged(2, true); - plot2.getSettings().setMerged(0, true); } } } } manager.finishPlotMerge(plotworld, plotIds); - if (updateDatabase) { - for (int x = pos1.x; x <= pos2.x; x++) { - for (int y = pos1.y; y <= pos2.y; y++) { - final PlotId id = new PlotId(x, y); - final Plot plot = PS.get().getPlot(world, id); - DBFunc.setMerged(plot, plot.getSettings().getMerged()); - } - } - } return true; } @@ -755,7 +905,7 @@ public class MainUtil { final PlotId id = plot.id; final PlotId id2 = new PlotId(id.x + 1, id.y + 1); final Location pos1 = getPlotTopLocAbs(plot.world, id).add(1, 0, 1); - final Location pos2 = getPlotBottomLocAbs(plot.world, id2); + final Location pos2 = getPlotBottomLocAbs(plot.world, id2).subtract(1, 0, 1); pos1.setY(0); pos2.setY(256); ChunkManager.manager.regenerateRegion(pos1, pos2, null); @@ -773,7 +923,7 @@ public class MainUtil { final PlotId id2 = new PlotId(id.x + 1, id.y); final Location bot = getPlotBottomLocAbs(plot.world, id2); final Location top = getPlotTopLocAbs(plot.world, id); - final Location pos1 = new Location(plot.world, top.getX() + 1, 0, bot.getZ() + 1); + final Location pos1 = new Location(plot.world, top.getX(), 0, bot.getZ()); final Location pos2 = new Location(plot.world, bot.getX(), 256, top.getZ()); ChunkManager.manager.regenerateRegion(pos1, pos2, null); } else { @@ -790,7 +940,7 @@ public class MainUtil { final PlotId id2 = new PlotId(id.x, id.y + 1); final Location bot = getPlotBottomLocAbs(plot.world, id2); final Location top = getPlotTopLocAbs(plot.world, id); - final Location pos1 = new Location(plot.world, bot.getX() + 1, 0, top.getZ() + 1); + final Location pos1 = new Location(plot.world, bot.getX(), 0, top.getZ()); final Location pos2 = new Location(plot.world, top.getX(), 256, bot.getZ()); ChunkManager.manager.regenerateRegion(pos1, pos2, null); } else { @@ -799,34 +949,98 @@ public class MainUtil { } /** - * Merges 2 plots Removes the road inbetween
- Assumes the first plot parameter is lower
- Assumes neither - * are a Mega-plot
- Assumes plots are directly next to each other
- Does not save to DB + * Merges 2 plots Removes the road inbetween
- Assumes plots are directly next to each other
- saves to DB * * @param world * @param lesserPlot * @param greaterPlot */ - public static void mergePlot(final String world, final Plot lesserPlot, final Plot greaterPlot, final boolean removeRoads) { + public static void mergePlot(final String world, Plot lesserPlot, Plot greaterPlot, final boolean removeRoads) { final PlotWorld plotworld = PS.get().getPlotWorld(world); if (lesserPlot.id.x.equals(greaterPlot.id.x)) { - if (!lesserPlot.getSettings().getMerged(2)) { - lesserPlot.getSettings().setMerged(2, true); - greaterPlot.getSettings().setMerged(0, true); + if (lesserPlot.id.y > greaterPlot.id.y) { + Plot tmp = lesserPlot; + lesserPlot = greaterPlot; + greaterPlot = tmp; + } + if (!lesserPlot.getMerged(2)) { + lesserPlot.setMerged(2, true); + greaterPlot.setMerged(0, true); + mergeData(lesserPlot, greaterPlot); if (removeRoads) { + if (lesserPlot.getMerged(5)) { + removeRoadSouthEast(plotworld, lesserPlot); + } MainUtil.removeRoadSouth(plotworld, lesserPlot); + Plot other = getPlotAbs(world, getPlotIdRelative(lesserPlot.id, 3)); + if (other.getMerged(2) && other.getMerged(1)) { + MainUtil.removeRoadSouthEast(plotworld, other); + mergePlot(world, greaterPlot, getPlotAbs(world, getPlotIdRelative(greaterPlot.id, 3)), removeRoads); + } } } } else { - if (!lesserPlot.getSettings().getMerged(1)) { - lesserPlot.getSettings().setMerged(1, true); - greaterPlot.getSettings().setMerged(3, true); + if (lesserPlot.id.x > greaterPlot.id.x) { + Plot tmp = lesserPlot; + lesserPlot = greaterPlot; + greaterPlot = tmp; + } + if (!lesserPlot.getMerged(1)) { + lesserPlot.setMerged(1, true); + greaterPlot.setMerged(3, true); + mergeData(lesserPlot, greaterPlot); if (removeRoads) { MainUtil.removeRoadEast(plotworld, lesserPlot); + if (lesserPlot.getMerged(5)) { + removeRoadSouthEast(plotworld, lesserPlot); + } + Plot other = getPlotAbs(world, getPlotIdRelative(lesserPlot.id, 0)); + if (other.getMerged(2) && other.getMerged(1)) { + MainUtil.removeRoadSouthEast(plotworld, other); + mergePlot(world, greaterPlot, getPlotAbs(world, getPlotIdRelative(greaterPlot.id, 0)), removeRoads); + } } } } } + public static void mergeData(Plot a, Plot b) { + HashMap flags1 = a.getFlags(); + HashMap flags2 = b.getFlags(); + if ((flags1.size() != 0 || flags2.size() != 0) && !flags1.equals(flags2)) { + boolean greater = flags1.size() > flags2.size(); + if (greater) { + flags1.putAll(flags2); + } + else { + flags2.putAll(flags1); + } + HashSet net = new HashSet<>((greater ? flags1 : flags2).values()); + a.setFlags(net); + b.setFlags(net); + } + for (UUID uuid : a.getTrusted()) { + b.addTrusted(uuid); + } + for (UUID uuid : b.getTrusted()) { + a.addTrusted(uuid); + } + + for (UUID uuid : a.getMembers()) { + b.addMember(uuid); + } + for (UUID uuid : b.getMembers()) { + a.addMember(uuid); + } + + for (UUID uuid : a.getDenied()) { + b.addDenied(uuid); + } + for (UUID uuid : b.getDenied()) { + a.addDenied(uuid); + } + } + public static void removeSign(final Plot p) { if (!PS.get().isMainThread(Thread.currentThread())) { TaskManager.runTask(new Runnable() { @@ -880,96 +1094,161 @@ public class MainUtil { } } - public static String getStringSized(final int max, final String string) { - if (string.length() > max) { - return string.substring(0, max); - } - return string; + public static Location[] getCorners(String world, RegionWrapper region) { + Location pos1 = new Location(world, region.minX, region.minY, region.minZ); + Location pos2 = new Location(world, region.maxX, region.maxY, region.maxZ); + return new Location[] { pos1, pos2 }; } - public static void autoMerge(final Plot plot, final UUID uuid, final boolean removeRoads) { + /** + * Returns the top and bottom connected plot.
+ * - If the plot is not connected, it will return itself for the top/bottom
+ * - the returned IDs will not necessarily correspond to claimed plots if the connected plots do not form a rectangular shape + * @param plot + * @return new PlotId[] { bottom, top } + */ + public static Location[] getCorners(Plot plot) { + if (!plot.isMerged()) { + return new Location[] { plot.getBottomAbs(), plot.getTopAbs() }; + } + return getCorners(plot.world, getRegions(plot)); + } + + public static Location[] getCorners(String world, Collection regions) { + Location min = null; + Location max = null; + for (RegionWrapper region : regions) { + Location[] corners = getCorners(world, region); + if (min == null) { + min = corners[0]; + max = corners[1]; + continue; + } + Location pos1 = corners[0]; + Location pos2 = corners[1]; + if (pos2.getX() > max.getX()) { + max.setX(pos2.getX()); + } + if (pos1.getX() < min.getX()) { + min.setX(pos1.getX()); + } + if (pos2.getZ() > max.getZ()) { + max.setZ(pos2.getZ()); + } + if (pos1.getZ() < min.getZ()) { + min.setZ(pos1.getZ()); + } + } + return new Location[] { min, max }; + } + + public static PlotId[] getCornerIds(Plot plot) { + if (!plot.isMerged()) { + return new PlotId[] { plot.id, plot.id }; + } + PlotId min = new PlotId(plot.id.x, plot.id.y); + PlotId max = new PlotId(plot.id.x, plot.id.y); + for (Plot current : getConnectedPlots(plot)) { + if (current.id.x < min.x) { + min.x = current.id.x; + } + else if (current.id.x > max.x) { + max.x = current.id.x; + } + if (current.id.y < min.y) { + min.y = current.id.y; + } + else if (current.id.y > max.y) { + max.y = current.id.y; + } + } + return new PlotId[] { min, max }; + } + + public static boolean autoMerge(final Plot plot, int dir, int max, final UUID uuid, final boolean removeRoads) { if (plot == null) { - return; + return false; } if (plot.owner == null) { - return; + return false; } if (!plot.owner.equals(uuid)) { - return; + return false; } - ArrayList plots; - boolean merge = true; - int count = 0; - final ArrayList toUpdate = new ArrayList<>(); - while (merge) { - if (count > 16) { - break; + HashSet visited = new HashSet<>(); + ArrayDeque frontier = new ArrayDeque<>(getConnectedPlots(plot)); + Plot current; + boolean toReturn = false; + while ((current = frontier.poll()) != null && max > 0) { + if (visited.contains(current)) { + continue; } - merge = false; - count++; - final PlotId bot = getBottomPlot(plot).id; - final PlotId top = getTopPlot(plot).id; - plots = getPlotSelectionIds(new PlotId(bot.x, bot.y - 1), new PlotId(top.x, top.y)); - if (ownsPlots(plot.world, plots, uuid, 0)) { - final boolean result = mergePlots(plot.world, plots, removeRoads, false); - if (result) { - toUpdate.addAll(plots); - merge = true; - continue; + visited.add(current); + if (max > 0 && (dir == -1 || dir == 0) && !current.getMerged(0)) { + Plot other = getPlotAbs(current.world, getPlotIdRelative(current.id, 0)); + if (other.isOwner(uuid)) { + frontier.addAll(other.getConnectedPlots()); + mergePlot(current.world, current, other, removeRoads); + toReturn = true; + max--; } } - plots = getPlotSelectionIds(new PlotId(bot.x, bot.y), new PlotId(top.x + 1, top.y)); - if (ownsPlots(plot.world, plots, uuid, 1)) { - final boolean result = mergePlots(plot.world, plots, removeRoads, false); - if (result) { - toUpdate.addAll(plots); - merge = true; - continue; + if (max > 0 && (dir == -1 || dir == 1) && !current.getMerged(1)) { + Plot other = getPlotAbs(current.world, getPlotIdRelative(current.id, 1)); + if (other.isOwner(uuid)) { + frontier.addAll(other.getConnectedPlots()); + mergePlot(current.world, current, other, removeRoads); + toReturn = true; + max--; } } - plots = getPlotSelectionIds(new PlotId(bot.x, bot.y), new PlotId(top.x, top.y + 1)); - if (ownsPlots(plot.world, plots, uuid, 2)) { - final boolean result = mergePlots(plot.world, plots, removeRoads, false); - if (result) { - toUpdate.addAll(plots); - merge = true; - continue; + if (max > 0 && (dir == -1 || dir == 2) && !current.getMerged(2)) { + Plot other = getPlotAbs(current.world, getPlotIdRelative(current.id, 2)); + if (other.isOwner(uuid)) { + frontier.addAll(other.getConnectedPlots()); + mergePlot(current.world, current, other, removeRoads); + toReturn = true; + max--; } } - plots = getPlotSelectionIds(new PlotId(bot.x - 1, bot.y), new PlotId(top.x, top.y)); - if (ownsPlots(plot.world, plots, uuid, 3)) { - final boolean result = mergePlots(plot.world, plots, removeRoads, false); - if (result) { - toUpdate.addAll(plots); - merge = true; - continue; + if (max > 0 && (dir == -1 || dir == 3) && !current.getMerged(3)) { + Plot other = getPlotAbs(current.world, getPlotIdRelative(current.id, 3)); + if (other.isOwner(uuid)) { + frontier.addAll(other.getConnectedPlots()); + mergePlot(current.world, current, other, removeRoads); + toReturn = true; + max--; } } + PlotManager manager = PS.get().getPlotManager(plot.world); + ArrayList ids = new ArrayList<>(visited.size()); + for (Plot visit : visited) { + ids.add(visit.id); + } + manager.finishPlotMerge(PS.get().getPlotWorld(plot.world), ids); } - for (final PlotId id : toUpdate) { - DBFunc.setMerged(plot, plot.getSettings().getMerged()); - } + return toReturn; } - private static boolean ownsPlots(final String world, final ArrayList plots, final UUID uuid, final int dir) { - final PlotId id_min = plots.get(0); - final PlotId id_max = plots.get(plots.size() - 1); - for (final PlotId myid : plots) { - final Plot myplot = PS.get().getPlot(world, myid); - if ((myplot == null) || (myplot.owner == null) || !(myplot.owner.equals(uuid))) { - return false; - } - final PlotId top = getTopPlot(myplot).id; - if (((top.x > id_max.x) && (dir != 1)) || ((top.y > id_max.y) && (dir != 2))) { - return false; - } - final PlotId bot = getBottomPlot(myplot).id; - if (((bot.x < id_min.x) && (dir != 3)) || ((bot.y < id_min.y) && (dir != 0))) { - return false; - } - } - return true; - } +// private static boolean ownsPlots(final String world, final ArrayList plots, final UUID uuid, final int dir) { +// final PlotId id_min = plots.get(0); +// final PlotId id_max = plots.get(plots.size() - 1); +// for (final PlotId myid : plots) { +// final Plot myplot = PS.get().getPlot(world, myid); +// if ((myplot == null) || (myplot.owner == null) || !(myplot.owner.equals(uuid))) { +// return false; +// } +// final PlotId top = getTopPlot(myplot).id; +// if (((top.x > id_max.x) && (dir != 1)) || ((top.y > id_max.y) && (dir != 2))) { +// return false; +// } +// final PlotId bot = getBottomPlot(myplot).id; +// if (((bot.x < id_min.x) && (dir != 3)) || ((bot.y < id_min.y) && (dir != 0))) { +// return false; +// } +// } +// return true; +// } public static void updateWorldBorder(final Plot plot) { if (!worldBorder.containsKey(plot.world)) { @@ -1011,7 +1290,7 @@ public class MainUtil { public void run() { final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); if (plotworld.AUTO_MERGE) { - autoMerge(p, uuid, true); + autoMerge(p, -1, Integer.MAX_VALUE, uuid, true); } } }); @@ -1060,49 +1339,89 @@ public class MainUtil { * @param whenDone */ public static boolean clearAsPlayer(final Plot plot, final boolean isDelete, final Runnable whenDone) { - if (runners.containsKey(plot)) { + if (plot.getRunning() != 0) { return false; } - System.currentTimeMillis(); - ChunkManager.manager.clearAllEntities(plot.getBottom(), plot.getTop()); - if (isDelete) { - removeSign(plot); - } clear(plot, isDelete, whenDone); return true; } + public static int[] countEntities(Plot plot) { + int[] count = new int[5]; + for (Plot current : getConnectedPlots(plot)) { + int[] result = ChunkManager.manager.countEntities(current); + count[0] += result[0]; + count[1] += result[1]; + count[2] += result[2]; + count[3] += result[3]; + count[4] += result[4]; + } + return count; + } + + public static boolean delete(final Plot plot, final Runnable whenDone) { + // Plot is not claimed + if (!plot.hasOwner()) { + return false; + } + final HashSet plots = getConnectedPlots(plot); + clear(plot, true, new Runnable() { + @Override + public void run() { + for (Plot current : plots) { + current.unclaim(); + } + TaskManager.runTask(whenDone); + } + }); + return true; + } + public static boolean clear(final Plot plot, final boolean isDelete, final Runnable whenDone) { if (!EventUtil.manager.callClear(plot.world, plot.id)) { return false; } + final HashSet plots = getConnectedPlots(plot); + final ArrayDeque queue = new ArrayDeque<>(plots); + removeSign(plot); + MainUtil.unlinkPlot(plot, true, !isDelete); final PlotManager manager = PS.get().getPlotManager(plot.world); - final Location pos1 = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); final PlotWorld plotworld = PS.get().getPlotWorld(plot.world); - runners.put(plot, 1); - final Runnable run = new Runnable() { + Runnable run = new Runnable() { @Override public void run() { - if (isDelete) { - manager.unclaimPlot(plotworld, plot, new Runnable() { + if (queue.size() == 0) { + final AtomicInteger finished = new AtomicInteger(0); + final Runnable run = new Runnable() { @Override public void run() { - runners.remove(plot); - TaskManager.runTask(whenDone); + if (finished.incrementAndGet() >= plots.size()) { + TaskManager.runTask(whenDone); + } } - }); - } else { - runners.remove(plot); - TaskManager.runTask(whenDone); + }; + if (isDelete) { + for (Plot current : plots) { + manager.unclaimPlot(plotworld, current, run); + } + } + else { + for (Plot current : plots) { + manager.claimPlot(plotworld, current); + SetBlockQueue.addNotify(run); + } + } + return; } + Plot current = queue.poll(); + if ((plotworld.TERRAIN != 0) || Settings.FAST_CLEAR) { + ChunkManager.manager.regenerateRegion(current.getBottomAbs(), current.getTopAbs(), this); + return; + } + manager.clearPlot(plotworld, current, this); } }; - if ((plotworld.TERRAIN != 0) || Settings.FAST_CLEAR) { - final Location pos2 = MainUtil.getPlotTopLoc(plot.world, plot.id); - ChunkManager.manager.regenerateRegion(pos1, pos2, run); - return true; - } - manager.clearPlot(plotworld, plot, run); + run.run(); return true; } @@ -1118,9 +1437,9 @@ public class MainUtil { final int[] ids = new int[length]; final byte[] data = new byte[length]; int index = 0; - for (int y = pos1.getY(); y < pos2.getY(); y++) { - for (int x = pos1.getX(); x < pos2.getX(); x++) { - for (int z = pos1.getZ(); z < pos2.getZ(); z++) { + for (int y = pos1.getY(); y <= pos2.getY(); y++) { + for (int x = pos1.getX(); x <= pos2.getX(); x++) { + for (int z = pos1.getZ(); z <= pos2.getZ(); z++) { final int i = random.random(blocks.length); xl[index] = x; yl[index] = y; @@ -1140,9 +1459,9 @@ public class MainUtil { setSimpleCuboidAsync(world, pos1, pos2, blocks[0]); return; } - for (int y = pos1.getY(); y < Math.min(256, pos2.getY()); y++) { - for (int x = pos1.getX(); x < pos2.getX(); x++) { - for (int z = pos1.getZ(); z < pos2.getZ(); z++) { + for (int y = pos1.getY(); y <= Math.min(255, pos2.getY()); y++) { + for (int x = pos1.getX(); x <= pos2.getX(); x++) { + for (int z = pos1.getZ(); z <= pos2.getZ(); z++) { final int i = random.random(blocks.length); final PlotBlock block = blocks[i]; SetBlockQueue.setBlock(world, x, y, z, block); @@ -1159,9 +1478,9 @@ public class MainUtil { final int[] ids = new int[length]; final byte[] data = new byte[length]; int index = 0; - for (int y = pos1.getY(); y < pos2.getY(); y++) { - for (int x = pos1.getX(); x < pos2.getX(); x++) { - for (int z = pos1.getZ(); z < pos2.getZ(); z++) { + for (int y = pos1.getY(); y <= Math.min(255, pos2.getY()); y++) { + for (int x = pos1.getX(); x <= pos2.getX(); x++) { + for (int z = pos1.getZ(); z <= pos2.getZ(); z++) { xl[index] = x; yl[index] = y; zl[index] = z; @@ -1175,9 +1494,9 @@ public class MainUtil { } public static void setSimpleCuboidAsync(final String world, final Location pos1, final Location pos2, final PlotBlock newblock) { - for (int y = pos1.getY(); y < Math.min(256, pos2.getY()); y++) { - for (int x = pos1.getX(); x < pos2.getX(); x++) { - for (int z = pos1.getZ(); z < pos2.getZ(); z++) { + for (int y = pos1.getY(); y <= Math.min(255, pos2.getY()); y++) { + for (int x = pos1.getX(); x <= pos2.getX(); x++) { + for (int z = pos1.getZ(); z <= pos2.getZ(); z++) { SetBlockQueue.setBlock(world, x, y, z, newblock); } } @@ -1185,23 +1504,31 @@ public class MainUtil { } public static void setBiome(final Plot plot, final String biome, final Runnable whenDone) { - final Location pos1 = plot.getBottom(); - final Location pos2 = plot.getTop(); - ChunkManager.chunkTask(pos1, pos2, new RunnableVal() { + final ArrayDeque regions = new ArrayDeque<>(getRegions(plot)); + Runnable run = new Runnable() { @Override public void run() { - final ChunkLoc loc = new ChunkLoc(value[0], value[1]); - ChunkManager.manager.loadChunk(plot.world, loc, false); - setBiome(plot.world, value[2], value[3], value[4], value[5], biome); - ChunkManager.manager.unloadChunk(plot.world, loc, true, true); + if (regions.size() == 0) { + update(plot); + TaskManager.runTask(whenDone); + return; + } + RegionWrapper region = regions.poll(); + Location pos1 = new Location(plot.world, region.minX, region.minY, region.minZ); + Location pos2 = new Location(plot.world, region.maxX, region.maxY, region.maxZ); + ChunkManager.chunkTask(pos1, pos2, new RunnableVal() { + @Override + public void run() { + final ChunkLoc loc = new ChunkLoc(value[0], value[1]); + ChunkManager.manager.loadChunk(plot.world, loc, false); + setBiome(plot.world, value[2], value[3], value[4], value[5], biome); + ChunkManager.manager.unloadChunk(plot.world, loc, true, true); + } + }, this, 5); + } - }, new Runnable() { - @Override - public void run() { - update(plot); - TaskManager.runTask(whenDone); - } - }, 5); + }; + run.run(); } public static void setBiome(final String world, final int p1x, final int p1z, final int p2x, final int p2z, final String biome) { @@ -1236,16 +1563,15 @@ public class MainUtil { * @return Home Location */ public static Location getPlotHome(final String w, final PlotId plotid) { - final Plot plot = getPlot(w, plotid); - final BlockLoc home = plot.getSettings().getPosition(); - final Location bot = getPlotBottomLoc(w, plotid); + final Plot plot = getPlotAbs(w, plotid).getBasePlot(false); + final BlockLoc home = plot.getPosition(); PS.get().getPlotManager(w); if ((home == null) || ((home.x == 0) && (home.z == 0))) { return getDefaultHome(plot); } else { + Location bot = plot.getBottomAbs(); final Location loc = new Location(bot.getWorld(), bot.getX() + home.x, bot.getY() + home.y, bot.getZ() + home.z); if (BlockManager.manager.getBlock(loc).id != 0) { - // sendConsoleMessage("ID was " + BukkitUtil.getBlock(loc).id); loc.setY(Math.max(getHeighestBlock(w, loc.getX(), loc.getZ()), bot.getY())); } return loc; @@ -1294,18 +1620,6 @@ public class MainUtil { return manager.getPlotBottomLocAbs(plotworld, id); } - /** - * Obtains the width of a plot (x width) - * - * @param world - * @param id - * - * @return int width of plot - */ - public static int getPlotWidth(final String world, final PlotId id) { - return getPlotTopLoc(world, id).getX() - getPlotBottomLoc(world, id).getX(); - } - /** * Gets the top loc of a plot (if mega, returns top loc of that mega plot) - If you would like each plot treated as * a small plot use getPlotTopLocAbs(...) @@ -1315,44 +1629,45 @@ public class MainUtil { * * @return Location top of mega plot */ - public static Location getPlotTopLoc(final String world, PlotId id) { - final Plot plot = PS.get().getPlot(world, id); - if (plot != null) { - id = getTopPlot(plot).id; + public static Location getPlotTopLoc_(Plot plot) { + Location top = getPlotTopLocAbs(plot.world, plot.id); + if (!plot.isMerged()) { + return top; } - final PlotWorld plotworld = PS.get().getPlotWorld(world); - final PlotManager manager = PS.get().getPlotManager(world); - return manager.getPlotTopLocAbs(plotworld, id); + PlotId id; + if (plot.getMerged(2)) { + id = getPlotIdRelative(plot.id, 2); + top.setZ(getPlotBottomLocAbs(plot.world, id).getZ() - 1); + } + if (plot.getMerged(1)) { + id = getPlotIdRelative(plot.id, 1); + top.setX(getPlotBottomLocAbs(plot.world, id).getX() - 1); + } + return top; } - /** - * Gets the bottom loc of a plot (if mega, returns bottom loc of that mega plot) - If you would like each plot - * treated as a small plot use getPlotBottomLocAbs(...) - * - * @param world - * @param id - * - * @return Location bottom of mega plot - * - * @deprecated Incorrect offset / legacy / use plot.getBottom() - * - */ - @Deprecated - public static Location getPlotBottomLoc(final String world, PlotId id) { - final Plot plot = PS.get().getPlot(world, id); - if (plot != null) { - id = getBottomPlot(plot).id; + public static Location getPlotBottomLoc_(Plot plot) { + Location bot = getPlotBottomLocAbs(plot.world, plot.id); + if (!plot.isMerged()) { + return bot; } - final PlotWorld plotworld = PS.get().getPlotWorld(world); - final PlotManager manager = PS.get().getPlotManager(world); - return manager.getPlotBottomLocAbs(plotworld, id); + PlotId id; + if (plot.getMerged(0)) { + id = getPlotIdRelative(plot.id, 0); + bot.setZ(getPlotTopLocAbs(plot.world, id).getZ() + 1); + } + if (plot.getMerged(3)) { + id = getPlotIdRelative(plot.id, 3); + bot.setX(getPlotTopLocAbs(plot.world, id).getX() + 1); + } + return bot; } public static boolean canClaim(final PlotPlayer player, final String world, final PlotId pos1, final PlotId pos2) { for (int x = pos1.x; x <= pos2.x; x++) { for (int y = pos1.y; y <= pos2.y; y++) { final PlotId id = new PlotId(x, y); - final Plot plot = getPlot(world, id); + final Plot plot = getPlotAbs(world, id); if (!canClaim(player, plot)) { return false; } @@ -1390,45 +1705,17 @@ public class MainUtil { return true; } - public static boolean swap(final String world, final PlotId current, final PlotId newPlot, final Runnable whenDone) { - final Plot p1 = PS.get().getPlot(world, current); - final Plot p2 = PS.get().getPlot(world, newPlot); - if ((p1 == null) || (p2 == null) || (p1.owner == null) || !p1.owner.equals(p2.owner)) { - return false; - } - // Swap blocks - ChunkManager.manager.swap(world, current, newPlot); - // Swap cached - final PlotId temp = new PlotId(p1.id.x.intValue(), p1.id.y.intValue()); - p1.id.x = p2.id.x.intValue(); - p1.id.y = p2.id.y.intValue(); - p2.id.x = temp.x; - p2.id.y = temp.y; - final Map> raw = PS.get().getAllPlotsRaw(); - raw.get(world).remove(p1.id); - raw.get(world).remove(p2.id); - p1.id.recalculateHash(); - p2.id.recalculateHash(); - raw.get(world).put(p1.id, p1); - raw.get(world).put(p2.id, p2); - // Swap database - DBFunc.dbManager.swapPlots(p2, p1); - return true; - } - - public static boolean swapData(final String world, final PlotId current, final PlotId newPlot, final Runnable whenDone) { - final Plot p1 = PS.get().getPlot(world, current); - final Plot p2 = PS.get().getPlot(world, newPlot); + public static boolean swapData(Plot p1, Plot p2, final Runnable whenDone) { if ((p1 == null) || (p1.owner == null)) { if ((p2 != null) && (p2.owner != null)) { - moveData(p2, getPlot(world, current), whenDone); + moveData(p2, p1, whenDone); return true; } return false; } if ((p2 == null) || (p2.owner == null)) { if ((p1 != null) && (p1.owner != null)) { - moveData(p1, getPlot(world, newPlot), whenDone); + moveData(p1, p2, whenDone); return true; } return false; @@ -1440,146 +1727,227 @@ public class MainUtil { p2.id.x = temp.x; p2.id.y = temp.y; final Map> raw = PS.get().getAllPlotsRaw(); - raw.get(world).remove(p1.id); - raw.get(world).remove(p2.id); + raw.get(p1.world).remove(p1.id); + raw.get(p2.world).remove(p2.id); p1.id.recalculateHash(); p2.id.recalculateHash(); - raw.get(world).put(p1.id, p1); - raw.get(world).put(p2.id, p2); + raw.get(p1.world).put(p1.id, p1); + raw.get(p2.world).put(p2.id, p2); // Swap database DBFunc.dbManager.swapPlots(p2, p1); - TaskManager.runTask(whenDone); - return true; - } - - public static boolean moveData(final Plot plot1, final Plot plot2, final Runnable whenDone) { - if (plot1.owner == null) { - PS.debug(plot2 + " is unowned (single)"); - TaskManager.runTask(whenDone); - return false; - } - final Plot pos1 = getBottomPlot(plot1); - final Plot pos2 = getTopPlot(plot1); - final PlotId size = MainUtil.getSize(plot1); - if (!MainUtil.isUnowned(plot2.world, plot2.id, new PlotId((plot2.id.x + size.x) - 1, (plot2.id.y + size.y) - 1))) { - PS.debug(plot2 + " is unowned (multi)"); - TaskManager.runTask(whenDone); - return false; - } - final int offset_x = plot2.id.x - pos1.id.x; - final int offset_y = plot2.id.y - pos1.id.y; - final ArrayList selection = getPlotSelectionIds(pos1.id, pos2.id); - for (final PlotId id : selection) { - final String worldOriginal = plot1.world; - final PlotId idOriginal = new PlotId(id.x, id.y); - final Plot plot = PS.get().getPlot(plot1.world, id); - final Map> raw = PS.get().getAllPlotsRaw(); - raw.get(plot1.world).remove(id); - plot.id.x += offset_x; - plot.id.y += offset_y; - plot.id.recalculateHash(); - raw.get(plot2.world).put(plot.id, plot); - DBFunc.movePlot(getPlot(worldOriginal, idOriginal), getPlot(plot2.world, new PlotId(id.x + offset_x, id.y + offset_y))); - } TaskManager.runTaskLater(whenDone, 1); return true; } - public static boolean move(final Plot plot1, final Plot plot2, final Runnable whenDone) { - final com.intellectualcrafters.plot.object.Location bot1 = MainUtil.getPlotBottomLoc(plot1.world, plot1.id); - final com.intellectualcrafters.plot.object.Location bot2 = MainUtil.getPlotBottomLoc(plot2.world, plot2.id); - final Location top = MainUtil.getPlotTopLoc(plot1.world, plot1.id); - if (plot1.owner == null) { - PS.debug(plot2 + " is unowned (single)"); + public static boolean moveData(final Plot pos1, final Plot pos2, final Runnable whenDone) { + if (pos1.owner == null) { + PS.debug(pos2 + " is unowned (single)"); TaskManager.runTask(whenDone); return false; } - final Plot pos1 = getBottomPlot(plot1); - final Plot pos2 = getTopPlot(plot1); - final PlotId size = MainUtil.getSize(plot1); - if (!MainUtil.isUnowned(plot2.world, plot2.id, new PlotId((plot2.id.x + size.x) - 1, (plot2.id.y + size.y) - 1))) { - PS.debug(plot2 + " is unowned (multi)"); + if (pos2.hasOwner()) { + PS.debug(pos2 + " is unowned (multi)"); TaskManager.runTask(whenDone); return false; } - final int offset_x = plot2.id.x - pos1.id.x; - final int offset_y = plot2.id.y - pos1.id.y; - final ArrayList selection = getPlotSelectionIds(pos1.id, pos2.id); - for (final PlotId id : selection) { - final String worldOriginal = plot1.world; - final PlotId idOriginal = new PlotId(id.x, id.y); - final Plot plot = PS.get().getPlot(plot1.world, id); - final Map> raw = PS.get().getAllPlotsRaw(); - raw.get(plot1.world).remove(id); - plot.id.x += offset_x; - plot.id.y += offset_y; - plot.id.recalculateHash(); - raw.get(plot2.world).put(plot.id, plot); - DBFunc.movePlot(getPlot(worldOriginal, idOriginal), getPlot(plot2.world, new PlotId(id.x + offset_x, id.y + offset_y))); - } - ChunkManager.manager.copyRegion(bot1, top, bot2, new Runnable() { - @Override - public void run() { - final Location bot = bot1.clone().add(1, 0, 1); - ChunkManager.manager.regenerateRegion(bot, top, null); - TaskManager.runTaskLater(whenDone, 1); - } - }); + final Map> raw = PS.get().getAllPlotsRaw(); + raw.get(pos1.world).remove(pos1.id); + pos1.id.x = (int) pos2.id.x; + pos1.id.y = (int) pos2.id.y; + pos1.id.recalculateHash(); + raw.get(pos2.world).put(pos1.id, pos1); + DBFunc.movePlot(pos1, pos2); + TaskManager.runTaskLater(whenDone, 1); return true; } + + public static boolean move(final Plot origin, final Plot destination, final Runnable whenDone, boolean allowSwap) { + PlotId offset = new PlotId(destination.id.x - origin.id.x, destination.id.y - origin.id.y); + Location db = destination.getBottomAbs(); + Location ob = origin.getBottomAbs(); + final int offsetX = db.getX() - ob.getX(); + final int offsetZ = db.getZ() - ob.getZ(); + if (origin.owner == null) { + TaskManager.runTaskLater(whenDone, 1); + return false; + } + boolean occupied = false; + HashSet plots = MainUtil.getConnectedPlots(origin); + for (Plot plot : plots) { + Plot other = MainUtil.getPlotAbs(destination.world, new PlotId(plot.id.x + offset.x, plot.id.y + offset.y)); + if (other.owner != null) { + if (!allowSwap) { + TaskManager.runTaskLater(whenDone, 1); + return false; + } + occupied = true; + } + } + final ArrayDeque regions = new ArrayDeque<>(getRegions(origin)); + // move / swap data + for (Plot plot : plots) { + Plot other = MainUtil.getPlotAbs(destination.world, new PlotId(plot.id.x + offset.x, plot.id.y + offset.y)); + swapData(plot, other, null); + } + // copy terrain + Runnable move = new Runnable() { + @Override + public void run() { + if (regions.size() == 0) { + TaskManager.runTask(whenDone); + return; + } + final Runnable task = this; + RegionWrapper region = regions.poll(); + Location[] corners = getCorners(origin.world, region); + final Location pos1 = corners[0]; + final Location pos2 = corners[1]; + Location newPos = pos1.clone().add(offsetX, 0, offsetZ); + newPos.setWorld(destination.world); + ChunkManager.manager.copyRegion(pos1, pos2, newPos, new Runnable() { + @Override + public void run() { + ChunkManager.manager.regenerateRegion(pos1, pos2, task); + } + }); + } + }; + Runnable swap = new Runnable() { + @Override + public void run() { + if (regions.size() == 0) { + TaskManager.runTask(whenDone); + return; + } + RegionWrapper region = regions.poll(); + Location[] corners = getCorners(origin.world, region); + Location pos1 = corners[0]; + Location pos2 = corners[1]; + Location pos3 = pos1.clone().add(offsetX, 0, offsetZ); + Location pos4 = pos2.clone().add(offsetX, 0, offsetZ); + pos3.setWorld(destination.world); + pos4.setWorld(destination.world); + ChunkManager.manager.swap(pos1, pos2, pos3, pos4, this); + } + }; + if (occupied) { + swap.run(); + } + else { + move.run(); + } + return true; + } +// final com.intellectualcrafters.plot.object.Location bot1 = MainUtil.getPlotBottomLoc(plot1.world, plot1.id); +// final com.intellectualcrafters.plot.object.Location bot2 = MainUtil.getPlotBottomLoc(plot2.world, plot2.id); +// final Location top = MainUtil.getPlotTopLoc(plot1.world, plot1.id); +// if (plot1.owner == null) { +// PS.debug(plot2 + " is unowned (single)"); +// TaskManager.runTask(whenDone); +// return false; +// } +// final Plot pos1 = getBottomPlot(plot1); +// final Plot pos2 = getTopPlot(plot1); +// final PlotId size = MainUtil.getSize(plot1); +// if (!MainUtil.isUnowned(plot2.world, plot2.id, new PlotId((plot2.id.x + size.x) - 1, (plot2.id.y + size.y) - 1))) { +// PS.debug(plot2 + " is unowned (multi)"); +// TaskManager.runTask(whenDone); +// return false; +// } +// final int offset_x = plot2.id.x - pos1.id.x; +// final int offset_y = plot2.id.y - pos1.id.y; +// final ArrayList selection = getPlotSelectionIds(pos1.id, pos2.id); +// for (final PlotId id : selection) { +// final String worldOriginal = plot1.world; +// final PlotId idOriginal = new PlotId(id.x, id.y); +// final Plot plot = PS.get().getPlot(plot1.world, id); +// final Map> raw = PS.get().getAllPlotsRaw(); +// raw.get(plot1.world).remove(id); +// plot.id.x += offset_x; +// plot.id.y += offset_y; +// plot.id.recalculateHash(); +// raw.get(plot2.world).put(plot.id, plot); +// DBFunc.movePlot(getPlot(worldOriginal, idOriginal), getPlot(plot2.world, new PlotId(id.x + offset_x, id.y + offset_y))); +// } +// ChunkManager.manager.copyRegion(bot1, top, bot2, new Runnable() { +// @Override +// public void run() { +// final Location bot = bot1.clone().add(1, 0, 1); +// ChunkManager.manager.regenerateRegion(bot, top, null); +// TaskManager.runTaskLater(whenDone, 1); +// } +// }); +// return true; +// } - public static boolean copy(final String world, final PlotId current, final PlotId newPlot, final Runnable whenDone) { - final com.intellectualcrafters.plot.object.Location bot1 = MainUtil.getPlotBottomLoc(world, current); - final com.intellectualcrafters.plot.object.Location bot2 = MainUtil.getPlotBottomLoc(world, newPlot); - final Location top = MainUtil.getPlotTopLoc(world, current); - final Plot currentPlot = MainUtil.getPlot(world, current); - if (currentPlot.owner == null) { + public static boolean copy(final Plot origin, final Plot destination, final Runnable whenDone) { + PlotId offset = new PlotId(destination.id.x - origin.id.x, destination.id.y - origin.id.y); + Location db = destination.getBottomAbs(); + Location ob = origin.getBottomAbs(); + final int offsetX = db.getX() - ob.getX(); + final int offsetZ = db.getZ() - ob.getZ(); + if (origin.owner == null) { TaskManager.runTaskLater(whenDone, 1); return false; } - final Plot pos1 = getBottomPlot(currentPlot); - final Plot pos2 = getTopPlot(currentPlot); - final PlotId size = MainUtil.getSize(currentPlot); - if (!MainUtil.isUnowned(world, newPlot, new PlotId((newPlot.x + size.x) - 1, (newPlot.y + size.y) - 1))) { - TaskManager.runTaskLater(whenDone, 1); - return false; + HashSet plots = MainUtil.getConnectedPlots(origin); + for (Plot plot : plots) { + Plot other = MainUtil.getPlotAbs(destination.world, new PlotId(plot.id.x + offset.x, plot.id.y + offset.y)); + if (other.owner != null) { + TaskManager.runTaskLater(whenDone, 1); + return false; + } } - final ArrayList selection = getPlotSelectionIds(pos1.id, pos2.id); - final int offset_x = newPlot.x - pos1.id.x; - final int offset_y = newPlot.y - pos1.id.y; - for (final PlotId id : selection) { - final int x = id.x + offset_x; - final int y = id.y + offset_y; - final Plot plot = createPlotAbs(currentPlot.owner, getPlot(world, new PlotId(x, y))); - if ((currentPlot.getSettings().flags != null) && (currentPlot.getSettings().flags.size() > 0)) { - plot.getSettings().flags = currentPlot.getSettings().flags; - DBFunc.setFlags(plot, currentPlot.getSettings().flags.values()); + // copy data + for (Plot plot : plots) { + Plot other = MainUtil.getPlotAbs(destination.world , new PlotId(plot.id.x + offset.x, plot.id.y + offset.y)); + other = createPlotAbs(plot.owner, other); + if ((plot.getFlags() != null) && (plot.getFlags().size() > 0)) { + other.getSettings().flags = plot.getFlags(); + DBFunc.setFlags(other, plot.getFlags().values()); } - if (currentPlot.isMerged()) { - plot.getSettings().setMerged(currentPlot.getSettings().getMerged()); - DBFunc.setMerged(plot, currentPlot.getSettings().getMerged()); + if (plot.isMerged()) { + other.setMerged(plot.getMerged()); } - if ((currentPlot.members != null) && (currentPlot.members.size() > 0)) { - plot.members = currentPlot.members; - for (final UUID member : plot.members) { - DBFunc.setMember(plot, member); + if ((plot.members != null) && (plot.members.size() > 0)) { + other.members = plot.members; + for (final UUID member : other.members) { + DBFunc.setMember(other, member); } } - if ((currentPlot.trusted != null) && (currentPlot.trusted.size() > 0)) { - plot.trusted = currentPlot.trusted; - for (final UUID trusted : plot.trusted) { - DBFunc.setTrusted(plot, trusted); + if ((plot.trusted != null) && (plot.trusted.size() > 0)) { + other.trusted = plot.trusted; + for (final UUID trusted : other.trusted) { + DBFunc.setTrusted(other, trusted); } } - if ((currentPlot.denied != null) && (currentPlot.denied.size() > 0)) { - plot.denied = currentPlot.denied; - for (final UUID denied : plot.denied) { - DBFunc.setDenied(plot, denied); + if ((plot.denied != null) && (plot.denied.size() > 0)) { + other.denied = plot.denied; + for (final UUID denied : other.denied) { + DBFunc.setDenied(other, denied); } } - PS.get().updatePlot(plot); + PS.get().updatePlot(other); } - ChunkManager.manager.copyRegion(bot1, top, bot2, whenDone); + // copy terrain + final ArrayDeque regions = new ArrayDeque<>(getRegions(origin)); + Runnable run = new Runnable() { + @Override + public void run() { + if (regions.size() == 0) { + TaskManager.runTask(whenDone); + return; + } + RegionWrapper region = regions.poll(); + Location[] corners = getCorners(origin.world, region); + Location pos1 = corners[0]; + Location pos2 = corners[1]; + Location newPos = pos1.clone().add(offsetX, 0, offsetZ); + newPos.setWorld(destination.world); + ChunkManager.manager.copyRegion(pos1, pos2, newPos, this); + } + }; + run.run(); return true; } @@ -1727,56 +2095,124 @@ public class MainUtil { return true; } - public static Plot getBottomPlot(final Plot plot) { - if (plot.getSettings().getMerged(0)) { - final Plot p = PS.get().getPlot(plot.world, new PlotId(plot.id.x, plot.id.y - 1)); - if (p == null) { - return plot; - } - return getBottomPlot(p); - } - if (plot.getSettings().getMerged(3)) { - final Plot p = PS.get().getPlot(plot.world, new PlotId(plot.id.x - 1, plot.id.y)); - if (p == null) { - return plot; - } - return getBottomPlot(p); - } - return plot; - } + /** + * @deprecated raw access is deprecated + */ + public static HashSet connected_cache; + public static HashSet regions_cache; - public static Plot getTopPlot(final Plot plot) { - if (plot.getSettings().getMerged(2)) { - final Plot p = PS.get().getPlot(plot.world, new PlotId(plot.id.x, plot.id.y + 1)); - if (p == null) { - return plot; + public static HashSet getConnectedPlots(Plot plot) { + if (plot == null) { + return null; + } + if (plot.settings == null) { + return new HashSet<>(Arrays.asList(plot)); + } + boolean[] merged = plot.getMerged(); + int hash = hash(merged); + if (hash == 0) { + return new HashSet<>(Arrays.asList(plot)); + } + if (connected_cache != null && connected_cache.contains(plot)) { + return connected_cache; + } + regions_cache = null; + connected_cache = new HashSet(); + ArrayDeque frontier = new ArrayDeque<>(); + HashSet queuecache = new HashSet<>(); + connected_cache.add(plot); + Plot tmp; + if (merged[0]) { + tmp = getPlotAbs(plot.world, getPlotIdRelative(plot.id, 0)); + if (!tmp.getMerged(2)) { + // invalid merge + PS.debug("Fixing invalid merge: " + plot); + tmp.settings.setMerged(2, true); + DBFunc.setMerged(tmp, tmp.settings.getMerged()); } - return getTopPlot(p); + queuecache.add(tmp); + frontier.add(tmp); } - if (plot.getSettings().getMerged(1)) { - final Plot p = PS.get().getPlot(plot.world, new PlotId(plot.id.x + 1, plot.id.y)); - if (p == null) { - return plot; + if (merged[1]) { + tmp = getPlotAbs(plot.world, getPlotIdRelative(plot.id, 1)); + if (!tmp.getMerged(3)) { + // invalid merge + PS.debug("Fixing invalid merge: " + plot); + tmp.settings.setMerged(3, true); + DBFunc.setMerged(tmp, tmp.settings.getMerged()); } - return getTopPlot(p); + queuecache.add(tmp); + frontier.add(tmp); } - return plot; - - } - - public static PlotId getSize(final Plot plot) { - if (!plot.isMerged()) { - return new PlotId(1, 1); + if (merged[2]) { + tmp = getPlotAbs(plot.world, getPlotIdRelative(plot.id, 2)); + if (!tmp.getMerged(0)) { + // invalid merge + PS.debug("Fixing invalid merge: " + plot); + tmp.settings.setMerged(0, true); + DBFunc.setMerged(tmp, tmp.settings.getMerged()); + } + queuecache.add(tmp); + frontier.add(tmp); } - final Plot top = getTopPlot(plot); - final Plot bot = getBottomPlot(plot); - return new PlotId((top.id.x - bot.id.x) + 1, (top.id.y - bot.id.y) + 1); + if (merged[3]) { + tmp = getPlotAbs(plot.world, getPlotIdRelative(plot.id, 3)); + if (!tmp.getMerged(1)) { + // invalid merge + PS.debug("Fixing invalid merge: " + plot); + tmp.settings.setMerged(1, true); + DBFunc.setMerged(tmp, tmp.settings.getMerged()); + } + queuecache.add(tmp); + frontier.add(tmp); + } + Plot current; + while ((current = frontier.poll()) != null) { + if (current.settings == null) { + // Invalid plot + // merged onto unclaimed plot + PS.debug("Ignoring invalid merged plot: " + current + " | " + current.owner); + continue; + } + connected_cache.add(current); + queuecache.remove(current); + merged = current.getMerged(); + if (merged[0]) { + tmp = getPlotAbs(current.world, getPlotIdRelative(current.id, 0)); + if (!queuecache.contains(tmp) && !connected_cache.contains(tmp)) { + queuecache.add(tmp); + frontier.add(tmp); + } + } + if (merged[1]) { + tmp = getPlotAbs(current.world, getPlotIdRelative(current.id, 1)); + if (!queuecache.contains(tmp) && !connected_cache.contains(tmp)) { + queuecache.add(tmp); + frontier.add(tmp); + } + } + if (merged[2]) { + tmp = getPlotAbs(current.world, getPlotIdRelative(current.id, 2)); + if (!queuecache.contains(tmp) && !connected_cache.contains(tmp)) { + queuecache.add(tmp); + frontier.add(tmp); + } + } + if (merged[3]) { + tmp = getPlotAbs(current.world, getPlotIdRelative(current.id, 3)); + if (!queuecache.contains(tmp) && !connected_cache.contains(tmp)) { + queuecache.add(tmp); + frontier.add(tmp); + } + } + } + return connected_cache; } /** * Fetches the plot from the main class */ - public static Plot getPlot(final String world, final PlotId id) { + public static Plot getPlotAbs(final String world, final PlotId id) { if (id == null) { return null; } @@ -1788,18 +2224,17 @@ public class MainUtil { } /** - * Returns the plot at a location (mega plots are not considered, all plots are treated as small plots) - * @param loc - * @return PlotId underlying plot id of loc + * Gets all the connected plots */ - public static PlotId getPlotAbs(final Location loc) { - final String world = loc.getWorld(); - final PlotManager manager = PS.get().getPlotManager(world); - if (manager == null) { + public static HashSet getPlots(final String world, final PlotId id) { + if (id == null) { return null; } - final PlotWorld plotworld = PS.get().getPlotWorld(world); - return manager.getPlotIdAbs(plotworld, loc.getX(), loc.getY(), loc.getZ()); + final Plot plot = PS.get().getPlot(world, id); + if (plot != null) { + return getConnectedPlots(plot); + } + return new HashSet<>(Arrays.asList(new Plot(world, id, null))); } /** @@ -1833,12 +2268,20 @@ public class MainUtil { return Permissions.hasPermissionRange(p, "plots.plot", Settings.MAX_PLOTS); } - public static Plot getPlot(final Location loc) { + public static Plot getPlotAbs(final Location loc) { final PlotId id = getPlotId(loc); if (id == null) { return null; } - return getPlot(loc.getWorld(), id); + return getPlotAbs(loc.getWorld(), id); + } + + public static Set getPlots(final Location loc) { + final PlotId id = getPlotId(loc); + if (id == null) { + return null; + } + return getPlots(loc.getWorld(), id); } public static double getAverageRating(final Plot plot) { @@ -1905,7 +2348,7 @@ public class MainUtil { return ratings; } - public static void setComponent(final Plot plot, final String component, final PlotBlock[] blocks) { - PS.get().getPlotManager(plot.world).setComponent(PS.get().getPlotWorld(plot.world), plot.id, component, blocks); + public static boolean setComponent(final Plot plot, final String component, final PlotBlock[] blocks) { + return PS.get().getPlotManager(plot.world).setComponent(PS.get().getPlotWorld(plot.world), plot.id, component, blocks); } } diff --git a/src/main/java/com/intellectualcrafters/plot/util/SchematicHandler.java b/src/main/java/com/intellectualcrafters/plot/util/SchematicHandler.java index 6728543ba..243a838c1 100644 --- a/src/main/java/com/intellectualcrafters/plot/util/SchematicHandler.java +++ b/src/main/java/com/intellectualcrafters/plot/util/SchematicHandler.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; @@ -46,6 +47,7 @@ import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotBlock; import com.intellectualcrafters.plot.object.PlotId; +import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.object.RunnableVal; import com.intellectualcrafters.plot.object.schematic.PlotItem; import com.plotsquared.object.schematic.StateWrapper; @@ -92,15 +94,6 @@ public abstract class SchematicHandler { } else { directory = outputDir.getPath(); } - final Location top = plot.getTop(); - final Location bot = plot.getBottom(); - final int area = ((1 + top.getX()) - bot.getX()) * ((1 + top.getZ()) - bot.getZ()); - if (area > 4096) { - PS.debug("The plot is > 64 x 64 - Fast lossy schematic saving will be used"); - } - // if (area <= 4096 && PS.get().worldEdit != null) { - // new WorldEditSchematic().saveSchematic(directory + File.separator + name + ".schematic", plot.world, plot.id); - // } final Runnable THIS = this; SchematicHandler.manager.getCompoundTag(plot.world, plot.id, new RunnableVal() { @Override @@ -162,9 +155,8 @@ public abstract class SchematicHandler { final int LENGTH = demensions.getZ(); final int HEIGHT = demensions.getY(); // Validate dimensions - final Location bottom = plot.getBottom(); - final Location top = plot.getTop(); - if ((((top.getX() - bottom.getX()) + 1) < WIDTH) || (((top.getZ() - bottom.getZ()) + 1) < LENGTH) || (HEIGHT > 256)) { + RegionWrapper region = MainUtil.getLargestRegion(plot); + if ((((region.maxX - region.minX + x_offset) + 1) < WIDTH) || (((region.maxZ - region.minZ + z_offset) + 1) < LENGTH) || (HEIGHT > 256)) { PS.debug("Schematic is too large"); TaskManager.runTask(whenDone); return; @@ -177,9 +169,10 @@ public abstract class SchematicHandler { if (HEIGHT >= 256) { y_offset = 0; } else { - y_offset = MainUtil.getHeighestBlock(plot.world, bottom.getX() + 1, bottom.getZ() + 1); + y_offset = MainUtil.getHeighestBlock(plot.world, region.minX + 1, region.minZ + 1); } - final Location pos1 = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1 + x_offset, y_offset - 1, 1 + z_offset); + final Location pos1 = new Location(plot.world, region.minX + x_offset, y_offset, region.minZ + z_offset); +// Location pos2 = new Location(plot.world, region.maxX, region.maxY, region.maxZ); final Location pos2 = pos1.clone().add(WIDTH - 1, HEIGHT - 1, LENGTH - 1); // TODO switch to ChunkManager.chunkTask(pos1, pos2, task, whenDone, allocate); final int p1x = pos1.getX(); @@ -369,14 +362,14 @@ public abstract class SchematicHandler { if (items == null) { return false; } - Location l1 = MainUtil.getPlotBottomLoc(plot.world, plot.getId()); + RegionWrapper region = MainUtil.getLargestRegion(plot); + Location l1 = new Location(plot.world, region.minX + x_offset, 1, region.minZ + z_offset); +// Location l1 = MainUtil.getPlotBottomLoc(plot.world, plot.getId()); final int sy = MainUtil.getHeighestBlock(plot.world, l1.getX() + 1, l1.getZ() + 1); final Dimension demensions = schematic.getSchematicDimension(); final int HEIGHT = demensions.getY(); if ((HEIGHT < 255)) { - l1 = l1.add(1, sy - 1, 1); - } else { - l1 = l1.add(1, 0, 1); + l1 = l1.add(0, sy - 1, 0); } final int X = l1.getX() + x_offset; final int Y = l1.getY(); @@ -675,25 +668,11 @@ public abstract class SchematicHandler { return new CompoundTag("Schematic", schematic); } - /** - * Gets the schematic of a plot - * - * @param world to check - * @param id plot - * - * @return tag - */ - public void getCompoundTag(final String world, final PlotId id, final RunnableVal whenDone) { - if (PS.get().getPlot(world, id) == null) { - whenDone.run(); - return; - } - final Location pos1 = MainUtil.getPlotBottomLoc(world, id).add(1, -1, 1); - final Location pos2 = MainUtil.getPlotTopLoc(world, id); - getCompoundTag(world, pos1, pos2, whenDone); - } + public abstract void getCompoundTag(final String world, Set regions, final RunnableVal whenDone); - public abstract void getCompoundTag(final String world, final Location pos1, final Location pos2, final RunnableVal whenDone); + public void getCompoundTag(final String world, PlotId id, final RunnableVal whenDone) { + getCompoundTag(world, MainUtil.getRegions(MainUtil.getPlotAbs(world, id)), whenDone); + } public boolean pastePart(final String world, final DataCollection[] blocks, final Location l1, final int x_offset, final int z_offset, final int i1, final int i2, final int WIDTH, final int LENGTH) { int length = 0; diff --git a/src/main/java/com/plotsquared/bukkit/BukkitMain.java b/src/main/java/com/plotsquared/bukkit/BukkitMain.java index 19ef8c33d..06eec4f04 100644 --- a/src/main/java/com/plotsquared/bukkit/BukkitMain.java +++ b/src/main/java/com/plotsquared/bukkit/BukkitMain.java @@ -59,7 +59,6 @@ import com.plotsquared.bukkit.listeners.PlayerEvents; import com.plotsquared.bukkit.listeners.PlayerEvents_1_8; import com.plotsquared.bukkit.listeners.PlayerEvents_1_8_3; import com.plotsquared.bukkit.listeners.PlotPlusListener; -import com.plotsquared.bukkit.listeners.TNTListener; import com.plotsquared.bukkit.listeners.WorldEvents; import com.plotsquared.bukkit.listeners.worldedit.WEListener; import com.plotsquared.bukkit.titles.DefaultTitle; @@ -520,7 +519,7 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { @Override public void registerTNTListener() { - getServer().getPluginManager().registerEvents(new TNTListener(), this); + // No longer here } @Override diff --git a/src/main/java/com/plotsquared/bukkit/database/plotme/ClassicPlotMeConnector.java b/src/main/java/com/plotsquared/bukkit/database/plotme/ClassicPlotMeConnector.java index c30e4d061..2a9a2cb4c 100644 --- a/src/main/java/com/plotsquared/bukkit/database/plotme/ClassicPlotMeConnector.java +++ b/src/main/java/com/plotsquared/bukkit/database/plotme/ClassicPlotMeConnector.java @@ -161,7 +161,7 @@ public class ClassicPlotMeConnector extends APlotMeConnector { final HashMap newplots = plots.get(world); final Plot plot = newplots.get(entry2.getKey()); if (plot != null) { - plot.getSettings().setMerged(entry2.getValue()); + plot.setMerged(entry2.getValue()); } } } diff --git a/src/main/java/com/plotsquared/bukkit/database/plotme/PlotMeConnector_017.java b/src/main/java/com/plotsquared/bukkit/database/plotme/PlotMeConnector_017.java index 7d8f2912f..43e7a578e 100644 --- a/src/main/java/com/plotsquared/bukkit/database/plotme/PlotMeConnector_017.java +++ b/src/main/java/com/plotsquared/bukkit/database/plotme/PlotMeConnector_017.java @@ -129,7 +129,7 @@ public class PlotMeConnector_017 extends APlotMeConnector { final HashMap mergeMap = merges.get(plot.world); if (mergeMap != null) { if (mergeMap.containsKey(plot.id)) { - plot.getSettings().setMerged(mergeMap.get(plot.id)); + plot.setMerged(mergeMap.get(plot.id)); } } } diff --git a/src/main/java/com/plotsquared/bukkit/generator/AugmentedPopulator.java b/src/main/java/com/plotsquared/bukkit/generator/AugmentedPopulator.java index cb5d6be5f..8dd52e568 100644 --- a/src/main/java/com/plotsquared/bukkit/generator/AugmentedPopulator.java +++ b/src/main/java/com/plotsquared/bukkit/generator/AugmentedPopulator.java @@ -51,7 +51,7 @@ public class AugmentedPopulator extends BlockPopulator { o = (plotworld.TERRAIN == 1) || (plotworld.TERRAIN == 2); final World bukkitWorld = Bukkit.getWorld(world); if (cluster != null) { - final Location bl = manager.getPlotBottomLocAbs(plotworld, cluster.getP1()); + final Location bl = manager.getPlotBottomLocAbs(plotworld, cluster.getP1()).subtract(1, 0, 1); final Location tl = manager.getPlotTopLocAbs(plotworld, cluster.getP2()).add(1, 0, 1); bx = bl.getX(); bz = bl.getZ(); diff --git a/src/main/java/com/plotsquared/bukkit/listeners/ChunkListener.java b/src/main/java/com/plotsquared/bukkit/listeners/ChunkListener.java index 25f08a667..9ec25d5fa 100644 --- a/src/main/java/com/plotsquared/bukkit/listeners/ChunkListener.java +++ b/src/main/java/com/plotsquared/bukkit/listeners/ChunkListener.java @@ -143,23 +143,23 @@ public class ChunkListener implements Listener { final int x2 = x + 15; final int z2 = z + 15; Plot plot; - plot = MainUtil.getPlot(new Location(world, x, 1, z)); + plot = MainUtil.getPlotAbs(new Location(world, x, 1, z)); if ((plot != null) && (plot.owner != null)) { return false; } - plot = MainUtil.getPlot(new Location(world, x2, 1, z2)); + plot = MainUtil.getPlotAbs(new Location(world, x2, 1, z2)); if ((plot != null) && (plot.owner != null)) { return false; } - plot = MainUtil.getPlot(new Location(world, x2, 1, z)); + plot = MainUtil.getPlotAbs(new Location(world, x2, 1, z)); if ((plot != null) && (plot.owner != null)) { return false; } - plot = MainUtil.getPlot(new Location(world, x, 1, z2)); + plot = MainUtil.getPlotAbs(new Location(world, x, 1, z2)); if ((plot != null) && (plot.owner != null)) { return false; } - plot = MainUtil.getPlot(new Location(world, x + 7, 1, z + 7)); + plot = MainUtil.getPlotAbs(new Location(world, x + 7, 1, z + 7)); if ((plot != null) && (plot.owner != null)) { return false; } diff --git a/src/main/java/com/plotsquared/bukkit/listeners/ForceFieldListener.java b/src/main/java/com/plotsquared/bukkit/listeners/ForceFieldListener.java index c729fedfc..b8f12be3f 100644 --- a/src/main/java/com/plotsquared/bukkit/listeners/ForceFieldListener.java +++ b/src/main/java/com/plotsquared/bukkit/listeners/ForceFieldListener.java @@ -31,48 +31,46 @@ import org.bukkit.event.Listener; import org.bukkit.util.Vector; import com.intellectualcrafters.plot.flag.FlagManager; +import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotPlayer; -import com.intellectualcrafters.plot.util.UUIDHandler; import com.plotsquared.bukkit.events.PlayerEnterPlotEvent; -import com.plotsquared.bukkit.util.BukkitPlayerFunctions; +import com.plotsquared.bukkit.object.BukkitPlayer; import com.plotsquared.bukkit.util.BukkitUtil; /** */ public class ForceFieldListener implements Listener { - private Set getNearbyPlayers(final Player player, final Plot plot) { - final Set players = new HashSet<>(); - Player oPlayer; + private Set getNearbyPlayers(final Player player, final Plot plot) { + final Set players = new HashSet<>(); + PlotPlayer pp; for (final Entity entity : player.getNearbyEntities(5d, 5d, 5d)) { - if (!(entity instanceof Player) || ((oPlayer = (Player) entity) == null) || !BukkitPlayerFunctions.isInPlot(oPlayer) || !BukkitPlayerFunctions.getCurrentPlot(oPlayer).equals(plot)) { + if (!(entity instanceof Player) || ((pp = BukkitUtil.getPlayer((Player) entity)) == null) || !plot.equals(pp.getCurrentPlot())) { continue; } - final UUID uuid = UUIDHandler.getUUID(BukkitUtil.getPlayer(oPlayer)); - if (!plot.isAdded(uuid)) { - players.add(oPlayer); + if (!plot.isAdded(pp.getUUID())) { + players.add(pp); } } return players; } - private Player hasNearbyPermitted(final Player player, final Plot plot) { - Player oPlayer; + private PlotPlayer hasNearbyPermitted(final Player player, final Plot plot) { + PlotPlayer pp; for (final Entity entity : player.getNearbyEntities(5d, 5d, 5d)) { - if (!(entity instanceof Player) || ((oPlayer = (Player) entity) == null) || !BukkitPlayerFunctions.isInPlot(oPlayer) || !BukkitPlayerFunctions.getCurrentPlot(oPlayer).equals(plot)) { + if (!(entity instanceof Player) || ((pp = BukkitUtil.getPlayer((Player) entity)) == null) || !plot.equals(pp.getCurrentPlot())) { continue; } - final UUID uuid = UUIDHandler.getUUID(BukkitUtil.getPlayer(oPlayer)); - if (plot.isAdded(uuid)) { - return oPlayer; + if (plot.isAdded(pp.getUUID())) { + return pp; } } return null; } - public Vector calculateVelocity(final Player p, final Player e) { - final org.bukkit.Location playerLocation = p.getLocation(); - final org.bukkit.Location oPlayerLocation = e.getLocation(); + public Vector calculateVelocity(final PlotPlayer pp, final PlotPlayer e) { + Location playerLocation = pp.getLocationFull(); + Location oPlayerLocation = e.getLocation(); final double playerX = playerLocation.getX(), playerY = playerLocation.getY(), playerZ = playerLocation.getZ(), oPlayerX = oPlayerLocation.getX(), oPlayerY = oPlayerLocation.getY(), oPlayerZ = oPlayerLocation .getZ(); double x = 0d, y = 0d, z = 0d; @@ -98,7 +96,6 @@ public class ForceFieldListener implements Listener { public void onPlotEntry(final PlayerEnterPlotEvent event) { final Player player = event.getPlayer(); final PlotPlayer pp = BukkitUtil.getPlayer(player); - pp.getLocation(); final Plot plot = event.getPlot(); if (plot == null) { return; @@ -107,16 +104,16 @@ public class ForceFieldListener implements Listener { if (!FlagManager.isBooleanFlag(plot, "forcefield", false)) { final UUID uuid = pp.getUUID(); if (plot.isAdded(uuid)) { - final Set players = getNearbyPlayers(player, plot); - for (final Player oPlayer : players) { - oPlayer.setVelocity(calculateVelocity(player, oPlayer)); + final Set players = getNearbyPlayers(player, plot); + for (final PlotPlayer oPlayer : players) { + ((BukkitPlayer) oPlayer).player.setVelocity(calculateVelocity(pp, oPlayer)); } } else { - final Player oPlayer = hasNearbyPermitted(player, plot); + final PlotPlayer oPlayer = hasNearbyPermitted(player, plot); if (oPlayer == null) { return; } - player.setVelocity(calculateVelocity(oPlayer, player)); + player.setVelocity(calculateVelocity(oPlayer, pp)); } } } diff --git a/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents.java b/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents.java index b56ae911b..31c4df757 100644 --- a/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents.java +++ b/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents.java @@ -32,6 +32,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Monster; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; +import org.bukkit.entity.TNTPrimed; import org.bukkit.entity.Tameable; import org.bukkit.entity.ThrownPotion; import org.bukkit.entity.Vehicle; @@ -41,6 +42,8 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.block.BlockExplodeEvent; import org.bukkit.event.block.BlockFadeEvent; import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.block.BlockFromToEvent; @@ -57,6 +60,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; import org.bukkit.event.entity.PotionSplashEvent; import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.hanging.HangingBreakByEntityEvent; @@ -83,6 +87,10 @@ import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.StructureGrowEvent; import org.bukkit.help.HelpTopic; import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.LazyMetadataValue; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.Plugin; import org.bukkit.projectiles.BlockProjectileSource; import org.bukkit.projectiles.ProjectileSource; import org.bukkit.util.Vector; @@ -476,17 +484,17 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen final PlotPlayer pp = BukkitUtil.getPlayer(player); // Set last location - pp.setMeta("location", BukkitUtil.getLocation(to)); + Location loc = BukkitUtil.getLocation(to); + pp.setMeta("location", loc); final String worldname = to.getWorld().getName(); final PlotWorld plotworld = PS.get().getPlotWorld(worldname); if (plotworld == null) { return; } - final PlotManager plotManager = PS.get().getPlotManager(worldname); - final PlotId id = plotManager.getPlotId(plotworld, x2, 0, MathMan.roundInt(to.getZ())); + Plot now = MainUtil.getPlot(loc); final Plot lastPlot = (Plot) pp.getMeta("lastplot"); - if (id == null) { + if (now == null) { if ((lastPlot != null) && !plotExit(pp, lastPlot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED); if (lastPlot.equals(MainUtil.getPlot(BukkitUtil.getLocation(from)))) { @@ -497,13 +505,12 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen event.setCancelled(true); return; } - } else if ((lastPlot != null) && id.equals(lastPlot.id)) { + } else if ((lastPlot != null) && now.equals(lastPlot)) { return; } else { - final Plot plot = MainUtil.getPlot(worldname, id); - if (!plotEntry(pp, plot)) { + if (!plotEntry(pp, now)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED); - if (!plot.equals(MainUtil.getPlot(BukkitUtil.getLocation(from)))) { + if (!now.equals(lastPlot)) { player.teleport(from); } else { player.teleport(player.getWorld().getSpawnLocation()); @@ -534,17 +541,17 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen final PlotPlayer pp = BukkitUtil.getPlayer(player); // Set last location - pp.setMeta("location", BukkitUtil.getLocation(to)); + Location loc = BukkitUtil.getLocation(to); + pp.setMeta("location", loc); final String worldname = to.getWorld().getName(); final PlotWorld plotworld = PS.get().getPlotWorld(worldname); if (plotworld == null) { return; } - final PlotManager plotManager = PS.get().getPlotManager(worldname); - final PlotId id = plotManager.getPlotId(plotworld, x2, 0, z2); + Plot now = MainUtil.getPlot(loc); final Plot lastPlot = (Plot) pp.getMeta("lastplot"); - if (id == null) { + if (now == null) { if ((lastPlot != null) && !plotExit(pp, lastPlot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED); if (lastPlot.equals(MainUtil.getPlot(BukkitUtil.getLocation(from)))) { @@ -555,13 +562,12 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen event.setCancelled(true); return; } - } else if ((lastPlot != null) && id.equals(lastPlot.id)) { + } else if ((lastPlot != null) && now.equals(lastPlot)) { return; } else { - final Plot plot = MainUtil.getPlot(worldname, id); - if (!plotEntry(pp, plot)) { + if (!plotEntry(pp, now)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED); - if (!plot.equals(MainUtil.getPlot(BukkitUtil.getLocation(from)))) { + if (!now.equals(lastPlot)) { player.teleport(from); } else { player.teleport(player.getWorld().getSpawnLocation()); @@ -656,7 +662,7 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen } MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_DESTROY_OTHER); event.setCancelled(true); - } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getSettings().flags.containsKey("done")) { + } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getFlags().containsKey("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); @@ -682,13 +688,32 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen if (!PS.get().isPlotWorld(world)) { return; } - final Plot plot = MainUtil.getPlot(loc); + Plot plot = MainUtil.getPlot(loc); if ((plot != null) && plot.hasOwner()) { if (FlagManager.isPlotFlagTrue(plot, "explosion")) { + List meta = event.getEntity().getMetadata("plot"); + Plot origin; + if (meta.size() == 0) { + origin = plot; + } + else { + origin = (Plot) meta.get(0).value(); + } + if (lastRadius != 0) { + final List nearby = event.getEntity().getNearbyEntities(lastRadius, lastRadius, lastRadius); + for (final Entity near : nearby) { + if ((near instanceof TNTPrimed) || (near.getType() == EntityType.MINECART_TNT)) { + if (!near.hasMetadata("plot")) { + near.setMetadata("plot", new FixedMetadataValue((Plugin) PS.get().IMP, plot)); + } + } + } + lastRadius = 0; + } final Iterator iter = event.blockList().iterator(); while (iter.hasNext()) { final Block b = iter.next(); - if (!plot.equals(MainUtil.getPlot(BukkitUtil.getLocation(b.getLocation())))) { + if (!origin.equals(MainUtil.getPlot(BukkitUtil.getLocation(b.getLocation())))) { iter.remove(); } } @@ -714,8 +739,8 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen final PlotPlayer pp = BukkitUtil.getPlayer(player); // Delete last location - BukkitUtil.getPlayer(event.getPlayer()).deleteMeta("location"); - BukkitUtil.getPlayer(event.getPlayer()).deleteMeta("lastplot"); + pp.deleteMeta("location"); + pp.deleteMeta("lastplot"); if (BukkitMain.worldEdit != null) { if (!Permissions.hasPermission(pp, C.PERMISSION_WORLDEDIT_BYPASS)) { @@ -941,25 +966,6 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen return; } } - if (!Settings.PISTON_FALLING_BLOCK_CHECK) { - return; - } - org.bukkit.Location lastLoc; - if (blocks.size() > 0) { - lastLoc = blocks.get(blocks.size() - 1).getLocation().add(relative); - } else { - lastLoc = event.getBlock().getLocation().add(relative); - } - final Entity[] ents = lastLoc.getChunk().getEntities(); - for (final Entity entity : ents) { - if (entity instanceof FallingBlock) { - final org.bukkit.Location eloc = entity.getLocation(); - if (eloc.distanceSquared(lastLoc) < 2) { - event.setCancelled(true); - return; - } - } - } } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @@ -998,6 +1004,20 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen } } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockDispense(final BlockDispenseEvent e) { + Material type = e.getItem().getType(); + if (type != Material.WATER_BUCKET && type != Material.LAVA_BUCKET) { + return; + } + final Location loc = BukkitUtil.getLocation(e.getVelocity().toLocation(e.getBlock().getWorld())); + if (PS.get().isPlotWorld(loc.getWorld())) { + if (MainUtil.isPlotRoad(loc)) { + e.setCancelled(true); + } + } + } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onStructureGrow(final StructureGrowEvent e) { if (!PS.get().isPlotWorld(e.getWorld().getName())) { @@ -1113,9 +1133,6 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen lb = new BukkitLazyBlock(block); break; } - // TODO calls both: - // redstone ore - lb = new BukkitLazyBlock(new PlotBlock((short) hand.getTypeId(), (byte) hand.getDurability())); switch (hand.getType()) { case MONSTER_EGG: @@ -1205,21 +1222,21 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen } final Location loc = BukkitUtil.getLocation(event.getLocation()); final String world = loc.getWorld(); - if (!PS.get().isPlotWorld(world)) { + final PlotWorld plotworld = PS.get().getPlotWorld(world); + if (plotworld == null) { return; } if (!MainUtil.isPlotArea(loc)) { return; } - final PlotWorld pW = PS.get().getPlotWorld(world); final CreatureSpawnEvent.SpawnReason reason = event.getSpawnReason(); - if (((reason == CreatureSpawnEvent.SpawnReason.SPAWNER_EGG) || (reason == CreatureSpawnEvent.SpawnReason.DISPENSE_EGG)) && !pW.SPAWN_EGGS) { + if (((reason == CreatureSpawnEvent.SpawnReason.SPAWNER_EGG) || (reason == CreatureSpawnEvent.SpawnReason.DISPENSE_EGG)) && !plotworld.SPAWN_EGGS) { event.setCancelled(true); return; - } else if ((reason == CreatureSpawnEvent.SpawnReason.BREEDING) && !pW.SPAWN_BREEDING) { + } else if ((reason == CreatureSpawnEvent.SpawnReason.BREEDING) && !plotworld.SPAWN_BREEDING) { event.setCancelled(true); return; - } else if ((reason == CreatureSpawnEvent.SpawnReason.CUSTOM) && !pW.SPAWN_CUSTOM && !(event.getEntityType().getTypeId() == 30)) { + } else if ((reason == CreatureSpawnEvent.SpawnReason.CUSTOM) && !plotworld.SPAWN_CUSTOM && !(event.getEntityType().getTypeId() == 30)) { event.setCancelled(true); return; } @@ -1227,6 +1244,7 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen final Plot plot = MainUtil.getPlot(loc); if (checkEntity(entity, plot)) { event.setCancelled(true); + return; } } @@ -1248,7 +1266,30 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen } if (FlagManager.isPlotFlagTrue(plot, "disable-physics")) { event.setCancelled(true); + return; } + if (event.getTo().hasGravity()) { + Entity entity = event.getEntity(); + List meta = entity.getMetadata("plot"); + if (meta.size() == 0) { + return; + } + Plot origin = (Plot) meta.get(0).value(); + if (origin != null && !origin.equals(plot)) { + event.setCancelled(true); + entity.remove(); + } + } + else if (event.getTo() == Material.AIR) { + event.getEntity().setMetadata("plot", new FixedMetadataValue((Plugin) PS.get().IMP, plot)); + } + } + + private float lastRadius; + + @EventHandler + public void onPrime(final ExplosionPrimeEvent event) { + lastRadius = event.getRadius() + 1; } public boolean checkEntity(final Entity entity, final Plot plot) { @@ -1260,7 +1301,7 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen if (cap == 0) { return true; } - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); if (mobs[0] >= cap) { return true; } @@ -1273,7 +1314,7 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen return true; } if (mobs == null) { - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); } if (mobs[3] >= cap) { return true; @@ -1287,7 +1328,7 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen return true; } if (mobs == null) { - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); } if (mobs[1] >= cap) { return true; @@ -1301,7 +1342,7 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen return true; } if (mobs == null) { - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); } if (mobs[2] >= cap) { return true; @@ -1316,7 +1357,7 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen return true; } if (mobs == null) { - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); } if (mobs[4] >= cap) { return true; @@ -1401,6 +1442,9 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen } } + // To prevent recursion + private boolean tmp_teleport = true; + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onTeleport(final PlayerTeleportEvent event) { if ((event.getTo() == null) || (event.getFrom() == null)) { @@ -1414,54 +1458,68 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen if (MathMan.roundInt(from.getX()) != (x2 = MathMan.roundInt(to.getX()))) { final Player player = event.getPlayer(); final PlotPlayer pp = BukkitUtil.getPlayer(player); - - // Set last location - pp.setMeta("location", BukkitUtil.getLocation(to)); - + Location loc = BukkitUtil.getLocation(to); + pp.setMeta("location", loc); final String worldname = to.getWorld().getName(); final PlotWorld plotworld = PS.get().getPlotWorld(worldname); if (plotworld == null) { return; } - final PlotManager plotManager = PS.get().getPlotManager(worldname); - final PlotId id = plotManager.getPlotId(plotworld, x2, 0, MathMan.roundInt(to.getZ())); + Plot now = MainUtil.getPlot(loc); final Plot lastPlot = (Plot) pp.getMeta("lastplot"); - if (id == null) { - if ((lastPlot != null) && !plotExit(pp, lastPlot)) { + if (now == null) { + if ((lastPlot != null) && !plotExit(pp, lastPlot) && tmp_teleport) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED); if (lastPlot.equals(MainUtil.getPlot(BukkitUtil.getLocation(from)))) { + tmp_teleport = false; player.teleport(from); + tmp_teleport = true; } else { - player.teleport(player.getWorld().getSpawnLocation()); + Location spawn = BukkitUtil.getLocation(player.getWorld().getSpawnLocation()); + if (spawn.getEuclideanDistanceSquared(pp.getLocation()) > 2) { + tmp_teleport = false; + player.teleport(player.getWorld().getSpawnLocation()); + tmp_teleport = true; + } } event.setCancelled(true); return; } - } else if ((lastPlot != null) && id.equals(lastPlot.id)) { + } else if ((lastPlot != null) && now.equals(lastPlot)) { return; } else { - final Plot plot = MainUtil.getPlot(worldname, id); - if (!plotEntry(pp, plot)) { + if (!plotEntry(pp, now) && tmp_teleport) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED); - if (!plot.equals(MainUtil.getPlot(BukkitUtil.getLocation(from)))) { + if (!now.equals(MainUtil.getPlot(BukkitUtil.getLocation(from)))) { + tmp_teleport = false; player.teleport(from); + tmp_teleport = true; } else { - player.teleport(player.getWorld().getSpawnLocation()); + Location spawn = BukkitUtil.getLocation(player.getWorld().getSpawnLocation()); + if (spawn.getEuclideanDistanceSquared(pp.getLocation()) > 2) { + tmp_teleport = false; + player.teleport(player.getWorld().getSpawnLocation()); + tmp_teleport = true; + } } event.setCancelled(true); return; } } final Integer border = MainUtil.worldBorder.get(worldname); - if (border != null) { + if (border != null && tmp_teleport) { if (x2 > border) { to.setX(border - 4); + tmp_teleport = false; player.teleport(event.getTo()); + tmp_teleport = true; MainUtil.sendMessage(pp, C.BORDER); return; } else if (x2 < -border) { to.setX(-border + 4); + tmp_teleport = false; player.teleport(event.getTo()); + tmp_teleport = true; MainUtil.sendMessage(pp, C.BORDER); return; } @@ -1472,19 +1530,17 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen if (MathMan.roundInt(from.getZ()) != (z2 = MathMan.roundInt(to.getZ()))) { final Player player = event.getPlayer(); final PlotPlayer pp = BukkitUtil.getPlayer(player); - // Set last location - pp.setMeta("location", BukkitUtil.getLocation(to)); - + Location loc = BukkitUtil.getLocation(to); + pp.setMeta("location", loc); final String worldname = to.getWorld().getName(); final PlotWorld plotworld = PS.get().getPlotWorld(worldname); if (plotworld == null) { return; } - final PlotManager plotManager = PS.get().getPlotManager(worldname); - final PlotId id = plotManager.getPlotId(plotworld, x2, 0, z2); + Plot now = MainUtil.getPlot(loc); final Plot lastPlot = (Plot) pp.getMeta("lastplot"); - if (id == null) { + if (now == null) { if ((lastPlot != null) && !plotExit(pp, lastPlot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED); if (lastPlot.equals(MainUtil.getPlot(BukkitUtil.getLocation(from)))) { @@ -1495,13 +1551,12 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen event.setCancelled(true); return; } - } else if ((lastPlot != null) && id.equals(lastPlot.id)) { + } else if ((lastPlot != null) && now.equals(lastPlot)) { return; } else { - final Plot plot = MainUtil.getPlot(worldname, id); - if (!plotEntry(pp, plot)) { + if (!plotEntry(pp, now)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED); - if (!plot.equals(MainUtil.getPlot(BukkitUtil.getLocation(from)))) { + if (!now.equals(lastPlot)) { player.teleport(from); } else { player.teleport(player.getWorld().getSpawnLocation()); @@ -2056,7 +2111,7 @@ public class PlayerEvents extends com.plotsquared.listener.PlotListener implemen event.setCancelled(true); return; } - } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getSettings().flags.containsKey("done")) { + } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getFlags().containsKey("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); diff --git a/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents_1_8.java b/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents_1_8.java index 65b5a96b7..8a85034fa 100644 --- a/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents_1_8.java +++ b/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents_1_8.java @@ -78,7 +78,7 @@ public class PlayerEvents_1_8 extends PlotListener implements Listener { return; } final Location l = BukkitUtil.getLocation(state.getLocation()); - final Plot plot = MainUtil.getPlot(l); + final Plot plot = MainUtil.getPlotAbs(l); final PlotPlayer pp = BukkitUtil.getPlayer(player); boolean cancelled = false; if (plot == null) { @@ -126,7 +126,7 @@ public class PlayerEvents_1_8 extends PlotListener implements Listener { if (!PS.get().isPlotWorld(world)) { return; } - final Plot plot = MainUtil.getPlot(l); + final Plot plot = MainUtil.getPlotAbs(l); final PlotPlayer pp = BukkitUtil.getPlayer(e.getPlayer()); if (plot == null) { if (!MainUtil.isPlotArea(l)) { diff --git a/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents_1_8_3.java b/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents_1_8_3.java index 68c3352da..5bece672b 100644 --- a/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents_1_8_3.java +++ b/src/main/java/com/plotsquared/bukkit/listeners/PlayerEvents_1_8_3.java @@ -24,13 +24,13 @@ public class PlayerEvents_1_8_3 implements Listener { if (!PS.get().isPlotWorld(world)) { return; } - final Plot plot = MainUtil.getPlot(loc); + final Plot plot = MainUtil.getPlotAbs(loc); if ((plot != null) && plot.hasOwner()) { if (FlagManager.isPlotFlagTrue(plot, "explosion")) { final Iterator iter = event.blockList().iterator(); while (iter.hasNext()) { final Block b = iter.next(); - if (!plot.equals(MainUtil.getPlot(BukkitUtil.getLocation(b.getLocation())))) { + if (!plot.equals(MainUtil.getPlotAbs(BukkitUtil.getLocation(b.getLocation())))) { iter.remove(); } } diff --git a/src/main/java/com/plotsquared/bukkit/listeners/PlotPlusListener.java b/src/main/java/com/plotsquared/bukkit/listeners/PlotPlusListener.java index 543aa2766..a1f0111ce 100644 --- a/src/main/java/com/plotsquared/bukkit/listeners/PlotPlusListener.java +++ b/src/main/java/com/plotsquared/bukkit/listeners/PlotPlusListener.java @@ -109,7 +109,7 @@ public class PlotPlusListener extends PlotListener implements Listener { if (player.getGameMode() != GameMode.SURVIVAL) { return; } - final Plot plot = MainUtil.getPlot(BukkitUtil.getLocation(player)); + final Plot plot = MainUtil.getPlotAbs(BukkitUtil.getLocation(player)); if (plot == null) { return; } @@ -124,7 +124,7 @@ public class PlotPlusListener extends PlotListener implements Listener { return; } final Player player = (Player) event.getEntity(); - final Plot plot = MainUtil.getPlot(BukkitUtil.getLocation(player)); + final Plot plot = MainUtil.getPlotAbs(BukkitUtil.getLocation(player)); if (plot == null) { return; } @@ -137,7 +137,7 @@ public class PlotPlusListener extends PlotListener implements Listener { public void onItemPickup(final PlayerPickupItemEvent event) { final Player player = event.getPlayer(); final PlotPlayer pp = BukkitUtil.getPlayer(player); - final Plot plot = MainUtil.getPlot(pp.getLocation()); + final Plot plot = MainUtil.getPlotAbs(pp.getLocation()); if (plot == null) { return; } @@ -151,7 +151,7 @@ public class PlotPlusListener extends PlotListener implements Listener { public void onItemDrop(final PlayerDropItemEvent event) { final Player player = event.getPlayer(); final PlotPlayer pp = BukkitUtil.getPlayer(player); - final Plot plot = MainUtil.getPlot(pp.getLocation()); + final Plot plot = MainUtil.getPlotAbs(pp.getLocation()); if (plot == null) { return; } diff --git a/src/main/java/com/plotsquared/bukkit/listeners/TNTListener.java b/src/main/java/com/plotsquared/bukkit/listeners/TNTListener.java deleted file mode 100644 index eb4bf39f2..000000000 --- a/src/main/java/com/plotsquared/bukkit/listeners/TNTListener.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.plotsquared.bukkit.listeners; - -import java.util.List; - -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.TNTPrimed; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.entity.ExplosionPrimeEvent; -import org.bukkit.util.Vector; - -import com.intellectualcrafters.plot.PS; -import com.intellectualcrafters.plot.flag.FlagManager; -import com.intellectualcrafters.plot.object.Location; -import com.intellectualcrafters.plot.object.Plot; -import com.intellectualcrafters.plot.util.MainUtil; -import com.plotsquared.bukkit.util.BukkitUtil; - -public class TNTListener implements Listener { - private double lastRadius; - - @EventHandler - public void onPrime(final ExplosionPrimeEvent event) { - lastRadius = event.getRadius() + 1; - } - - @EventHandler - public void onExplode(final EntityExplodeEvent event) { - final Entity entity = event.getEntity(); - if (entity == null) { - return; - } - final World world = entity.getWorld(); - final String worldname = world.getName(); - if (!PS.get().isPlotWorld(worldname)) { - return; - } - final Plot plot = MainUtil.getPlot(BukkitUtil.getLocation(entity)); - if (plot == null) { - return; - } - - if (!FlagManager.isPlotFlagTrue(plot, "explosion")) { - return; - } - - final Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id); - final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id); - - final List nearby = entity.getNearbyEntities(lastRadius, lastRadius, lastRadius); - for (final Entity near : nearby) { - if ((near instanceof TNTPrimed) || (near.getType() == EntityType.MINECART_TNT)) { - final Vector velocity = near.getVelocity(); - final Location loc = BukkitUtil.getLocation(near); - final Plot nearPlot = MainUtil.getPlot(loc); - if (!plot.equals(nearPlot)) { - near.setVelocity(new Vector(0, 0, 0)); - continue; - } - final double vx = velocity.getX(); - velocity.getX(); - final double vz = velocity.getX(); - - int dx; - int dz; - - if (vx > 0) { - dx = top.getX() - loc.getX(); - } else { - dx = bot.getX() - loc.getX(); - } - if (vz > 0) { - dz = top.getZ() - loc.getZ(); - } else { - dz = bot.getZ() - loc.getZ(); - } - - final double s1 = dx / vx; - final double s2 = dz / vz; - final Vector v1 = new Vector(dx, 0, vz * s1); - final Vector v2 = new Vector(vx * s2, 0, dz); - - Vector shortest; - if (v1.length() < v2.length()) { - shortest = v1; - } else { - shortest = v2; - } - - final Location landing = loc.add(shortest.getBlockX() + 1, 0, shortest.getBlockZ() + 1); - final int ty = MainUtil.getHeighestBlock(worldname, landing.getX(), landing.getZ()); - final int diff = ty - loc.getY(); - final double calcDiff = getY(velocity, Math.sqrt((shortest.getBlockX() * shortest.getBlockX()) + (shortest.getBlockZ() * shortest.getBlockZ()))); - if (calcDiff > diff) { - near.setVelocity(new Vector(0, 0, 0)); - } - } - } - event.getEntity().setVelocity(new Vector(0, 0, 0)); - } - - public double getY(final Vector velocity, final double x) { - - final double g = 16; - final double l1 = velocity.length(); - final double l2 = Math.sqrt((velocity.getX() * velocity.getX()) + (velocity.getZ() * velocity.getZ())); - - final double v = l1 * 20; - double theta = Math.acos(l2 / l1); - if (velocity.getY() < 0) { - theta = -theta; - } - final double cos = Math.cos(theta); - final double yDiff = (x * Math.tan(theta)) - ((g * x * x) / (2 * (v * v * cos * cos))); - return yDiff; - } -} diff --git a/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WEListener.java b/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WEListener.java index bc99ace52..799722b23 100644 --- a/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WEListener.java +++ b/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WEListener.java @@ -305,7 +305,7 @@ public class WEListener implements Listener { } } if (restricted.contains(reduced)) { - final Plot plot = MainUtil.getPlot(pp.getLocation()); + final Plot plot = MainUtil.getPlotAbs(pp.getLocation()); if ((plot != null) && plot.isAdded(pp.getUUID())) { if (delay(p, message, false)) { e.setCancelled(true); diff --git a/src/main/java/com/plotsquared/bukkit/object/BukkitPlayer.java b/src/main/java/com/plotsquared/bukkit/object/BukkitPlayer.java index f3b83c38e..22c9b9d5f 100644 --- a/src/main/java/com/plotsquared/bukkit/object/BukkitPlayer.java +++ b/src/main/java/com/plotsquared/bukkit/object/BukkitPlayer.java @@ -177,9 +177,14 @@ public class BukkitPlayer extends PlotPlayer { } Permission perm = Bukkit.getServer().getPluginManager().getPermission(key); if (perm == null) { - perm = new Permission(key, PermissionDefault.FALSE); - Bukkit.getServer().getPluginManager().addPermission(perm); - Bukkit.getServer().getPluginManager().recalculatePermissionDefaults(perm); + try { + perm = new Permission(key, PermissionDefault.FALSE); + Bukkit.getServer().getPluginManager().addPermission(perm); + Bukkit.getServer().getPluginManager().recalculatePermissionDefaults(perm); + } + catch (Exception e) { + e.printStackTrace(); + } } return player.hasPermission(key); } diff --git a/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java b/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java index 45fe46431..852855f42 100644 --- a/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java +++ b/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Random; +import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -67,11 +68,11 @@ import com.plotsquared.bukkit.object.entity.EntityWrapper; public class BukkitChunkManager extends ChunkManager { @Override - public ArrayList getChunkChunks(final String world) { + public Set getChunkChunks(final String world) { final String directory = Bukkit.getWorldContainer() + File.separator + world + File.separator + "region"; final File folder = new File(directory); final File[] regionFiles = folder.listFiles(); - final ArrayList chunks = new ArrayList<>(); + final HashSet chunks = new HashSet<>(); if (regionFiles == null) { throw new RuntimeException("Could not find worlds folder."); } @@ -107,7 +108,7 @@ public class BukkitChunkManager extends ChunkManager { for (final Player player : worldObj.getPlayers()) { final org.bukkit.Location locObj = player.getLocation(); if (((locObj.getBlockX() >> 4) == loc.x) && ((locObj.getBlockZ() >> 4) == loc.z) && !locObj.getBlock().isEmpty()) { - final Plot plot = MainUtil.getPlot(BukkitUtil.getLocation(locObj)); + final Plot plot = MainUtil.getPlotAbs(BukkitUtil.getLocation(locObj)); if (plot != null) { final PlotPlayer pp = BukkitUtil.getPlayer(player); pp.teleport(MainUtil.getDefaultHome(plot)); @@ -167,12 +168,12 @@ public class BukkitChunkManager extends ChunkManager { final int z2 = z1 + 15; final Location bot = new Location(world, x1, 0, z1); Plot plot; - plot = MainUtil.getPlot(bot); + plot = MainUtil.getPlotAbs(bot); if ((plot != null) && (plot.owner != null)) { return plot; } final Location top = new Location(world, x2, 0, z2); - plot = MainUtil.getPlot(top); + plot = MainUtil.getPlotAbs(top); if ((plot != null) && (plot.owner != null)) { return plot; } @@ -198,9 +199,6 @@ public class BukkitChunkManager extends ChunkManager { private static HashMap bannerBase; private static HashSet entities; - /** - * Copy a region to a new location (in the same world) - */ @Override public boolean copyRegion(final Location pos1, final Location pos2, final Location newPos, final Runnable whenDone) { final int relX = newPos.getX() - pos1.getX(); @@ -254,7 +252,6 @@ public class BukkitChunkManager extends ChunkManager { }, new Runnable() { @Override public void run() { - // TODO whenDone TaskManager.runTask(whenDone); } }, 5); @@ -947,7 +944,7 @@ public class BukkitChunkManager extends ChunkManager { return BukkitUtil.getWorld(world).unloadChunk(loc.x, loc.z, save, safe); } - public static void swapChunk(final World world, final Chunk pos1, final Chunk pos2, final RegionWrapper r1, final RegionWrapper r2) { + public static void swapChunk(final World world1, final World world2, final Chunk pos1, final Chunk pos2, final RegionWrapper r1, final RegionWrapper r2) { initMaps(); final int relX = (r2.minX - r1.minX); final int relZ = (r2.minZ - r1.minZ); @@ -958,29 +955,27 @@ public class BukkitChunkManager extends ChunkManager { final int sx = pos1.getX() << 4; final int sz = pos1.getZ() << 4; - final int maxY = world.getMaxHeight(); - for (int x = Math.max(r1.minX, sx); x <= Math.min(r1.maxX, sx + 15); x++) { for (int z = Math.max(r1.minZ, sz); z <= Math.min(r1.maxZ, sz + 15); z++) { - saveBlocks(world, maxY, sx, sz, relX, relZ); - for (int y = 0; y < maxY; y++) { - final Block block1 = world.getBlockAt(x, y, z); + saveBlocks(world1, 256, sx, sz, relX, relZ); + for (int y = 0; y < 256; y++) { + final Block block1 = world1.getBlockAt(x, y, z); final int id1 = block1.getTypeId(); final byte data1 = block1.getData(); final int xx = x + relX; final int zz = z + relZ; - final Block block2 = world.getBlockAt(xx, y, zz); + final Block block2 = world2.getBlockAt(xx, y, zz); final int id2 = block2.getTypeId(); final byte data2 = block2.getData(); if (id1 == 0) { if (id2 != 0) { - BukkitSetBlockManager.setBlockManager.set(world, x, y, z, id2, data2); - BukkitSetBlockManager.setBlockManager.set(world, xx, y, zz, 0, (byte) 0); + BukkitSetBlockManager.setBlockManager.set(world1, x, y, z, id2, data2); + BukkitSetBlockManager.setBlockManager.set(world2, xx, y, zz, 0, (byte) 0); } } else if (id2 == 0) { if (id1 != 0) { - BukkitSetBlockManager.setBlockManager.set(world, xx, y, zz, id1, data1); - BukkitSetBlockManager.setBlockManager.set(world, x, y, z, 0, (byte) 0); + BukkitSetBlockManager.setBlockManager.set(world1, x, y, z, 0, (byte) 0); + BukkitSetBlockManager.setBlockManager.set(world2, xx, y, zz, id1, data1); } } else if (id1 == id2) { if (data1 != data2) { @@ -988,52 +983,35 @@ public class BukkitChunkManager extends ChunkManager { block2.setData(data1); } } else { - BukkitSetBlockManager.setBlockManager.set(world, x, y, z, id2, data2); - BukkitSetBlockManager.setBlockManager.set(world, xx, y, zz, id1, data1); + BukkitSetBlockManager.setBlockManager.set(world1, x, y, z, id2, data2); + BukkitSetBlockManager.setBlockManager.set(world2, xx, y, zz, id1, data1); } } } } - restoreBlocks(world, 0, 0); - restoreEntities(world, 0, 0); + restoreBlocks(world1, 0, 0); + restoreEntities(world1, 0, 0); } @Override - public void swap(final String worldname, final PlotId pos1, final PlotId pos2) { - final Location bot1 = MainUtil.getPlotBottomLoc(worldname, pos1).add(1, 0, 1); - final Location top1 = MainUtil.getPlotTopLoc(worldname, pos1); - - final Location bot2 = MainUtil.getPlotBottomLoc(worldname, pos2).add(1, 0, 1); - final Location top2 = MainUtil.getPlotTopLoc(worldname, pos2); - swap(worldname, bot1, top1, bot2, top2); - - final Plot plot1 = MainUtil.getPlot(worldname, pos1); - final Plot plot2 = MainUtil.getPlot(worldname, pos2); - - // TODO clear all entities - - clearAllEntities(plot1.getBottom(), plot1.getTop()); - clearAllEntities(plot2.getBottom(), plot2.getTop()); - } - - @Override - public void swap(final String worldname, final Location bot1, final Location top1, final Location bot2, final Location top2) { + public void swap(final Location bot1, final Location top1, final Location bot2, final Location top2, final Runnable whenDone) { final RegionWrapper region1 = new RegionWrapper(bot1.getX(), top1.getX(), bot1.getZ(), top1.getZ()); final RegionWrapper region2 = new RegionWrapper(bot2.getX(), top2.getX(), bot2.getZ(), top2.getZ()); - final World world = Bukkit.getWorld(bot1.getWorld()); + final World world1 = Bukkit.getWorld(bot1.getWorld()); + final World world2 = Bukkit.getWorld(bot2.getWorld()); final int relX = bot2.getX() - bot1.getX(); final int relZ = bot2.getZ() - bot1.getZ(); for (int x = bot1.getX() >> 4; x <= (top1.getX() >> 4); x++) { for (int z = bot1.getZ() >> 4; z <= (top1.getZ() >> 4); z++) { - final Chunk chunk1 = world.getChunkAt(x, z); - final Chunk chunk2 = world.getChunkAt(x + (relX >> 4), z + (relZ >> 4)); - swapChunk(world, chunk1, chunk2, region1, region2); + final Chunk chunk1 = world1.getChunkAt(x, z); + final Chunk chunk2 = world2.getChunkAt(x + (relX >> 4), z + (relZ >> 4)); + swapChunk(world1, world2, chunk1, chunk2, region1, region2); } } - // FIXME swap plots + TaskManager.runTaskLater(whenDone, 1); } @Override @@ -1041,8 +1019,8 @@ public class BukkitChunkManager extends ChunkManager { final int[] count = new int[5]; final World world = BukkitUtil.getWorld(plot.world); - final Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); - final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id); + final Location bot = MainUtil.getPlotBottomLocAbs(plot.world, plot.id); + final Location top = MainUtil.getPlotTopLocAbs(plot.world, plot.id); final int bx = bot.getX() >> 4; final int bz = bot.getZ() >> 4; diff --git a/src/main/java/com/plotsquared/bukkit/util/BukkitHybridUtils.java b/src/main/java/com/plotsquared/bukkit/util/BukkitHybridUtils.java index caa3a00d3..8dce0107d 100644 --- a/src/main/java/com/plotsquared/bukkit/util/BukkitHybridUtils.java +++ b/src/main/java/com/plotsquared/bukkit/util/BukkitHybridUtils.java @@ -22,6 +22,7 @@ import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotAnalysis; import com.intellectualcrafters.plot.object.PlotBlock; +import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.object.RunnableVal; import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.MainUtil; @@ -31,7 +32,7 @@ import com.intellectualcrafters.plot.util.TaskManager; public class BukkitHybridUtils extends HybridUtils { @Override - public void analyzePlot(final Plot plot, final RunnableVal whenDone) { + public void analyzeRegion(final String world, final RegionWrapper region, final RunnableVal whenDone) { // int diff, int variety, int verticies, int rotation, int height_sd /* * diff: compare to base by looping through all blocks @@ -47,12 +48,12 @@ public class BukkitHybridUtils extends HybridUtils { TaskManager.runTaskAsync(new Runnable() { @Override public void run() { - final World world = Bukkit.getWorld(plot.world); - final ChunkGenerator gen = world.getGenerator(); + final World worldObj = Bukkit.getWorld(world); + final ChunkGenerator gen = worldObj.getGenerator(); if (gen == null) { return; } - final BiomeGrid base = new BiomeGrid() { + final BiomeGrid nullBiomeGrid = new BiomeGrid() { @Override public void setBiome(final int a, final int b, final Biome c) {} @@ -61,8 +62,13 @@ public class BukkitHybridUtils extends HybridUtils { return null; } }; - final Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); - final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id); + + final Location bot = new Location(world, region.minX, region.minY, region.minZ); + final Location top = new Location(world, region.maxX, region.maxY, region.maxZ); + +// final Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); +// final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id); + final int bx = bot.getX(); final int bz = bot.getZ(); final int tx = top.getX(); @@ -87,10 +93,10 @@ public class BukkitHybridUtils extends HybridUtils { ChunkManager.chunkTask(bot, top, new RunnableVal() { @Override public void run() { - // TODO [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge] + // [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge] final int X = value[0]; final int Z = value[1]; - final short[][] result = gen.generateExtBlockSections(world, r, X, Z, base); + final short[][] result = gen.generateExtBlockSections(worldObj, r, X, Z, nullBiomeGrid); final int xb = ((X) << 4) - bx; final int zb = ((Z) << 4) - bz; for (int i = 0; i < result.length; i++) { @@ -202,21 +208,6 @@ public class BukkitHybridUtils extends HybridUtils { analysis.data_sd = (int) (MathMan.getSD(data, analysis.data)); analysis.air_sd = (int) (MathMan.getSD(air, analysis.air)); analysis.variety_sd = (int) (MathMan.getSD(variety, analysis.variety)); - - final List result = new ArrayList<>(); - result.add(analysis.changes); - result.add(analysis.faces); - result.add(analysis.data); - result.add(analysis.air); - result.add(analysis.variety); - - result.add(analysis.changes_sd); - result.add(analysis.faces_sd); - result.add(analysis.data_sd); - result.add(analysis.air_sd); - result.add(analysis.variety_sd); - final Flag flag = new Flag(FlagManager.getFlag("analysis"), result); - FlagManager.addPlotFlag(plot, flag); System.gc(); System.gc(); whenDone.value = analysis; @@ -236,7 +227,7 @@ public class BukkitHybridUtils extends HybridUtils { public void run() { final int X = value[0]; final int Z = value[1]; - world.loadChunk(X, Z); + worldObj.loadChunk(X, Z); int minX; int minZ; int maxX; @@ -272,14 +263,14 @@ public class BukkitHybridUtils extends HybridUtils { for (int z = minZ; z <= maxZ; z++) { final int zz = cbz + z; for (int y = 0; y < 256; y++) { - final Block block = world.getBlockAt(xx, y, zz); + final Block block = worldObj.getBlockAt(xx, y, zz); final int xr = xb + x; final int zr = zb + z; newblocks[y][xr][zr] = (short) block.getTypeId(); } } } - world.unloadChunkRequest(X, Z, true); + worldObj.unloadChunkRequest(X, Z, true); } }, new Runnable() { @Override diff --git a/src/main/java/com/plotsquared/bukkit/util/BukkitPlayerFunctions.java b/src/main/java/com/plotsquared/bukkit/util/BukkitPlayerFunctions.java deleted file mode 100644 index 0c746ab68..000000000 --- a/src/main/java/com/plotsquared/bukkit/util/BukkitPlayerFunctions.java +++ /dev/null @@ -1,140 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////// -// PlotSquared - A plot manager and world generator for the Bukkit API / -// Copyright (c) 2014 IntellectualSites/IntellectualCrafters / -// / -// This program is free software; you can redistribute it and/or modify / -// it under the terms of the GNU General Public License as published by / -// the Free Software Foundation; either version 3 of the License, or / -// (at your option) any later version. / -// / -// This program is distributed in the hope that it will be useful, / -// but WITHOUT ANY WARRANTY; without even the implied warranty of / -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the / -// GNU General Public License for more details. / -// / -// You should have received a copy of the GNU General Public License / -// along with this program; if not, write to the Free Software Foundation, / -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA / -// / -// You can contact us via: support@intellectualsites.com / -//////////////////////////////////////////////////////////////////////////////////////////////////// -package com.plotsquared.bukkit.util; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -import org.bukkit.entity.Player; - -import com.intellectualcrafters.plot.PS; -import com.intellectualcrafters.plot.config.C; -import com.intellectualcrafters.plot.object.Plot; -import com.intellectualcrafters.plot.object.PlotId; -import com.intellectualcrafters.plot.util.MainUtil; -import com.intellectualcrafters.plot.util.UUIDHandler; - -/** - * Functions involving players, plots and locations. - */ -public class BukkitPlayerFunctions { - - /* - * =========== NOTICE ================ - * - We will try to move as many functions as we can out of this class and into the MainUtil class - */ - - /** - * Clear a plot. Use null player if no player is present - * @param player - * @param world - * @param plot - * @param isDelete - */ - public static void clear(final Player player, final String world, final Plot plot, final boolean isDelete) { - final long start = System.currentTimeMillis(); - final Runnable whenDone = new Runnable() { - @Override - public void run() { - if ((player != null) && player.isOnline()) { - MainUtil.sendMessage(BukkitUtil.getPlayer(player), C.CLEARING_DONE, "" + (System.currentTimeMillis() - start)); - } - } - }; - if (!MainUtil.clearAsPlayer(plot, isDelete, whenDone)) { - MainUtil.sendMessage(null, C.WAIT_FOR_TIMER); - } - } - - public static String getPlayerName(final UUID uuid) { - if (uuid == null) { - return "unknown"; - } - final String name = UUIDHandler.getName(uuid); - if (name == null) { - return "unknown"; - } - return name; - } - - /** - * @param player player - * - * @return boolean - */ - public static boolean isInPlot(final Player player) { - return getCurrentPlot(player) != null; - } - - public static ArrayList getMaxPlotSelectionIds(final String world, PlotId pos1, PlotId pos2) { - final Plot plot1 = PS.get().getPlot(world, pos1); - final Plot plot2 = PS.get().getPlot(world, pos2); - if (plot1 != null) { - pos1 = MainUtil.getBottomPlot(plot1).id; - } - if (plot2 != null) { - pos2 = MainUtil.getTopPlot(plot2).id; - } - final ArrayList myplots = new ArrayList<>(); - for (int x = pos1.x; x <= pos2.x; x++) { - for (int y = pos1.y; y <= pos2.y; y++) { - myplots.add(new PlotId(x, y)); - } - } - return myplots; - } - - /** - * Returns the plot a player is currently in. - * - * @param player - * - * @return boolean - */ - public static Plot getCurrentPlot(final Player player) { - if (!PS.get().isPlotWorld(player.getWorld().getName())) { - return null; - } - final PlotId id = MainUtil.getPlotId(BukkitUtil.getLocation(player)); - final String world = player.getWorld().getName(); - if (id == null) { - return null; - } - return MainUtil.getPlot(world, id); - } - - /** - * Get the plots for a player - * - * @param plr - * - * @return boolean - */ - public static Set getPlayerPlots(final String world, final Player plr) { - final Set p = PS.get().getPlots(world, plr.getName()); - if (p == null) { - return new HashSet<>(); - } - return p; - } -} diff --git a/src/main/java/com/plotsquared/bukkit/util/BukkitSchematicHandler.java b/src/main/java/com/plotsquared/bukkit/util/BukkitSchematicHandler.java index 65022234f..2abab4914 100644 --- a/src/main/java/com/plotsquared/bukkit/util/BukkitSchematicHandler.java +++ b/src/main/java/com/plotsquared/bukkit/util/BukkitSchematicHandler.java @@ -20,11 +20,14 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// package com.plotsquared.bukkit.util; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -41,8 +44,13 @@ import com.intellectualcrafters.jnbt.StringTag; import com.intellectualcrafters.jnbt.Tag; import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.Location; +import com.intellectualcrafters.plot.object.Plot; +import com.intellectualcrafters.plot.object.PlotId; +import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.object.RunnableVal; +import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.SchematicHandler; +import com.intellectualcrafters.plot.util.StringMan; import com.intellectualcrafters.plot.util.TaskManager; import com.plotsquared.object.schematic.StateWrapper; @@ -53,32 +61,21 @@ import com.plotsquared.object.schematic.StateWrapper; public class BukkitSchematicHandler extends SchematicHandler { @Override - public void getCompoundTag(final String world, final Location pos1, final Location pos2, final RunnableVal whenDone) { - + public void getCompoundTag(final String world, final Set regions, final RunnableVal whenDone) { // async TaskManager.runTaskAsync(new Runnable() { - @Override public void run() { // Main positions - final int p1x = pos1.getX(); - final int p1z = pos1.getZ(); - final int p2x = pos2.getX(); - final int p2z = pos2.getZ(); - final int bcx = p1x >> 4; - final int bcz = p1z >> 4; - final int tcx = p2x >> 4; - final int tcz = p2z >> 4; - final int sy = pos1.getY(); - final int ey = pos2.getY(); - - final int width = (pos2.getX() - pos1.getX()) + 1; - final int height = (pos2.getY() - pos1.getY()) + 1; - final int length = (pos2.getZ() - pos1.getZ()) + 1; + Location[] corners = MainUtil.getCorners(world, regions); + final Location bot = corners[0]; + final Location top = corners[1]; + final int width = (top.getX() - bot.getX()) + 1; + final int height = (top.getY() - bot.getY()) + 1; + final int length = (top.getZ() - bot.getZ()) + 1; // Main Schematic tag final HashMap schematic = new HashMap<>(); - schematic.put("Width", new ShortTag("Width", (short) width)); schematic.put("Length", new ShortTag("Length", (short) length)); schematic.put("Height", new ShortTag("Height", (short) height)); @@ -89,214 +86,16 @@ public class BukkitSchematicHandler extends SchematicHandler { schematic.put("WEOffsetX", new IntTag("WEOffsetX", 0)); schematic.put("WEOffsetY", new IntTag("WEOffsetY", 0)); schematic.put("WEOffsetZ", new IntTag("WEOffsetZ", 0)); - // Arrays of data types final List tileEntities = new ArrayList(); final byte[] blocks = new byte[width * height * length]; final byte[] blockData = new byte[width * height * length]; - - // Generate list of chunks - final ArrayList chunks = new ArrayList(); - for (int x = bcx; x <= tcx; x++) { - for (int z = bcz; z <= tcz; z++) { - chunks.add(new ChunkLoc(x, z)); - } - } - - final World worldObj = Bukkit.getWorld(world); - // Main thread + // Queue + final ArrayDeque queue = new ArrayDeque<>(regions); TaskManager.runTask(new Runnable() { @Override public void run() { - final long start = System.currentTimeMillis(); - while ((chunks.size() > 0) && ((System.currentTimeMillis() - start) < 20)) { - // save schematics - final ChunkLoc chunk = chunks.remove(0); - - final Chunk bc = worldObj.getChunkAt(chunk.x, chunk.z); - if (!bc.load(false)) { - continue; - } - - final int X = chunk.x; - final int Z = chunk.z; - int xxb = X << 4; - int zzb = Z << 4; - int xxt = xxb + 15; - int zzt = zzb + 15; - - if (X == bcx) { - xxb = p1x; - } - if (X == tcx) { - xxt = p2x; - } - if (Z == bcz) { - zzb = p1z; - } - if (Z == tcz) { - zzt = p2z; - } - for (int y = sy; y <= Math.min(255, ey); y++) { - final int ry = y - sy; - final int i1 = (ry * width * length); - for (int z = zzb; z <= zzt; z++) { - final int rz = z - p1z; - final int i2 = i1 + (rz * width); - for (int x = xxb; x <= xxt; x++) { - final int rx = x - p1x; - final int index = i2 + rx; - final Block block = worldObj.getBlockAt(x, y, z); - final int id = block.getTypeId(); - switch (id) { - case 0: - case 2: - case 4: - case 13: - case 14: - case 15: - case 20: - case 21: - case 22: - case 24: - case 30: - case 32: - case 37: - case 39: - case 40: - case 41: - case 42: - case 45: - case 46: - case 47: - case 48: - case 49: - case 50: - case 51: - case 55: - case 56: - case 57: - case 58: - case 60: - case 7: - case 8: - case 9: - case 10: - case 11: - case 73: - case 74: - case 75: - case 76: - case 78: - case 79: - case 80: - case 81: - case 82: - case 83: - case 85: - case 87: - case 88: - case 101: - case 102: - case 103: - case 110: - case 112: - case 113: - case 121: - case 122: - case 129: - case 133: - case 165: - case 166: - case 169: - case 170: - case 172: - case 173: - case 174: - case 181: - case 182: - case 188: - case 189: - case 190: - case 191: - case 192: { - break; - } - case 54: - case 130: - case 142: - case 27: - case 137: - case 52: - case 154: - case 84: - case 25: - case 144: - case 138: - case 176: - case 177: - case 63: - case 68: - case 323: - case 117: - case 116: - case 28: - case 66: - case 157: - case 61: - case 62: - case 140: - case 146: - case 149: - case 150: - case 158: - case 23: - case 123: - case 124: - case 29: - case 33: - case 151: - case 178: { - // TODO implement fully - final BlockState state = block.getState(); - if (state != null) { - final StateWrapper wrapper = new StateWrapper(state); - final CompoundTag rawTag = wrapper.getTag(); - if (rawTag != null) { - final Map values = new HashMap(); - for (final Entry entry : rawTag.getValue().entrySet()) { - values.put(entry.getKey(), entry.getValue()); - } - values.put("id", new StringTag("id", wrapper.getId())); - values.put("x", new IntTag("x", x)); - values.put("y", new IntTag("y", y)); - values.put("z", new IntTag("z", z)); - final CompoundTag tileEntityTag = new CompoundTag(values); - tileEntities.add(tileEntityTag); - } - } - } - default: { - blockData[index] = block.getData(); - } - } - // For optimization reasons, we are not supporting custom data types - // Especially since the most likely reason beyond this range is modded servers in which the blocks have NBT - // if (id > 255) { - // if (addBlocks == null) { - // addBlocks = new byte[(blocks.length >> 1) + 1]; - // } - // addBlocks[index >> 1] = (byte) (((index & 1) == 0) ? (addBlocks[index >> 1] & 0xF0) | ((id >> 8) & 0xF) : (addBlocks[index >> 1] & 0xF) | (((id >> 8) & 0xF) << 4)); - // } - blocks[index] = (byte) id; - } - } - } - - } - if (chunks.size() != 0) { - TaskManager.runTaskLater(this, 1); - } else { + if (queue.size() == 0) { TaskManager.runTaskAsync(new Runnable() { @Override public void run() { @@ -310,7 +109,226 @@ public class BukkitSchematicHandler extends SchematicHandler { System.gc(); } }); + return; } + final Runnable regionTask = this; + RegionWrapper region = queue.poll(); + Location pos1 = new Location(world, region.minX, region.minY, region.minZ); + Location pos2 = new Location(world, region.maxX, region.maxY, region.maxZ); + final int bx = bot.getX(); + final int bz = bot.getZ(); + final int p1x = pos1.getX(); + final int p1z = pos1.getZ(); + final int p2x = pos2.getX(); + final int p2z = pos2.getZ(); + final int bcx = p1x >> 4; + final int bcz = p1z >> 4; + final int tcx = p2x >> 4; + final int tcz = p2z >> 4; + final int sy = pos1.getY(); + final int ey = pos2.getY(); + // Generate list of chunks + final ArrayList chunks = new ArrayList(); + for (int x = bcx; x <= tcx; x++) { + for (int z = bcz; z <= tcz; z++) { + chunks.add(new ChunkLoc(x, z)); + } + } + final World worldObj = Bukkit.getWorld(world); + // Main thread + TaskManager.runTask(new Runnable() { + @Override + public void run() { + final long start = System.currentTimeMillis(); + while ((chunks.size() > 0) && ((System.currentTimeMillis() - start) < 20)) { + // save schematics + final ChunkLoc chunk = chunks.remove(0); + final Chunk bc = worldObj.getChunkAt(chunk.x, chunk.z); + if (!bc.load(false)) { + continue; + } + final int X = chunk.x; + final int Z = chunk.z; + int xxb = X << 4; + int zzb = Z << 4; + int xxt = xxb + 15; + int zzt = zzb + 15; + + if (X == bcx) { + xxb = p1x; + } + if (X == tcx) { + xxt = p2x; + } + if (Z == bcz) { + zzb = p1z; + } + if (Z == tcz) { + zzt = p2z; + } + for (int y = sy; y <= Math.min(255, ey); y++) { + final int ry = y - sy; + final int i1 = (ry * width * length); + for (int z = zzb; z <= zzt; z++) { + final int rz = z - bz; + final int i2 = i1 + (rz * width); + for (int x = xxb; x <= xxt; x++) { + final int rx = x - bx; + final int index = i2 + rx; + final Block block = worldObj.getBlockAt(x, y, z); + final int id = block.getTypeId(); + switch (id) { + case 0: + case 2: + case 4: + case 13: + case 14: + case 15: + case 20: + case 21: + case 22: + case 24: + case 30: + case 32: + case 37: + case 39: + case 40: + case 41: + case 42: + case 45: + case 46: + case 47: + case 48: + case 49: + case 50: + case 51: + case 55: + case 56: + case 57: + case 58: + case 60: + case 7: + case 8: + case 9: + case 10: + case 11: + case 73: + case 74: + case 75: + case 76: + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + case 85: + case 87: + case 88: + case 101: + case 102: + case 103: + case 110: + case 112: + case 113: + case 121: + case 122: + case 129: + case 133: + case 165: + case 166: + case 169: + case 170: + case 172: + case 173: + case 174: + case 181: + case 182: + case 188: + case 189: + case 190: + case 191: + case 192: { + break; + } + case 54: + case 130: + case 142: + case 27: + case 137: + case 52: + case 154: + case 84: + case 25: + case 144: + case 138: + case 176: + case 177: + case 63: + case 68: + case 323: + case 117: + case 116: + case 28: + case 66: + case 157: + case 61: + case 62: + case 140: + case 146: + case 149: + case 150: + case 158: + case 23: + case 123: + case 124: + case 29: + case 33: + case 151: + case 178: { + // TODO implement fully + final BlockState state = block.getState(); + if (state != null) { + final StateWrapper wrapper = new StateWrapper(state); + final CompoundTag rawTag = wrapper.getTag(); + if (rawTag != null) { + final Map values = new HashMap(); + for (final Entry entry : rawTag.getValue().entrySet()) { + values.put(entry.getKey(), entry.getValue()); + } + values.put("id", new StringTag("id", wrapper.getId())); + values.put("x", new IntTag("x", x)); + values.put("y", new IntTag("y", y)); + values.put("z", new IntTag("z", z)); + final CompoundTag tileEntityTag = new CompoundTag(values); + tileEntities.add(tileEntityTag); + } + } + } + default: { + blockData[index] = block.getData(); + } + } + // For optimization reasons, we are not supporting custom data types + // Especially since the most likely reason beyond this range is modded servers in which the blocks have NBT + // if (id > 255) { + // if (addBlocks == null) { + // addBlocks = new byte[(blocks.length >> 1) + 1]; + // } + // addBlocks[index >> 1] = (byte) (((index & 1) == 0) ? (addBlocks[index >> 1] & 0xF0) | ((id >> 8) & 0xF) : (addBlocks[index >> 1] & 0xF) | (((id >> 8) & 0xF) << 4)); + // } + blocks[index] = (byte) id; + } + } + } + } + if (chunks.size() != 0) { + TaskManager.runTaskLater(this, 1); + } else { + regionTask.run(); + } + } + }); } }); } diff --git a/src/main/java/com/plotsquared/bukkit/util/SetBlockFast.java b/src/main/java/com/plotsquared/bukkit/util/SetBlockFast.java index 96d1bc328..8b821b6ba 100644 --- a/src/main/java/com/plotsquared/bukkit/util/SetBlockFast.java +++ b/src/main/java/com/plotsquared/bukkit/util/SetBlockFast.java @@ -64,7 +64,6 @@ public class SetBlockFast extends BukkitSetBlockManager { @Override public void run() { - // TODO Auto-generated method stub update(toUpdate.values()); toUpdate = new HashMap<>(); } diff --git a/src/main/java/com/plotsquared/bukkit/util/SetBlockSlow.java b/src/main/java/com/plotsquared/bukkit/util/SetBlockSlow.java index 021964b5c..36d1d9899 100644 --- a/src/main/java/com/plotsquared/bukkit/util/SetBlockSlow.java +++ b/src/main/java/com/plotsquared/bukkit/util/SetBlockSlow.java @@ -29,6 +29,6 @@ public class SetBlockSlow extends BukkitSetBlockManager { @Override public void update(final Collection chunks) { - // TODO nothing + // nothing } } diff --git a/src/main/java/com/plotsquared/bukkit/util/WorldEditSchematic.java b/src/main/java/com/plotsquared/bukkit/util/WorldEditSchematic.java deleted file mode 100644 index 079ab9c98..000000000 --- a/src/main/java/com/plotsquared/bukkit/util/WorldEditSchematic.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.plotsquared.bukkit.util; - -import java.io.File; - -import org.bukkit.Bukkit; - -import com.intellectualcrafters.plot.object.Location; -import com.intellectualcrafters.plot.object.PlotId; -import com.intellectualcrafters.plot.util.MainUtil; -import com.plotsquared.bukkit.BukkitMain; -import com.sk89q.worldedit.CuboidClipboard; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.bukkit.BukkitWorld; - -public class WorldEditSchematic { - public void saveSchematic(final String file, final String world, final PlotId id) { - final Location bot = MainUtil.getPlotBottomLoc(world, id).add(1, 0, 1); - final Location top = MainUtil.getPlotTopLoc(world, id); - final Vector size = new Vector((top.getX() - bot.getX()) + 1, top.getY() - bot.getY() - 1, (top.getZ() - bot.getZ()) + 1); - final Vector origin = new Vector(bot.getX(), bot.getY(), bot.getZ()); - final CuboidClipboard clipboard = new CuboidClipboard(size, origin); - new Vector(bot.getX(), bot.getY(), bot.getZ()); - new Vector(top.getX(), top.getY(), top.getZ()); - final EditSession session = BukkitMain.worldEdit.getWorldEdit().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorld(world)), 999999999); - clipboard.copy(session); - try { - clipboard.saveSchematic(new File(file)); - MainUtil.sendMessage(null, "&7 - &a success: " + id); - } catch (final Exception e) { - e.printStackTrace(); - MainUtil.sendMessage(null, "&7 - Failed to save &c" + id); - } - } -} diff --git a/src/main/java/com/plotsquared/listener/PlotListener.java b/src/main/java/com/plotsquared/listener/PlotListener.java index 38c67ddab..be8ac7bde 100644 --- a/src/main/java/com/plotsquared/listener/PlotListener.java +++ b/src/main/java/com/plotsquared/listener/PlotListener.java @@ -60,7 +60,7 @@ public class PlotListener { if ((last != null) && !last.id.equals(plot.id)) { plotExit(pp, last); } - pp.setMeta("lastplot", plot); + pp.setMeta("lastplot", MainUtil.getPlot(plot)); EventUtil.manager.callEntry(pp, plot); if (plot.hasOwner()) { final HashMap flags = FlagManager.getPlotFlags(plot); diff --git a/src/main/java/com/plotsquared/listener/WEManager.java b/src/main/java/com/plotsquared/listener/WEManager.java index 9e95ff9f1..c7d766a33 100644 --- a/src/main/java/com/plotsquared/listener/WEManager.java +++ b/src/main/java/com/plotsquared/listener/WEManager.java @@ -47,9 +47,7 @@ public class WEManager { continue; } if (Settings.WE_ALLOW_HELPER ? plot.isAdded(uuid) : (plot.isOwner(uuid) || plot.getTrusted().contains(uuid))) { - final Location pos1 = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); - final Location pos2 = MainUtil.getPlotTopLoc(plot.world, plot.id); - regions.add(new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getY(), pos2.getY(), pos1.getZ(), pos2.getZ())); + regions.addAll(MainUtil.getRegions(plot)); } } return regions; diff --git a/src/main/java/com/plotsquared/sponge/generator/AugmentedPopulator.java b/src/main/java/com/plotsquared/sponge/generator/AugmentedPopulator.java index c63061145..9104189f3 100644 --- a/src/main/java/com/plotsquared/sponge/generator/AugmentedPopulator.java +++ b/src/main/java/com/plotsquared/sponge/generator/AugmentedPopulator.java @@ -61,7 +61,7 @@ public class AugmentedPopulator implements Populator { this.b = b; o = (plotworld.TERRAIN == 1) || (plotworld.TERRAIN == 2); if (cluster != null) { - final Location bl = manager.getPlotBottomLocAbs(plotworld, cluster.getP1()); + final Location bl = manager.getPlotBottomLocAbs(plotworld, cluster.getP1()).subtract(1, 0, 1); final Location tl = manager.getPlotTopLocAbs(plotworld, cluster.getP2()).add(1, 0, 1); bx = bl.getX(); bz = bl.getZ(); diff --git a/src/main/java/com/plotsquared/sponge/generator/SpongeBasicGen.java b/src/main/java/com/plotsquared/sponge/generator/SpongeBasicGen.java index f0e0ec9b0..7c27f9f35 100644 --- a/src/main/java/com/plotsquared/sponge/generator/SpongeBasicGen.java +++ b/src/main/java/com/plotsquared/sponge/generator/SpongeBasicGen.java @@ -27,9 +27,6 @@ public class SpongeBasicGen extends SpongePlotGenerator { /** * Some generator specific variables (implementation dependent) - * - * TODO USE THESE - * */ public int plotsize; public int pathsize; diff --git a/src/main/java/com/plotsquared/sponge/listener/MainListener.java b/src/main/java/com/plotsquared/sponge/listener/MainListener.java index 2b6e27535..d4ac8d024 100644 --- a/src/main/java/com/plotsquared/sponge/listener/MainListener.java +++ b/src/main/java/com/plotsquared/sponge/listener/MainListener.java @@ -93,6 +93,7 @@ public class MainListener { * - HangingBreakEvent * - Liquid flow * - PVP + * - block dispense * - PVE * - VehicleDestroy * - Projectile @@ -164,7 +165,7 @@ public class MainListener { return; } if (mobs == null) { - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); } if (mobs[3] >= cap) { event.setCancelled(true); @@ -180,7 +181,7 @@ public class MainListener { return; } if (mobs == null) { - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); } if (mobs[1] >= cap) { event.setCancelled(true); @@ -197,7 +198,7 @@ public class MainListener { return; } if (mobs == null) { - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); } if (mobs[2] >= cap) { event.setCancelled(true); @@ -216,7 +217,7 @@ public class MainListener { return; } if (mobs == null) { - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); } if (mobs[4] >= cap) { event.setCancelled(true); @@ -232,7 +233,7 @@ public class MainListener { return; } if (mobs == null) { - mobs = ChunkManager.manager.countEntities(plot); + mobs = MainUtil.countEntities(plot); } if (mobs[0] >= cap) { event.setCancelled(true); @@ -266,7 +267,6 @@ public class MainListener { event.setCancelled(true); } } - // TODO } @Subscribe @@ -519,7 +519,7 @@ public class MainListener { } MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_DESTROY_OTHER); event.setCancelled(true); - } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getSettings().flags.containsKey("done")) { + } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getFlags().containsKey("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); @@ -570,7 +570,7 @@ public class MainListener { } MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_DESTROY_OTHER); event.setCancelled(true); - } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getSettings().flags.containsKey("done")) { + } else if (Settings.DONE_RESTRICTS_BUILDING && plot.getFlags().containsKey("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); @@ -658,9 +658,6 @@ public class MainListener { final UUID uuid = pp.getUUID(); UUIDHandler.add(name, uuid); ExpireManager.dates.put(uuid, System.currentTimeMillis()); - - // TODO worldedit bypass - if ((PS.get().update != null) && pp.hasPermission("plots.admin")) { TaskManager.runTaskLater(new Runnable() { @Override @@ -740,7 +737,7 @@ public class MainListener { final Plot plot = MainUtil.getPlot(worldname, id); if (!PlotListener.plotEntry(pp, plot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED); - if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { + if (!plot.getBasePlot(false).equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { event.setNewLocation(from); } else { event.setNewLocation(world.getSpawnLocation()); @@ -964,9 +961,6 @@ public class MainListener { player.deleteMeta("location"); player.deleteMeta("lastplot"); - - // TODO worldedit mask - if (Settings.PERMISSION_CACHING) { ((SpongePlayer) player).hasPerm = new HashSet<>(); ((SpongePlayer) player).noPerm = new HashSet<>(); diff --git a/src/main/java/com/plotsquared/sponge/util/SpongeChunkManager.java b/src/main/java/com/plotsquared/sponge/util/SpongeChunkManager.java index d6f0e75c4..54a2059a7 100644 --- a/src/main/java/com/plotsquared/sponge/util/SpongeChunkManager.java +++ b/src/main/java/com/plotsquared/sponge/util/SpongeChunkManager.java @@ -1,7 +1,9 @@ package com.plotsquared.sponge.util; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.spongepowered.api.entity.Entity; import org.spongepowered.api.entity.living.Living; @@ -32,8 +34,8 @@ public class SpongeChunkManager extends ChunkManager { @Override public int[] countEntities(final Plot plot) { - final Location pos1 = plot.getBottom(); - final Location pos2 = plot.getTop(); + final Location pos1 = plot.getBottomAbs(); + final Location pos2 = plot.getTopAbs(); final String worldname = pos1.getWorld(); final World world = SpongeUtil.getWorld(worldname); @@ -87,8 +89,8 @@ public class SpongeChunkManager extends ChunkManager { } @Override - public List getChunkChunks(final String world) { - final ArrayList chunks = new ArrayList(); + public Set getChunkChunks(final String world) { + final HashSet chunks = new HashSet(); final World worldObj = SpongeUtil.getWorld(world); final ChunkDataStream storage = worldObj.getWorldStorage().getGeneratedChunks(); while (storage.hasNext()) { diff --git a/target/PlotSquared-Bukkit.jar b/target/PlotSquared-Bukkit.jar index 86ec9bbf8..c5a1944d3 100644 Binary files a/target/PlotSquared-Bukkit.jar and b/target/PlotSquared-Bukkit.jar differ