From edd18a7178bc5129f2098b9c8a5b225680b0c17f Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Thu, 31 Mar 2016 20:48:46 +1100 Subject: [PATCH] Various - Fix some block change issues (for some reason sending a chunk would sometimes reset any recent changes) - Send chunk changes for relight command - Have kick cmd kick the player from the server if they are kicked from the spawn plot - Plot size checks for downloading - Fix some potential integer overflow issues for large plots (>64K x 64K) - Fix some edge cases for plot move/copy --- .../plot/api/PlotAPI.java | 3 +- .../bukkit/util/BukkitChunkManager.java | 7 +- .../plotsquared/bukkit/util/BukkitUtil.java | 10 +- .../bukkit/util/block/FastQueue_1_8_3.java | 28 ++--- .../bukkit/util/block/FastQueue_1_9.java | 104 +++++------------- .../bukkit/util/block/SlowQueue.java | 7 +- .../plot/commands/Area.java | 2 + .../plot/commands/Download.java | 8 ++ .../plot/commands/Kick.java | 14 ++- .../plot/commands/Relight.java | 1 + .../intellectualcrafters/plot/config/C.java | 5 + .../plot/flag/FlagValue.java | 1 - .../plot/object/Plot.java | 79 ++++++++----- .../plot/util/WorldUtil.java | 5 +- .../plotsquared/sponge/util/SpongeUtil.java | 8 +- 15 files changed, 151 insertions(+), 131 deletions(-) diff --git a/Bukkit/src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java b/Bukkit/src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java index 62cd84868..ca456b97b 100644 --- a/Bukkit/src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java +++ b/Bukkit/src/main/java/com/intellectualcrafters/plot/api/PlotAPI.java @@ -33,7 +33,6 @@ import java.util.UUID; /** * PlotSquared API. *
- * @version API 3.3.2 *
* Useful classes:
* @see BukkitUtil @@ -42,7 +41,7 @@ import java.util.UUID; * @see com.intellectualcrafters.plot.object.Location * @see PlotArea * @see PS - * @version 3.3.1 + * @version 3.3.3 >>>>>>> origin/master */ public class PlotAPI { diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java index f09f0fb6a..aecbaa448 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java @@ -513,10 +513,11 @@ public class BukkitChunkManager extends ChunkManager { for (short y = 0; y <= maxY; y++) { Block block = world.getBlockAt(x, y, z); Material id = block.getType(); + if (storeNormal) { + int typeId = id.getId(); + ids[y] = new PlotBlock((short) typeId, typeId == 0 ? 0 : block.getData()); + } if (!id.equals(Material.AIR)) { - if (storeNormal) { - ids[y] = new PlotBlock((short) id.getId(), block.getData()); - } try { BlockLoc bl = new BlockLoc(x + offsetX, y, z + offsetZ); if (block.getState() instanceof InventoryHolder) { diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java index 26f5b008e..59a500efd 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitUtil.java @@ -12,6 +12,8 @@ import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.UUIDHandler; import com.intellectualcrafters.plot.util.WorldUtil; import com.plotsquared.bukkit.object.BukkitPlayer; +import java.util.Arrays; +import java.util.List; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -32,9 +34,6 @@ import org.bukkit.material.Tree; import org.bukkit.material.WoodenStep; import org.bukkit.material.Wool; -import java.util.Arrays; -import java.util.List; - public class BukkitUtil extends WorldUtil { private static String lastString = null; @@ -157,6 +156,11 @@ public class BukkitUtil extends WorldUtil { return null; } + @Override + public Location getSpawn(PlotPlayer pp) { + return getLocation(((BukkitPlayer) pp).player.getBedSpawnLocation()); + } + @Override public Location getSpawn(String world) { org.bukkit.Location temp = getWorld(world).getSpawnLocation(); diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/FastQueue_1_8_3.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/FastQueue_1_8_3.java index 16a50885d..4fe6218af 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/FastQueue_1_8_3.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/FastQueue_1_8_3.java @@ -1,7 +1,5 @@ package com.plotsquared.bukkit.util.block; -import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass; - import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.PseudoRandom; import com.intellectualcrafters.plot.util.ChunkManager; @@ -16,12 +14,6 @@ import com.intellectualcrafters.plot.util.SetQueue; import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper; import com.intellectualcrafters.plot.util.TaskManager; import com.plotsquared.bukkit.util.SendChunk; -import org.bukkit.Chunk; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.World.Environment; -import org.bukkit.block.Biome; - import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -31,6 +23,14 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; import java.util.Set; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.block.Biome; + + +import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass; public class FastQueue_1_8_3 extends SlowQueue { @@ -46,7 +46,7 @@ public class FastQueue_1_8_3 extends SlowQueue { private final RefField fieldWorld; private final RefMethod methodGetIdArray; private final RefMethod methodGetWorld; - private final RefField tileEntityUnload; + private final RefField tileEntityListTick; public FastQueue_1_8_3() throws RuntimeException { RefClass classCraftChunk = getRefClass("{cb}.CraftChunk"); @@ -63,7 +63,7 @@ public class FastQueue_1_8_3 extends SlowQueue { this.methodGetIdArray = classChunkSection.getMethod("getIdArray"); this.methodAreNeighborsLoaded = classChunk.getMethod("areNeighborsLoaded", int.class); this.classChunkSectionConstructor = classChunkSection.getConstructor(int.class, boolean.class, char[].class); - this.tileEntityUnload = classWorld.getField("c"); + this.tileEntityListTick = classWorld.getField("tileEntityList"); this.methodGetWorld = classChunk.getMethod("getWorld"); this.sendChunk = new SendChunk(); TaskManager.runTaskRepeat(new Runnable() { @@ -135,10 +135,8 @@ public class FastQueue_1_8_3 extends SlowQueue { sections1.setAccessible(true); Field tileEntities = clazz.getDeclaredField("tileEntities"); Field entitySlices = clazz.getDeclaredField("entitySlices"); - Object[] sections = (Object[]) sections1.get(c); HashMap tiles = (HashMap) tileEntities.get(c); - Collection tilesUnload = (Collection) this.tileEntityUnload.of(w).get(); Collection[] entities = (Collection[]) entitySlices.get(c); Method getX = null; @@ -146,6 +144,7 @@ public class FastQueue_1_8_3 extends SlowQueue { Method getZ = null; // Trim tiles + boolean removed = false; Set> entrySet = (Set>) (Set) tiles.entrySet(); Iterator> iterator = entrySet.iterator(); while (iterator.hasNext()) { @@ -167,10 +166,13 @@ public class FastQueue_1_8_3 extends SlowQueue { continue; } if (array[k] != 0) { - tilesUnload.add(tile.getValue()); + removed = true; iterator.remove(); } } + if (removed) { + ((Collection) this.tileEntityListTick.of(w).get()).clear(); + } // Trim entities for (int i = 0; i < 16; i++) { diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/FastQueue_1_9.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/FastQueue_1_9.java index 54f19dbf3..04b3eaa91 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/FastQueue_1_9.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/FastQueue_1_9.java @@ -1,7 +1,5 @@ package com.plotsquared.bukkit.util.block; -import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass; - import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.PseudoRandom; import com.intellectualcrafters.plot.util.ChunkManager; @@ -12,32 +10,31 @@ import com.intellectualcrafters.plot.util.ReflectionUtils.RefConstructor; import com.intellectualcrafters.plot.util.ReflectionUtils.RefField; import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod; import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod.RefExecutor; -import com.intellectualcrafters.plot.util.SetQueue; import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper; import com.intellectualcrafters.plot.util.TaskManager; import com.plotsquared.bukkit.util.BukkitUtil; -import com.plotsquared.bukkit.util.SendChunk; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.World.Environment; import org.bukkit.block.Biome; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map.Entry; -import java.util.Set; + +import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass; public class FastQueue_1_9 extends SlowQueue { private final Object air; - private final SendChunk chunkSender; - private final HashMap toUpdate = new HashMap<>(); +// private final HashMap toUpdate = new HashMap<>(); private final RefMethod methodGetHandleChunk; private final RefMethod methodInitLighting; private final RefConstructor classBlockPositionConstructor; @@ -52,7 +49,8 @@ public class FastQueue_1_9 extends SlowQueue { private final RefMethod methodGetCombinedId; private final RefMethod methodGetByCombinedId; private final RefMethod methodGetWorld; - private final RefField tileEntityUnload; + + private final RefField tileEntityListTick; public FastQueue_1_9() throws RuntimeException { @@ -63,7 +61,7 @@ public class FastQueue_1_9 extends SlowQueue { RefClass classBlockPosition = getRefClass("{nms}.BlockPosition"); this.classBlockPositionConstructor = classBlockPosition.getConstructor(int.class, int.class, int.class); RefClass classWorld = getRefClass("{nms}.World"); - this.tileEntityUnload = classWorld.getField("tileEntityListUnload"); + this.tileEntityListTick = classWorld.getField("tileEntityListTick"); this.methodGetWorld = classChunk.getMethod("getWorld"); this.methodW = classWorld.getMethod("w", classBlockPosition.getRealClass()); this.fieldSections = classChunk.getField("sections"); @@ -79,63 +77,19 @@ public class FastQueue_1_9 extends SlowQueue { this.methodAreNeighborsLoaded = classChunk.getMethod("areNeighborsLoaded", int.class); this.classChunkSectionConstructor = classChunkSection.getConstructor(int.class, boolean.class, char[].class); this.air = this.methodGetByCombinedId.call(0); - this.chunkSender = new SendChunk(); - TaskManager.runTaskRepeat(new Runnable() { - @Override - public void run() { - if (FastQueue_1_9.this.toUpdate.isEmpty()) { - return; - } - int count = 0; - ArrayList chunks = new ArrayList<>(); - Iterator> i = FastQueue_1_9.this.toUpdate.entrySet().iterator(); - while (i.hasNext() && count < 128) { - chunks.add(i.next().getValue()); - i.remove(); - count++; - } - if (count == 0) { - return; - } - update(chunks); - } - }, 1); MainUtil.initCache(); } - public void update(Collection chunks) { - if (chunks.isEmpty()) { - return; - } - if (!MainUtil.canSendChunk) { - for (Chunk chunk : chunks) { - chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ()); - chunk.unload(true, true); - chunk.load(); - } - return; - } - try { - this.chunkSender.sendChunk(chunks); - } catch (Throwable e) { - e.printStackTrace(); - MainUtil.canSendChunk = false; - } - } - /** * This should be overridden by any specialized queues * @param plotChunk */ @Override - public void execute(PlotChunk plotChunk) { - FastChunk_1_9 fs = (FastChunk_1_9) plotChunk; + public void execute(final PlotChunk plotChunk) { + final FastChunk_1_9 fs = (FastChunk_1_9) plotChunk; Chunk chunk = plotChunk.getChunk(); World world = chunk.getWorld(); ChunkWrapper wrapper = plotChunk.getChunkWrapper(); - if (!this.toUpdate.containsKey(wrapper)) { - this.toUpdate.put(wrapper, chunk); - } chunk.load(true); try { boolean flag = world.getEnvironment() == Environment.NORMAL; @@ -149,16 +103,15 @@ public class FastQueue_1_9 extends SlowQueue { sf.setAccessible(true); Field tf = clazz.getDeclaredField("tileEntities"); Field entitySlices = clazz.getDeclaredField("entitySlices"); - Object[] sections = (Object[]) sf.get(c); HashMap tiles = (HashMap) tf.get(c); - Collection tilesUnload = (Collection) this.tileEntityUnload.of(w).get(); Collection[] entities = (Collection[]) entitySlices.get(c); Method xm = null; Method ym = null; Method zm = null; // Trim tiles + boolean removed = false; Set> entrySet = (Set>) (Set) tiles.entrySet(); Iterator> iterator = entrySet.iterator(); while (iterator.hasNext()) { @@ -180,10 +133,13 @@ public class FastQueue_1_9 extends SlowQueue { continue; } if (array[k] != 0) { - tilesUnload.add(tile.getValue()); + removed = true; iterator.remove(); } } + if (removed) { + ((Collection) this.tileEntityListTick.of(w).get()).clear(); + } // Trim entities for (int i = 0; i < 16; i++) { @@ -264,6 +220,12 @@ public class FastQueue_1_9 extends SlowQueue { } } } + TaskManager.runTaskLater(new Runnable() { + @Override + public void run() { + sendChunk(fs.getChunkWrapper().world, Arrays.asList(new ChunkLoc(fs.getX(), fs.getZ()))); + } + }, 1); } public Object newChunkSection(int i, boolean flag, char[] ids) { @@ -442,7 +404,6 @@ public class FastQueue_1_9 extends SlowQueue { if (section == null) { return 0; } - // Object array = getBlocks(section); return getId(section, x, y, z); } @@ -455,14 +416,7 @@ public class FastQueue_1_9 extends SlowQueue { public void sendChunk(final String world, final Collection locations) { World worldObj = BukkitUtil.getWorld(world); for (ChunkLoc loc : locations) { - ChunkWrapper wrapper = SetQueue.IMP.new ChunkWrapper(world, loc.x, loc.z); - this.toUpdate.remove(wrapper); + worldObj.refreshChunk(loc.x, loc.z); } - TaskManager.runTaskLater(new Runnable() { - @Override - public void run() { - FastQueue_1_9.this.chunkSender.sendChunk(world, locations); - } - }, 1); } } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/SlowQueue.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/SlowQueue.java index ea1bcb052..60405a756 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/SlowQueue.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/block/SlowQueue.java @@ -8,14 +8,13 @@ import com.intellectualcrafters.plot.util.PlotChunk; import com.intellectualcrafters.plot.util.PlotQueue; import com.intellectualcrafters.plot.util.SetQueue; import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper; -import org.bukkit.Chunk; -import org.bukkit.block.Biome; -import org.bukkit.block.Block; - import java.util.Collection; import java.util.Iterator; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; +import org.bukkit.Chunk; +import org.bukkit.block.Biome; +import org.bukkit.block.Block; public class SlowQueue implements PlotQueue { diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/Area.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/Area.java index 6d7ae5cb6..2e5838fbd 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/Area.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/Area.java @@ -394,6 +394,8 @@ public class Area extends SubCommand { }, "/plot area list", C.AREA_LIST_HEADER_PAGED.s()); return true; case "regen": + case "clear": + case "reset": case "regenerate": { if (!Permissions.hasPermission(plr, "plots.area.regen")) { C.NO_PERMISSION.send(plr, "plots.area.regen"); diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/Download.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/Download.java index 7a42a944c..441ea13fe 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/Download.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/Download.java @@ -51,6 +51,10 @@ public class Download extends SubCommand { return false; } if (args.length == 0 || (args.length == 1 && StringMan.isEqualIgnoreCaseToAny(args[0], "sch", "schem", "schematic"))) { + if (plot.getVolume() > 512d * 512d * 256d) { + C.SCHEMATIC_TOO_LARGE.send(plr); + return false; + } plot.addRunning(); SchematicHandler.manager.getCompoundTag(plot, new RunnableVal() { @Override @@ -72,6 +76,10 @@ public class Download extends SubCommand { if (!Permissions.hasPermission(plr, "plots.download.bo3")) { C.NO_PERMISSION.send(plr, "plots.download.bo3"); } + if (plot.getVolume() > 128d * 128d * 256) { + C.SCHEMATIC_TOO_LARGE.send(plr); + return false; + } plot.addRunning(); BO3Handler.upload(plot, null, null, new RunnableVal() { @Override diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/Kick.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/Kick.java index 2c130b061..16a817f5f 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/Kick.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/Kick.java @@ -49,7 +49,19 @@ public class Kick extends SubCommand { C.CANNOT_KICK_PLAYER.send(plr, player.getName()); return false; } - player.teleport(WorldUtil.IMP.getSpawn(loc.getWorld())); + Location spawn = WorldUtil.IMP.getSpawn(loc.getWorld()); + C.YOU_GOT_KICKED.send(player); + if (plot.equals(spawn.getPlot())) { + Location newSpawn = WorldUtil.IMP.getSpawn(player); + if (plot.equals(newSpawn.getPlot())) { + // Kick from server if you can't be teleported to spawn + player.kick(C.YOU_GOT_KICKED.s()); + } else { + player.teleport(newSpawn); + } + } else { + player.teleport(spawn); + } return true; } } diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/Relight.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/Relight.java index d2b3fd3e9..21bcfb646 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/Relight.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/Relight.java @@ -38,6 +38,7 @@ public class Relight extends Command { }, new Runnable() { @Override public void run() { + plot.refreshChunks(); C.SET_BLOCK_ACTION_FINISHED.send(player); } }, 5); diff --git a/Core/src/main/java/com/intellectualcrafters/plot/config/C.java b/Core/src/main/java/com/intellectualcrafters/plot/config/C.java index 8a2ac56c8..eaaa4012d 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/config/C.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/config/C.java @@ -271,6 +271,7 @@ public enum C { /* * Schematic Stuff */ + SCHEMATIC_TOO_LARGE("$2The plot is too large for this action!", "Schematics"), SCHEMATIC_MISSING_ARG("$2You need to specify an argument. Possible values: $1test $2 , $1save$2 , $1paste $2, $1exportall", "Schematics"), SCHEMATIC_INVALID("$2That is not a valid schematic. Reason: $2%s", "Schematics"), SCHEMATIC_VALID("$2That is a valid schematic", "Schematics"), @@ -535,6 +536,10 @@ public enum C { DENIED_NEED_ARGUMENT("$2Arguments are missing. $1/plot denied add $2or $1/plot denied remove ", "Deny"), WAS_NOT_DENIED("$2That player was not denied on this plot", "Deny"), YOU_GOT_DENIED("$4You are denied from the plot you were previously on, and got teleported to spawn", "Deny"), + /* + * Kick + */ + YOU_GOT_KICKED("$4You got kicked!", "Kick"), /* * Rain */ diff --git a/Core/src/main/java/com/intellectualcrafters/plot/flag/FlagValue.java b/Core/src/main/java/com/intellectualcrafters/plot/flag/FlagValue.java index 6f9f29ec2..23193b8ef 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/flag/FlagValue.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/flag/FlagValue.java @@ -438,7 +438,6 @@ public abstract class FlagValue { @Override public List parse(final String t) { - System.out.println("PARSE: " + t); return new ArrayList<>(Arrays.asList(t.split(","))); } diff --git a/Core/src/main/java/com/intellectualcrafters/plot/object/Plot.java b/Core/src/main/java/com/intellectualcrafters/plot/object/Plot.java index e3948abed..950090c66 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/object/Plot.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/object/Plot.java @@ -20,7 +20,6 @@ import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.UUIDHandler; import com.intellectualcrafters.plot.util.WorldUtil; import com.plotsquared.listener.PlotListener; - import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.geom.PathIterator; @@ -777,23 +776,14 @@ public class Plot { TaskManager.runTask(whenDone); } }; - if (isDelete) { - for (Plot current : plots) { - manager.unclaimPlot(Plot.this.area, current, new Runnable() { - @Override - public void run() { - if (finished.incrementAndGet() >= plots.size()) { - run.run(); - } - } - }); - } - } else { - for (Plot current : plots) { + for (Plot current : plots) { + if (isDelete || current.owner == null) { + manager.unclaimPlot(Plot.this.area, current, null); + } else { manager.claimPlot(Plot.this.area, current); } - SetQueue.IMP.addTask(run); } + SetQueue.IMP.addTask(run); return; } Plot current = queue.poll(); @@ -804,7 +794,16 @@ public class Plot { manager.clearPlot(Plot.this.area, current, this); } }; - run.run(); + if (!isMerged() && area.getRegion().equals(getLargestRegion())) { + ChunkManager.largeRegionTask(area.worldname, area.getRegion(), new RunnableVal() { + @Override + public void run(ChunkLoc value) { + ChunkManager.manager.regenerateChunk(area.worldname, value); + } + }, whenDone); + } else { + run.run(); + } return true; } @@ -1137,8 +1136,8 @@ public class Plot { if (this.area.DEFAULT_HOME.x == Integer.MAX_VALUE && this.area.DEFAULT_HOME.z == Integer.MAX_VALUE) { // center RegionWrapper largest = plot.getLargestRegion(); - x = (largest.maxX - largest.minX) / 2 + largest.minX; - z = (largest.maxZ - largest.minZ) / 2 + largest.minZ; + x = (largest.maxX >> 1) - (largest.minX >> 1) + largest.minX; + z = (largest.maxZ >> 1) - (largest.minZ >> 1) + largest.minZ; } else { // specific Location bot = plot.getBottomAbs(); @@ -1150,13 +1149,21 @@ public class Plot { } // Side RegionWrapper largest = plot.getLargestRegion(); - int x = (largest.maxX - largest.minX) / 2 + largest.minX; + int x = (largest.maxX >> 1) - (largest.minX >> 1) + largest.minX; int z = largest.minZ - 1; PlotManager manager = plot.getManager(); int y = Math.max(WorldUtil.IMP.getHighestBlock(plot.area.worldname, x, z), manager.getSignLoc(plot.area, plot).getY()); return new Location(plot.area.worldname, x, y + 1, z); } + public double getVolume() { + double count = 0; + for (RegionWrapper region : getRegions()) { + count += (region.maxX - (double) region.minX + 1) * (region.maxZ - (double) region.minZ + 1) * 256; + } + return count; + } + /** * Get the average rating of the plot. This is the value displayed in /plot info * @return average rating as double @@ -2201,6 +2208,10 @@ public class Plot { return this.area.getPlotAbs(this.id.getRelative(x, y)); } + public Plot getRelative(PlotArea area, int x, int y) { + return area.getPlotAbs(this.id.getRelative(x, y)); + } + /** * Get the plot in a relative direction
* 0 = north
@@ -2470,9 +2481,9 @@ public class Plot { public RegionWrapper getLargestRegion() { HashSet regions = this.getRegions(); RegionWrapper max = null; - int area = 0; + double area = Double.NEGATIVE_INFINITY; for (RegionWrapper region : regions) { - int current = (region.maxX - region.minX + 1) * (region.maxZ - region.minZ + 1); + double current = ((region.maxX - (double) region.minX + 1)) * (region.maxZ - (double) region.minZ + 1); if (current > area) { max = region; area = current; @@ -2680,7 +2691,7 @@ public class Plot { * @return */ public boolean move(final Plot destination, final Runnable whenDone, boolean allowSwap) { - PlotId offset = new PlotId(destination.getId().x - this.getId().x, destination.getId().y - this.getId().y); + final PlotId offset = new PlotId(destination.getId().x - this.getId().x, destination.getId().y - this.getId().y); Location db = destination.getBottomAbs(); Location ob = this.getBottomAbs(); final int offsetX = db.getX() - ob.getX(); @@ -2692,21 +2703,24 @@ public class Plot { boolean occupied = false; HashSet plots = this.getConnectedPlots(); for (Plot plot : plots) { - Plot other = plot.getRelative(offset.x, offset.y); + Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); if (other.hasOwner()) { if (!allowSwap) { TaskManager.runTaskLater(whenDone, 1); return false; } occupied = true; + } else { + plot.removeSign(); } } // world border destination.updateWorldBorder(); final ArrayDeque regions = new ArrayDeque<>(this.getRegions()); // move / swap data + final PlotArea originArea = getArea(); for (Plot plot : plots) { - Plot other = plot.getRelative(offset.x, offset.y); + Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); plot.swapData(other, null); } // copy terrain @@ -2714,6 +2728,13 @@ public class Plot { @Override public void run() { if (regions.isEmpty()) { + Plot plot = destination.getRelative(0, 0); + for (Plot current : plot.getConnectedPlots()) { + getManager().claimPlot(current.getArea(), current); + Plot originPlot = originArea.getPlotAbs(new PlotId(current.id.x - offset.x, current.id.y - offset.y)); + originPlot.getManager().unclaimPlot(originArea, originPlot, null); + } + plot.setSign(); TaskManager.runTask(whenDone); return; } @@ -2728,7 +2749,7 @@ public class Plot { @Override public void run() { ChunkManager.manager.regenerateRegion(pos1, pos2, false, task); - } + } }); } }; @@ -2776,7 +2797,7 @@ public class Plot { } HashSet plots = this.getConnectedPlots(); for (Plot plot : plots) { - Plot other = plot.getRelative(offset.x, offset.y); + Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); if (other.hasOwner()) { TaskManager.runTaskLater(whenDone, 1); return false; @@ -2786,7 +2807,7 @@ public class Plot { destination.updateWorldBorder(); // copy data for (Plot plot : plots) { - Plot other = plot.getRelative(offset.x, offset.y); + Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); other.create(plot.owner, false); if (!plot.getFlags().isEmpty()) { other.getSettings().flags = plot.getFlags(); @@ -2820,6 +2841,10 @@ public class Plot { @Override public void run() { if (regions.isEmpty()) { + for (Plot current : getConnectedPlots()) { + destination.getManager().claimPlot(destination.getArea(), destination); + } + destination.setSign(); TaskManager.runTask(whenDone); return; } diff --git a/Core/src/main/java/com/intellectualcrafters/plot/util/WorldUtil.java b/Core/src/main/java/com/intellectualcrafters/plot/util/WorldUtil.java index 1555b5f3b..04f57e68c 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/util/WorldUtil.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/util/WorldUtil.java @@ -4,6 +4,7 @@ import com.intellectualcrafters.plot.PS; 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.object.RegionWrapper; import com.intellectualcrafters.plot.object.RunnableVal; import com.intellectualcrafters.plot.object.schematic.PlotItem; @@ -29,9 +30,11 @@ public abstract class WorldUtil { public abstract boolean isWorld(String worldName); public abstract String[] getSign(Location location); - + public abstract Location getSpawn(String world); + public abstract Location getSpawn(PlotPlayer pp); + public abstract void setSpawn(Location location); public abstract void saveWorld(String world); diff --git a/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeUtil.java b/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeUtil.java index d8b537906..3f8b61a20 100644 --- a/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeUtil.java +++ b/Sponge/src/main/java/com/plotsquared/sponge/util/SpongeUtil.java @@ -345,7 +345,13 @@ public class SpongeUtil extends WorldUtil { BlockState state = SpongeUtil.getWorld(location.getWorld()).getBlock(location.getX(), location.getY(), location.getZ()); return SpongeUtil.getPlotBlock(state); } - + + @Override + public Location getSpawn(PlotPlayer pp) { + throw new NotImplementedException("TODO IMPLEMENT THIS"); // TODO FIXME + // Probably can call a respawn event and get the location from there + } + @Override public Location getSpawn(String world) { Location result = SpongeUtil.getLocation(world, SpongeUtil.getWorld(world).getSpawnLocation());