- 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
This commit is contained in:
Jesse Boyd 2016-03-31 20:48:46 +11:00
parent dbdd9f9e5a
commit edd18a7178
15 changed files with 151 additions and 131 deletions

View File

@ -33,7 +33,6 @@ import java.util.UUID;
/** /**
* PlotSquared API. * PlotSquared API.
* <br> * <br>
* @version API 3.3.2
* <br> * <br>
* Useful classes:<br> * Useful classes:<br>
* @see BukkitUtil * @see BukkitUtil
@ -42,7 +41,7 @@ import java.util.UUID;
* @see com.intellectualcrafters.plot.object.Location * @see com.intellectualcrafters.plot.object.Location
* @see PlotArea * @see PlotArea
* @see PS * @see PS
* @version 3.3.1 * @version 3.3.3
>>>>>>> origin/master >>>>>>> origin/master
*/ */
public class PlotAPI { public class PlotAPI {

View File

@ -513,10 +513,11 @@ public class BukkitChunkManager extends ChunkManager {
for (short y = 0; y <= maxY; y++) { for (short y = 0; y <= maxY; y++) {
Block block = world.getBlockAt(x, y, z); Block block = world.getBlockAt(x, y, z);
Material id = block.getType(); 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 (!id.equals(Material.AIR)) {
if (storeNormal) {
ids[y] = new PlotBlock((short) id.getId(), block.getData());
}
try { try {
BlockLoc bl = new BlockLoc(x + offsetX, y, z + offsetZ); BlockLoc bl = new BlockLoc(x + offsetX, y, z + offsetZ);
if (block.getState() instanceof InventoryHolder) { if (block.getState() instanceof InventoryHolder) {

View File

@ -12,6 +12,8 @@ import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler; import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil; import com.intellectualcrafters.plot.util.WorldUtil;
import com.plotsquared.bukkit.object.BukkitPlayer; import com.plotsquared.bukkit.object.BukkitPlayer;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -32,9 +34,6 @@ import org.bukkit.material.Tree;
import org.bukkit.material.WoodenStep; import org.bukkit.material.WoodenStep;
import org.bukkit.material.Wool; import org.bukkit.material.Wool;
import java.util.Arrays;
import java.util.List;
public class BukkitUtil extends WorldUtil { public class BukkitUtil extends WorldUtil {
private static String lastString = null; private static String lastString = null;
@ -157,6 +156,11 @@ public class BukkitUtil extends WorldUtil {
return null; return null;
} }
@Override
public Location getSpawn(PlotPlayer pp) {
return getLocation(((BukkitPlayer) pp).player.getBedSpawnLocation());
}
@Override @Override
public Location getSpawn(String world) { public Location getSpawn(String world) {
org.bukkit.Location temp = getWorld(world).getSpawnLocation(); org.bukkit.Location temp = getWorld(world).getSpawnLocation();

View File

@ -1,7 +1,5 @@
package com.plotsquared.bukkit.util.block; 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.ChunkLoc;
import com.intellectualcrafters.plot.object.PseudoRandom; import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.util.ChunkManager; 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.SetQueue.ChunkWrapper;
import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.util.SendChunk; 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.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -31,6 +23,14 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; 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 { 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 RefField fieldWorld;
private final RefMethod methodGetIdArray; private final RefMethod methodGetIdArray;
private final RefMethod methodGetWorld; private final RefMethod methodGetWorld;
private final RefField tileEntityUnload; private final RefField tileEntityListTick;
public FastQueue_1_8_3() throws RuntimeException { public FastQueue_1_8_3() throws RuntimeException {
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk"); RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
@ -63,7 +63,7 @@ public class FastQueue_1_8_3 extends SlowQueue {
this.methodGetIdArray = classChunkSection.getMethod("getIdArray"); this.methodGetIdArray = classChunkSection.getMethod("getIdArray");
this.methodAreNeighborsLoaded = classChunk.getMethod("areNeighborsLoaded", int.class); this.methodAreNeighborsLoaded = classChunk.getMethod("areNeighborsLoaded", int.class);
this.classChunkSectionConstructor = classChunkSection.getConstructor(int.class, boolean.class, char[].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.methodGetWorld = classChunk.getMethod("getWorld");
this.sendChunk = new SendChunk(); this.sendChunk = new SendChunk();
TaskManager.runTaskRepeat(new Runnable() { TaskManager.runTaskRepeat(new Runnable() {
@ -135,10 +135,8 @@ public class FastQueue_1_8_3 extends SlowQueue {
sections1.setAccessible(true); sections1.setAccessible(true);
Field tileEntities = clazz.getDeclaredField("tileEntities"); Field tileEntities = clazz.getDeclaredField("tileEntities");
Field entitySlices = clazz.getDeclaredField("entitySlices"); Field entitySlices = clazz.getDeclaredField("entitySlices");
Object[] sections = (Object[]) sections1.get(c); Object[] sections = (Object[]) sections1.get(c);
HashMap<?, ?> tiles = (HashMap<?, ?>) tileEntities.get(c); HashMap<?, ?> tiles = (HashMap<?, ?>) tileEntities.get(c);
Collection<Object> tilesUnload = (Collection<Object>) this.tileEntityUnload.of(w).get();
Collection<?>[] entities = (Collection<?>[]) entitySlices.get(c); Collection<?>[] entities = (Collection<?>[]) entitySlices.get(c);
Method getX = null; Method getX = null;
@ -146,6 +144,7 @@ public class FastQueue_1_8_3 extends SlowQueue {
Method getZ = null; Method getZ = null;
// Trim tiles // Trim tiles
boolean removed = false;
Set<Entry<?, ?>> entrySet = (Set<Entry<?, ?>>) (Set<?>) tiles.entrySet(); Set<Entry<?, ?>> entrySet = (Set<Entry<?, ?>>) (Set<?>) tiles.entrySet();
Iterator<Entry<?, ?>> iterator = entrySet.iterator(); Iterator<Entry<?, ?>> iterator = entrySet.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
@ -167,10 +166,13 @@ public class FastQueue_1_8_3 extends SlowQueue {
continue; continue;
} }
if (array[k] != 0) { if (array[k] != 0) {
tilesUnload.add(tile.getValue()); removed = true;
iterator.remove(); iterator.remove();
} }
} }
if (removed) {
((Collection) this.tileEntityListTick.of(w).get()).clear();
}
// Trim entities // Trim entities
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {

View File

@ -1,7 +1,5 @@
package com.plotsquared.bukkit.util.block; 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.ChunkLoc;
import com.intellectualcrafters.plot.object.PseudoRandom; import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.util.ChunkManager; 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.RefField;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod; import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod.RefExecutor; 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.SetQueue.ChunkWrapper;
import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.util.BukkitUtil; 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.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
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;
public class FastQueue_1_9 extends SlowQueue { public class FastQueue_1_9 extends SlowQueue {
private final Object air; private final Object air;
private final SendChunk chunkSender; // private final HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
private final HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
private final RefMethod methodGetHandleChunk; private final RefMethod methodGetHandleChunk;
private final RefMethod methodInitLighting; private final RefMethod methodInitLighting;
private final RefConstructor classBlockPositionConstructor; private final RefConstructor classBlockPositionConstructor;
@ -52,7 +49,8 @@ public class FastQueue_1_9 extends SlowQueue {
private final RefMethod methodGetCombinedId; private final RefMethod methodGetCombinedId;
private final RefMethod methodGetByCombinedId; private final RefMethod methodGetByCombinedId;
private final RefMethod methodGetWorld; private final RefMethod methodGetWorld;
private final RefField tileEntityUnload;
private final RefField tileEntityListTick;
public FastQueue_1_9() throws RuntimeException { public FastQueue_1_9() throws RuntimeException {
@ -63,7 +61,7 @@ public class FastQueue_1_9 extends SlowQueue {
RefClass classBlockPosition = getRefClass("{nms}.BlockPosition"); RefClass classBlockPosition = getRefClass("{nms}.BlockPosition");
this.classBlockPositionConstructor = classBlockPosition.getConstructor(int.class, int.class, int.class); this.classBlockPositionConstructor = classBlockPosition.getConstructor(int.class, int.class, int.class);
RefClass classWorld = getRefClass("{nms}.World"); RefClass classWorld = getRefClass("{nms}.World");
this.tileEntityUnload = classWorld.getField("tileEntityListUnload"); this.tileEntityListTick = classWorld.getField("tileEntityListTick");
this.methodGetWorld = classChunk.getMethod("getWorld"); this.methodGetWorld = classChunk.getMethod("getWorld");
this.methodW = classWorld.getMethod("w", classBlockPosition.getRealClass()); this.methodW = classWorld.getMethod("w", classBlockPosition.getRealClass());
this.fieldSections = classChunk.getField("sections"); this.fieldSections = classChunk.getField("sections");
@ -79,63 +77,19 @@ public class FastQueue_1_9 extends SlowQueue {
this.methodAreNeighborsLoaded = classChunk.getMethod("areNeighborsLoaded", int.class); this.methodAreNeighborsLoaded = classChunk.getMethod("areNeighborsLoaded", int.class);
this.classChunkSectionConstructor = classChunkSection.getConstructor(int.class, boolean.class, char[].class); this.classChunkSectionConstructor = classChunkSection.getConstructor(int.class, boolean.class, char[].class);
this.air = this.methodGetByCombinedId.call(0); 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<Chunk> chunks = new ArrayList<>();
Iterator<Entry<ChunkWrapper, Chunk>> 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(); MainUtil.initCache();
} }
public void update(Collection<Chunk> 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 * This should be overridden by any specialized queues
* @param plotChunk * @param plotChunk
*/ */
@Override @Override
public void execute(PlotChunk<Chunk> plotChunk) { public void execute(final PlotChunk<Chunk> plotChunk) {
FastChunk_1_9 fs = (FastChunk_1_9) plotChunk; final FastChunk_1_9 fs = (FastChunk_1_9) plotChunk;
Chunk chunk = plotChunk.getChunk(); Chunk chunk = plotChunk.getChunk();
World world = chunk.getWorld(); World world = chunk.getWorld();
ChunkWrapper wrapper = plotChunk.getChunkWrapper(); ChunkWrapper wrapper = plotChunk.getChunkWrapper();
if (!this.toUpdate.containsKey(wrapper)) {
this.toUpdate.put(wrapper, chunk);
}
chunk.load(true); chunk.load(true);
try { try {
boolean flag = world.getEnvironment() == Environment.NORMAL; boolean flag = world.getEnvironment() == Environment.NORMAL;
@ -149,16 +103,15 @@ public class FastQueue_1_9 extends SlowQueue {
sf.setAccessible(true); sf.setAccessible(true);
Field tf = clazz.getDeclaredField("tileEntities"); Field tf = clazz.getDeclaredField("tileEntities");
Field entitySlices = clazz.getDeclaredField("entitySlices"); Field entitySlices = clazz.getDeclaredField("entitySlices");
Object[] sections = (Object[]) sf.get(c); Object[] sections = (Object[]) sf.get(c);
HashMap<?, ?> tiles = (HashMap<?, ?>) tf.get(c); HashMap<?, ?> tiles = (HashMap<?, ?>) tf.get(c);
Collection<Object> tilesUnload = (Collection<Object>) this.tileEntityUnload.of(w).get();
Collection<?>[] entities = (Collection<?>[]) entitySlices.get(c); Collection<?>[] entities = (Collection<?>[]) entitySlices.get(c);
Method xm = null; Method xm = null;
Method ym = null; Method ym = null;
Method zm = null; Method zm = null;
// Trim tiles // Trim tiles
boolean removed = false;
Set<Entry<?, ?>> entrySet = (Set<Entry<?, ?>>) (Set<?>) tiles.entrySet(); Set<Entry<?, ?>> entrySet = (Set<Entry<?, ?>>) (Set<?>) tiles.entrySet();
Iterator<Entry<?, ?>> iterator = entrySet.iterator(); Iterator<Entry<?, ?>> iterator = entrySet.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
@ -180,10 +133,13 @@ public class FastQueue_1_9 extends SlowQueue {
continue; continue;
} }
if (array[k] != 0) { if (array[k] != 0) {
tilesUnload.add(tile.getValue()); removed = true;
iterator.remove(); iterator.remove();
} }
} }
if (removed) {
((Collection) this.tileEntityListTick.of(w).get()).clear();
}
// Trim entities // Trim entities
for (int i = 0; i < 16; i++) { 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) { public Object newChunkSection(int i, boolean flag, char[] ids) {
@ -442,7 +404,6 @@ public class FastQueue_1_9 extends SlowQueue {
if (section == null) { if (section == null) {
return 0; return 0;
} }
// Object array = getBlocks(section);
return getId(section, x, y, z); 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<ChunkLoc> locations) { public void sendChunk(final String world, final Collection<ChunkLoc> locations) {
World worldObj = BukkitUtil.getWorld(world); World worldObj = BukkitUtil.getWorld(world);
for (ChunkLoc loc : locations) { for (ChunkLoc loc : locations) {
ChunkWrapper wrapper = SetQueue.IMP.new ChunkWrapper(world, loc.x, loc.z); worldObj.refreshChunk(loc.x, loc.z);
this.toUpdate.remove(wrapper);
} }
TaskManager.runTaskLater(new Runnable() {
@Override
public void run() {
FastQueue_1_9.this.chunkSender.sendChunk(world, locations);
}
}, 1);
} }
} }

View File

@ -8,14 +8,13 @@ import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.PlotQueue; import com.intellectualcrafters.plot.util.PlotQueue;
import com.intellectualcrafters.plot.util.SetQueue; import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper; 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.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Chunk;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
public class SlowQueue implements PlotQueue<Chunk> { public class SlowQueue implements PlotQueue<Chunk> {

View File

@ -394,6 +394,8 @@ public class Area extends SubCommand {
}, "/plot area list", C.AREA_LIST_HEADER_PAGED.s()); }, "/plot area list", C.AREA_LIST_HEADER_PAGED.s());
return true; return true;
case "regen": case "regen":
case "clear":
case "reset":
case "regenerate": { case "regenerate": {
if (!Permissions.hasPermission(plr, "plots.area.regen")) { if (!Permissions.hasPermission(plr, "plots.area.regen")) {
C.NO_PERMISSION.send(plr, "plots.area.regen"); C.NO_PERMISSION.send(plr, "plots.area.regen");

View File

@ -51,6 +51,10 @@ public class Download extends SubCommand {
return false; return false;
} }
if (args.length == 0 || (args.length == 1 && StringMan.isEqualIgnoreCaseToAny(args[0], "sch", "schem", "schematic"))) { 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(); plot.addRunning();
SchematicHandler.manager.getCompoundTag(plot, new RunnableVal<CompoundTag>() { SchematicHandler.manager.getCompoundTag(plot, new RunnableVal<CompoundTag>() {
@Override @Override
@ -72,6 +76,10 @@ public class Download extends SubCommand {
if (!Permissions.hasPermission(plr, "plots.download.bo3")) { if (!Permissions.hasPermission(plr, "plots.download.bo3")) {
C.NO_PERMISSION.send(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(); plot.addRunning();
BO3Handler.upload(plot, null, null, new RunnableVal<URL>() { BO3Handler.upload(plot, null, null, new RunnableVal<URL>() {
@Override @Override

View File

@ -49,7 +49,19 @@ public class Kick extends SubCommand {
C.CANNOT_KICK_PLAYER.send(plr, player.getName()); C.CANNOT_KICK_PLAYER.send(plr, player.getName());
return false; 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; return true;
} }
} }

View File

@ -38,6 +38,7 @@ public class Relight extends Command {
}, new Runnable() { }, new Runnable() {
@Override @Override
public void run() { public void run() {
plot.refreshChunks();
C.SET_BLOCK_ACTION_FINISHED.send(player); C.SET_BLOCK_ACTION_FINISHED.send(player);
} }
}, 5); }, 5);

View File

@ -271,6 +271,7 @@ public enum C {
/* /*
* Schematic Stuff * 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 <name>$2 , $1save$2 , $1paste $2, $1exportall", "Schematics"), SCHEMATIC_MISSING_ARG("$2You need to specify an argument. Possible values: $1test <name>$2 , $1save$2 , $1paste $2, $1exportall", "Schematics"),
SCHEMATIC_INVALID("$2That is not a valid schematic. Reason: $2%s", "Schematics"), SCHEMATIC_INVALID("$2That is not a valid schematic. Reason: $2%s", "Schematics"),
SCHEMATIC_VALID("$2That is a valid schematic", "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 <name> $2or $1/plot denied remove <name>", "Deny"), DENIED_NEED_ARGUMENT("$2Arguments are missing. $1/plot denied add <name> $2or $1/plot denied remove <name>", "Deny"),
WAS_NOT_DENIED("$2That player was not denied on this plot", "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"), 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 * Rain
*/ */

View File

@ -438,7 +438,6 @@ public abstract class FlagValue<T> {
@Override @Override
public List<String> parse(final String t) { public List<String> parse(final String t) {
System.out.println("PARSE: " + t);
return new ArrayList<>(Arrays.asList(t.split(","))); return new ArrayList<>(Arrays.asList(t.split(",")));
} }

View File

@ -20,7 +20,6 @@ import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler; import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil; import com.intellectualcrafters.plot.util.WorldUtil;
import com.plotsquared.listener.PlotListener; import com.plotsquared.listener.PlotListener;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.geom.Area; import java.awt.geom.Area;
import java.awt.geom.PathIterator; import java.awt.geom.PathIterator;
@ -777,23 +776,14 @@ public class Plot {
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
} }
}; };
if (isDelete) { for (Plot current : plots) {
for (Plot current : plots) { if (isDelete || current.owner == null) {
manager.unclaimPlot(Plot.this.area, current, new Runnable() { manager.unclaimPlot(Plot.this.area, current, null);
@Override } else {
public void run() {
if (finished.incrementAndGet() >= plots.size()) {
run.run();
}
}
});
}
} else {
for (Plot current : plots) {
manager.claimPlot(Plot.this.area, current); manager.claimPlot(Plot.this.area, current);
} }
SetQueue.IMP.addTask(run);
} }
SetQueue.IMP.addTask(run);
return; return;
} }
Plot current = queue.poll(); Plot current = queue.poll();
@ -804,7 +794,16 @@ public class Plot {
manager.clearPlot(Plot.this.area, current, this); manager.clearPlot(Plot.this.area, current, this);
} }
}; };
run.run(); if (!isMerged() && area.getRegion().equals(getLargestRegion())) {
ChunkManager.largeRegionTask(area.worldname, area.getRegion(), new RunnableVal<ChunkLoc>() {
@Override
public void run(ChunkLoc value) {
ChunkManager.manager.regenerateChunk(area.worldname, value);
}
}, whenDone);
} else {
run.run();
}
return true; 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) { if (this.area.DEFAULT_HOME.x == Integer.MAX_VALUE && this.area.DEFAULT_HOME.z == Integer.MAX_VALUE) {
// center // center
RegionWrapper largest = plot.getLargestRegion(); RegionWrapper largest = plot.getLargestRegion();
x = (largest.maxX - largest.minX) / 2 + largest.minX; x = (largest.maxX >> 1) - (largest.minX >> 1) + largest.minX;
z = (largest.maxZ - largest.minZ) / 2 + largest.minZ; z = (largest.maxZ >> 1) - (largest.minZ >> 1) + largest.minZ;
} else { } else {
// specific // specific
Location bot = plot.getBottomAbs(); Location bot = plot.getBottomAbs();
@ -1150,13 +1149,21 @@ public class Plot {
} }
// Side // Side
RegionWrapper largest = plot.getLargestRegion(); 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; int z = largest.minZ - 1;
PlotManager manager = plot.getManager(); PlotManager manager = plot.getManager();
int y = Math.max(WorldUtil.IMP.getHighestBlock(plot.area.worldname, x, z), manager.getSignLoc(plot.area, plot).getY()); 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); 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 * Get the average rating of the plot. This is the value displayed in /plot info
* @return average rating as double * @return average rating as double
@ -2201,6 +2208,10 @@ public class Plot {
return this.area.getPlotAbs(this.id.getRelative(x, y)); 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<br> * Get the plot in a relative direction<br>
* 0 = north<br> * 0 = north<br>
@ -2470,9 +2481,9 @@ public class Plot {
public RegionWrapper getLargestRegion() { public RegionWrapper getLargestRegion() {
HashSet<RegionWrapper> regions = this.getRegions(); HashSet<RegionWrapper> regions = this.getRegions();
RegionWrapper max = null; RegionWrapper max = null;
int area = 0; double area = Double.NEGATIVE_INFINITY;
for (RegionWrapper region : regions) { 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) { if (current > area) {
max = region; max = region;
area = current; area = current;
@ -2680,7 +2691,7 @@ public class Plot {
* @return * @return
*/ */
public boolean move(final Plot destination, final Runnable whenDone, boolean allowSwap) { 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 db = destination.getBottomAbs();
Location ob = this.getBottomAbs(); Location ob = this.getBottomAbs();
final int offsetX = db.getX() - ob.getX(); final int offsetX = db.getX() - ob.getX();
@ -2692,21 +2703,24 @@ public class Plot {
boolean occupied = false; boolean occupied = false;
HashSet<Plot> plots = this.getConnectedPlots(); HashSet<Plot> plots = this.getConnectedPlots();
for (Plot plot : plots) { 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 (other.hasOwner()) {
if (!allowSwap) { if (!allowSwap) {
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, 1);
return false; return false;
} }
occupied = true; occupied = true;
} else {
plot.removeSign();
} }
} }
// world border // world border
destination.updateWorldBorder(); destination.updateWorldBorder();
final ArrayDeque<RegionWrapper> regions = new ArrayDeque<>(this.getRegions()); final ArrayDeque<RegionWrapper> regions = new ArrayDeque<>(this.getRegions());
// move / swap data // move / swap data
final PlotArea originArea = getArea();
for (Plot plot : plots) { 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); plot.swapData(other, null);
} }
// copy terrain // copy terrain
@ -2714,6 +2728,13 @@ public class Plot {
@Override @Override
public void run() { public void run() {
if (regions.isEmpty()) { 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); TaskManager.runTask(whenDone);
return; return;
} }
@ -2728,7 +2749,7 @@ public class Plot {
@Override @Override
public void run() { public void run() {
ChunkManager.manager.regenerateRegion(pos1, pos2, false, task); ChunkManager.manager.regenerateRegion(pos1, pos2, false, task);
} }
}); });
} }
}; };
@ -2776,7 +2797,7 @@ public class Plot {
} }
HashSet<Plot> plots = this.getConnectedPlots(); HashSet<Plot> plots = this.getConnectedPlots();
for (Plot plot : plots) { 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 (other.hasOwner()) {
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, 1);
return false; return false;
@ -2786,7 +2807,7 @@ public class Plot {
destination.updateWorldBorder(); destination.updateWorldBorder();
// copy data // copy data
for (Plot plot : plots) { 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); other.create(plot.owner, false);
if (!plot.getFlags().isEmpty()) { if (!plot.getFlags().isEmpty()) {
other.getSettings().flags = plot.getFlags(); other.getSettings().flags = plot.getFlags();
@ -2820,6 +2841,10 @@ public class Plot {
@Override @Override
public void run() { public void run() {
if (regions.isEmpty()) { if (regions.isEmpty()) {
for (Plot current : getConnectedPlots()) {
destination.getManager().claimPlot(destination.getArea(), destination);
}
destination.setSign();
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
return; return;
} }

View File

@ -4,6 +4,7 @@ import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.Location; import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotBlock; import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.RunnableVal; import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.object.schematic.PlotItem; import com.intellectualcrafters.plot.object.schematic.PlotItem;
@ -29,9 +30,11 @@ public abstract class WorldUtil {
public abstract boolean isWorld(String worldName); public abstract boolean isWorld(String worldName);
public abstract String[] getSign(Location location); public abstract String[] getSign(Location location);
public abstract Location getSpawn(String world); public abstract Location getSpawn(String world);
public abstract Location getSpawn(PlotPlayer pp);
public abstract void setSpawn(Location location); public abstract void setSpawn(Location location);
public abstract void saveWorld(String world); public abstract void saveWorld(String world);

View File

@ -345,7 +345,13 @@ public class SpongeUtil extends WorldUtil {
BlockState state = SpongeUtil.getWorld(location.getWorld()).getBlock(location.getX(), location.getY(), location.getZ()); BlockState state = SpongeUtil.getWorld(location.getWorld()).getBlock(location.getX(), location.getY(), location.getZ());
return SpongeUtil.getPlotBlock(state); 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 @Override
public Location getSpawn(String world) { public Location getSpawn(String world) {
Location result = SpongeUtil.getLocation(world, SpongeUtil.getWorld(world).getSpawnLocation()); Location result = SpongeUtil.getLocation(world, SpongeUtil.getWorld(world).getSpawnLocation());