PlotSquared/src/main/java/com/intellectualcrafters/plot/util/bukkit/BukkitChunkManager.java

1124 lines
52 KiB
Java
Raw Normal View History

2015-02-23 06:29:45 +01:00
package com.intellectualcrafters.plot.util.bukkit;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.apache.commons.lang.mutable.MutableInt;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.Note;
import org.bukkit.SkullType;
import org.bukkit.World;
import org.bukkit.block.Banner;
import org.bukkit.block.Beacon;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.BrewingStand;
import org.bukkit.block.Chest;
import org.bukkit.block.CommandBlock;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.block.Dispenser;
import org.bukkit.block.Dropper;
import org.bukkit.block.Furnace;
import org.bukkit.block.Hopper;
import org.bukkit.block.Jukebox;
import org.bukkit.block.NoteBlock;
import org.bukkit.block.Sign;
import org.bukkit.block.Skull;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
2015-03-20 14:09:51 +01:00
import org.bukkit.entity.Animals;
import org.bukkit.entity.Creature;
2015-02-23 06:29:45 +01:00
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
2015-04-14 16:35:01 +02:00
import org.bukkit.entity.Vehicle;
2015-02-23 06:29:45 +01:00
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import com.intellectualcrafters.plot.BukkitMain;
import com.intellectualcrafters.plot.PS;
2015-04-26 08:29:58 +02:00
import com.intellectualcrafters.plot.listeners.APlotListener;
2015-02-23 06:29:45 +01:00
import com.intellectualcrafters.plot.object.BlockLoc;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotBlock;
2015-02-23 06:29:45 +01:00
import com.intellectualcrafters.plot.object.PlotId;
2015-02-26 05:43:01 +01:00
import com.intellectualcrafters.plot.object.PlotLoc;
2015-04-26 08:29:58 +02:00
import com.intellectualcrafters.plot.object.PlotPlayer;
2015-02-23 06:29:45 +01:00
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.entity.EntityWrapper;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.MainUtil;
2015-05-15 10:12:52 +02:00
import com.intellectualcrafters.plot.util.SetBlockQueue.ChunkWrapper;
2015-02-23 06:29:45 +01:00
import com.intellectualcrafters.plot.util.TaskManager;
public class BukkitChunkManager extends ChunkManager {
@Override
public ArrayList<ChunkLoc> getChunkChunks(final String world) {
final String directory = Bukkit.getWorldContainer() + File.separator + world + File.separator + "region";
2015-02-23 06:29:45 +01:00
final File folder = new File(directory);
final File[] regionFiles = folder.listFiles();
final ArrayList<ChunkLoc> chunks = new ArrayList<>();
if (regionFiles == null) {
throw new RuntimeException("Could not find worlds folder.");
}
2015-02-23 06:29:45 +01:00
for (final File file : regionFiles) {
final String name = file.getName();
if (name.endsWith("mca")) {
final String[] split = name.split("\\.");
try {
final int x = Integer.parseInt(split[1]);
final int z = Integer.parseInt(split[2]);
final ChunkLoc loc = new ChunkLoc(x, z);
chunks.add(loc);
} catch (final Exception e) {
}
}
}
for (final Chunk chunk : Bukkit.getWorld(world).getLoadedChunks()) {
final ChunkLoc loc = new ChunkLoc(chunk.getX() >> 5, chunk.getZ() >> 5);
if (!chunks.contains(loc)) {
chunks.add(loc);
}
}
return chunks;
}
@Override
public void regenerateChunk(String world, ChunkLoc loc) {
World worldObj = Bukkit.getWorld(world);
// Chunk chunk = worldObj.getChunkAt(loc.x, loc.z);
worldObj.regenerateChunk(loc.x, loc.z);
for (final Player player : worldObj.getPlayers()) {
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));
if (plot != null) {
final PlotPlayer pp = BukkitUtil.getPlayer(player);
pp.teleport(MainUtil.getDefaultHome(plot));
}
}
}
}
2015-02-23 06:29:45 +01:00
@Override
public void deleteRegionFile(final String world, final ChunkLoc loc) {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
final String directory = world + File.separator + "region" + File.separator + "r." + loc.x + "." + loc.z + ".mca";
final File file = new File(directory);
PS.log("&6 - Deleting region: " + file.getName() + " (approx 1024 chunks)");
2015-02-23 06:29:45 +01:00
if (file.exists()) {
file.delete();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
});
}
@Override
public void deleteRegionFiles(final String world, final List<ChunkLoc> chunks) {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
for (ChunkLoc loc : chunks) {
final String directory = world + File.separator + "region" + File.separator + "r." + loc.x + "." + loc.z + ".mca";
final File file = new File(directory);
PS.log("&6 - Deleting file: " + file.getName() + " (max 1024 chunks)");
if (file.exists()) {
file.delete();
}
}
2015-02-23 06:29:45 +01:00
}
});
}
@Override
public Plot hasPlot(final String world, final ChunkLoc chunk) {
final int x1 = chunk.x << 4;
final int z1 = chunk.z << 4;
final int x2 = x1 + 15;
final int z2 = z1 + 15;
final Location bot = new Location(world, x1, 0, z1);
Plot plot;
plot = MainUtil.getPlot(bot);
2015-03-20 05:11:02 +01:00
if ((plot != null) && (plot.owner != null)) {
2015-02-23 06:29:45 +01:00
return plot;
}
final Location top = new Location(world, x2, 0, z2);
plot = MainUtil.getPlot(top);
2015-03-20 05:11:02 +01:00
if ((plot != null) && (plot.owner != null)) {
2015-02-23 06:29:45 +01:00
return plot;
}
return null;
}
private static HashMap<BlockLoc, ItemStack[]> chestContents;
private static HashMap<BlockLoc, ItemStack[]> furnaceContents;
private static HashMap<BlockLoc, ItemStack[]> dispenserContents;
private static HashMap<BlockLoc, ItemStack[]> dropperContents;
private static HashMap<BlockLoc, ItemStack[]> brewingStandContents;
private static HashMap<BlockLoc, ItemStack[]> beaconContents;
private static HashMap<BlockLoc, ItemStack[]> hopperContents;
private static HashMap<BlockLoc, Short[]> furnaceTime;
private static HashMap<BlockLoc, Object[]> skullData;
private static HashMap<BlockLoc, Short> jukeDisc;
private static HashMap<BlockLoc, Short> brewTime;
private static HashMap<BlockLoc, String> spawnerData;
private static HashMap<BlockLoc, String> cmdData;
private static HashMap<BlockLoc, String[]> signContents;
private static HashMap<BlockLoc, Note> noteBlockContents;
private static HashMap<BlockLoc, ArrayList<Byte[]>> bannerColors;
private static HashMap<BlockLoc, Byte> bannerBase;
private static HashSet<EntityWrapper> 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) {
2015-05-21 10:42:00 +02:00
TaskManager.index.increment();
2015-02-23 06:29:45 +01:00
final int relX = newPos.getX() - pos1.getX();
final int relZ = newPos.getZ() - pos1.getZ();
2015-05-21 10:42:00 +02:00
2015-02-23 06:29:45 +01:00
final RegionWrapper region = new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
final World oldWorld = Bukkit.getWorld(pos1.getWorld());
final World newWorld = Bukkit.getWorld(newPos.getWorld());
2015-05-21 10:42:00 +02:00
final Chunk c1 = newWorld.getChunkAt(pos1.getX() >> 4, pos1.getZ() >> 4);
final Chunk c2 = newWorld.getChunkAt(pos2.getX() >> 4, pos2.getZ() >> 4);
2015-05-21 10:42:00 +02:00
2015-02-23 06:29:45 +01:00
final int sx = pos1.getX();
final int sz = pos1.getZ();
final int ex = pos2.getX();
final int ez = pos2.getZ();
2015-05-21 10:42:00 +02:00
2015-02-23 06:29:45 +01:00
final int c1x = c1.getX();
final int c1z = c1.getZ();
final int c2x = c2.getX();
final int c2z = c2.getZ();
2015-05-21 10:42:00 +02:00
2015-02-23 06:29:45 +01:00
final ArrayList<Chunk> chunks = new ArrayList<>();
final ArrayList<Chunk> toGenerate = new ArrayList<>();
// Load chunks
2015-03-26 08:09:09 +01:00
for (int x = c1x; x <= c2x; x++) {
for (int z = c1z; z <= c2z; z++) {
final Chunk chunk = newWorld.getChunkAt(x, z);
2015-02-23 06:29:45 +01:00
toGenerate.add(chunk);
}
}
final Plugin plugin = BukkitMain.THIS;
2015-04-01 02:52:22 +02:00
final Integer currentIndex = TaskManager.index.toInteger();
2015-02-23 06:29:45 +01:00
final int loadTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
final long start = System.currentTimeMillis();
while ((System.currentTimeMillis() - start) < 25) {
if (toGenerate.size() == 0) {
2015-04-01 02:52:22 +02:00
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
2015-02-23 06:29:45 +01:00
TaskManager.runTask(new Runnable() {
@Override
public void run() {
2015-05-21 10:42:00 +02:00
TaskManager.index.increment();
2015-02-23 06:29:45 +01:00
// Copy entities
initMaps();
2015-02-23 10:03:42 +01:00
for (int x = c1x; x <= c2x; x++) {
for (int z = c1z; z <= c2z; z++) {
final Chunk chunk = oldWorld.getChunkAt(x, z);
2015-02-23 06:29:45 +01:00
chunks.add(chunk);
chunk.load(false);
}
}
// Copy blocks
final MutableInt mx = new MutableInt(sx);
2015-04-01 02:52:22 +02:00
final Integer currentIndex = TaskManager.index.toInteger();
final int maxY = oldWorld.getMaxHeight();
2015-02-23 06:29:45 +01:00
final Integer task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
final long start = System.currentTimeMillis();
while ((System.currentTimeMillis() - start) < 25) {
final int xv = mx.intValue();
for (int z = sz; z <= ez; z++) {
saveBlocks(oldWorld, maxY, xv, z);
2015-02-23 06:29:45 +01:00
for (int y = 1; y <= maxY; y++) {
final Block block = oldWorld.getBlockAt(xv, y, z);
2015-02-23 06:29:45 +01:00
final int id = block.getTypeId();
final byte data = block.getData();
BukkitSetBlockManager.setBlockManager.set(newWorld, xv + relX, y, z + relZ, id, data);
2015-02-23 06:29:45 +01:00
}
}
mx.increment();
if (xv == ex) { // done!
2015-04-01 14:36:46 +02:00
for (int x = c1x; x <= c2x; x++) {
for (int z = c1z; z <= c2z; z++) {
final Chunk chunk = oldWorld.getChunkAt(x, z);
chunks.add(chunk);
chunk.load(false);
saveEntitiesIn(chunk, region);
}
}
restoreBlocks(newWorld, relX, relZ);
2015-05-21 10:42:00 +02:00
restoreEntities(newWorld, relX, relZ);
2015-02-23 06:29:45 +01:00
BukkitSetBlockManager.setBlockManager.update(chunks);
TaskManager.runTask(whenDone);
2015-04-01 02:52:22 +02:00
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
2015-02-23 06:29:45 +01:00
return;
}
}
};
}, 1, 1);
2015-04-01 02:52:22 +02:00
TaskManager.tasks.put(currentIndex, task);
2015-02-23 06:29:45 +01:00
}
});
return;
}
final Chunk chunk = toGenerate.get(0);
toGenerate.remove(0);
chunk.load(true);
chunks.add(chunk);
}
}
}, 1l, 1l);
2015-04-01 02:52:22 +02:00
TaskManager.tasks.put(currentIndex, loadTask);
2015-02-23 06:29:45 +01:00
return true;
}
2015-05-21 10:42:00 +02:00
2015-02-23 06:29:45 +01:00
@Override
public boolean regenerateRegion(final Location pos1, final Location pos2, final Runnable whenDone) {
2015-05-21 10:42:00 +02:00
TaskManager.index.increment();
2015-02-23 06:29:45 +01:00
final Plugin plugin = BukkitMain.THIS;
final World world = Bukkit.getWorld(pos1.getWorld());
final Chunk c1 = world.getChunkAt(pos1.getX() >> 4, pos1.getZ() >> 4);
final Chunk c2 = world.getChunkAt(pos2.getX() >> 4, pos2.getZ() >> 4);
final int sx = pos1.getX();
final int sz = pos1.getZ();
final int ex = pos2.getX();
final int ez = pos2.getZ();
final int c1x = c1.getX();
final int c1z = c1.getZ();
final int c2x = c2.getX();
final int c2z = c2.getZ();
final ArrayList<Chunk> chunks = new ArrayList<Chunk>();
for (int x = c1x; x <= c2x; x++) {
for (int z = c1z; z <= c2z; z++) {
final Chunk chunk = world.getChunkAt(x, z);
chunk.load(false);
chunks.add(chunk);
}
}
final int maxY = world.getMaxHeight();
2015-04-01 02:52:22 +02:00
final Integer currentIndex = TaskManager.index.toInteger();
2015-02-23 06:29:45 +01:00
final Integer task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
2015-05-21 10:42:00 +02:00
final long start = System.currentTimeMillis();
while ((System.currentTimeMillis() - start) < 20) {
2015-04-26 14:11:18 +02:00
if (chunks.size() == 0) {
TaskManager.runTaskLater(whenDone, 1);
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
return;
2015-02-23 06:29:45 +01:00
}
2015-04-26 14:11:18 +02:00
CURRENT_PLOT_CLEAR = new RegionWrapper(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
final Chunk chunk = chunks.get(0);
chunks.remove(0);
final int x = chunk.getX();
final int z = chunk.getZ();
boolean loaded = true;
2015-02-23 06:29:45 +01:00
if (!chunk.isLoaded()) {
2015-04-26 14:11:18 +02:00
final boolean result = chunk.load(false);
if (!result) {
loaded = false;
}
if (!chunk.isLoaded()) {
loaded = false;
}
2015-02-23 06:29:45 +01:00
}
2015-04-26 14:11:18 +02:00
if (loaded) {
initMaps();
final int absX = x << 4;
final int absZ = z << 4;
boolean save = false;
if ((x == c1x) || (z == c1z)) {
save = true;
for (int X = 0; X < 16; X++) {
for (int Z = 0; Z < 16; Z++) {
if ((((X + absX) < sx) || ((Z + absZ) < sz)) || (((X + absX) > ex) || ((Z + absZ) > ez))) {
saveBlocks(world, maxY, X + absX, Z + absZ);
}
2015-02-23 06:29:45 +01:00
}
}
2015-04-26 14:11:18 +02:00
} else if ((x == c2x) || (z == c2z)) {
for (int X = 0; X < 16; X++) {
save = true;
for (int Z = 0; Z < 16; Z++) {
if ((((X + absX) > ex) || ((Z + absZ) > ez)) || (((X + absX) < sx) || ((Z + absZ) < sz))) {
saveBlocks(world, maxY, X + absX, Z + absZ);
}
2015-02-23 06:29:45 +01:00
}
}
}
2015-04-26 14:11:18 +02:00
if (save) {
saveEntitiesOut(chunk, CURRENT_PLOT_CLEAR);
}
ChunkLoc loc = new ChunkLoc(chunk.getX(), chunk.getZ());
regenerateChunk(world.getName(), loc);
2015-04-26 14:11:18 +02:00
if (save) {
restoreBlocks(world, 0, 0);
restoreEntities(world, 0, 0);
}
MainUtil.update(world.getName(), loc);
2015-04-26 14:11:18 +02:00
BukkitSetBlockManager.setBlockManager.update(Arrays.asList(new Chunk[] { chunk }));
2015-02-23 06:29:45 +01:00
}
2015-04-26 14:11:18 +02:00
CURRENT_PLOT_CLEAR = null;
2015-02-23 06:29:45 +01:00
}
}
}, 1, 1);
2015-04-01 02:52:22 +02:00
TaskManager.tasks.put(currentIndex, task);
2015-02-23 06:29:45 +01:00
return true;
}
public static void initMaps() {
GENERATE_BLOCKS = new HashMap<>();
GENERATE_DATA = new HashMap<>();
chestContents = new HashMap<>();
furnaceContents = new HashMap<>();
dispenserContents = new HashMap<>();
dropperContents = new HashMap<>();
brewingStandContents = new HashMap<>();
beaconContents = new HashMap<>();
hopperContents = new HashMap<>();
furnaceTime = new HashMap<>();
skullData = new HashMap<>();
brewTime = new HashMap<>();
jukeDisc = new HashMap<>();
spawnerData = new HashMap<>();
noteBlockContents = new HashMap<>();
signContents = new HashMap<>();
cmdData = new HashMap<>();
bannerBase = new HashMap<>();
bannerColors = new HashMap<>();
entities = new HashSet<>();
}
public static boolean isIn(final RegionWrapper region, final int x, final int z) {
return ((x >= region.minX) && (x <= region.maxX) && (z >= region.minZ) && (z <= region.maxZ));
}
public static void saveEntitiesOut(final Chunk chunk, final RegionWrapper region) {
for (final Entity entity : chunk.getEntities()) {
final Location loc = BukkitUtil.getLocation(entity);
final int x = loc.getX();
final int z = loc.getZ();
if (isIn(region, x, z)) {
continue;
}
if (entity.getVehicle() != null) {
continue;
}
final EntityWrapper wrap = new EntityWrapper(entity, (short) 2);
entities.add(wrap);
}
}
public static void saveEntitiesIn(final Chunk chunk, final RegionWrapper region) {
2015-02-23 09:53:37 +01:00
saveEntitiesIn(chunk, region, 0, 0, false);
2015-02-23 08:08:49 +01:00
}
2015-05-21 10:42:00 +02:00
public static void saveEntitiesIn(final Chunk chunk, final RegionWrapper region, final int offset_x, final int offset_z, final boolean delete) {
2015-02-23 06:29:45 +01:00
for (final Entity entity : chunk.getEntities()) {
final Location loc = BukkitUtil.getLocation(entity);
final int x = loc.getX();
final int z = loc.getZ();
if (!isIn(region, x, z)) {
continue;
}
if (entity.getVehicle() != null) {
continue;
}
final EntityWrapper wrap = new EntityWrapper(entity, (short) 2);
2015-02-23 08:08:49 +01:00
wrap.x += offset_x;
2015-02-23 09:53:37 +01:00
wrap.z += offset_z;
2015-02-23 06:29:45 +01:00
entities.add(wrap);
2015-02-23 09:53:37 +01:00
if (delete) {
if (!(entity instanceof Player)) {
entity.remove();
}
}
2015-02-23 06:29:45 +01:00
}
}
public static void restoreEntities(final World world, final int x_offset, final int z_offset) {
for (final EntityWrapper entity : entities) {
try {
entity.spawn(world, x_offset, z_offset);
} catch (final Exception e) {
PS.log("Failed to restore entity " + entity.x + "," + entity.y + "," + entity.z + " : " + entity.id + " : " + EntityType.fromId(entity.id));
2015-02-23 06:29:45 +01:00
e.printStackTrace();
}
}
}
public static void restoreBlocks(final World world, final int x_offset, final int z_offset) {
for (final BlockLoc loc : chestContents.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Chest) {
final Chest chest = (Chest) state;
chest.getInventory().setContents(chestContents.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate chest: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate chest: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : signContents.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Sign) {
final Sign sign = (Sign) state;
int i = 0;
for (final String line : signContents.get(loc)) {
sign.setLine(i, line);
i++;
}
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate sign: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
2015-05-21 10:42:00 +02:00
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate sign: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : dispenserContents.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Dispenser) {
((Dispenser) (state)).getInventory().setContents(dispenserContents.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate dispenser: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate dispenser: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : dropperContents.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Dropper) {
((Dropper) (state)).getInventory().setContents(dropperContents.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate dispenser: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate dispenser: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : beaconContents.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Beacon) {
((Beacon) (state)).getInventory().setContents(beaconContents.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate beacon: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate beacon: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : jukeDisc.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Jukebox) {
((Jukebox) (state)).setPlaying(Material.getMaterial(jukeDisc.get(loc)));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to restore jukebox: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate jukebox: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : skullData.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Skull) {
final Object[] data = skullData.get(loc);
if (data[0] != null) {
((Skull) (state)).setOwner((String) data[0]);
}
if (((Integer) data[1]) != 0) {
((Skull) (state)).setRotation(BlockFace.values()[(int) data[1]]);
}
if (((Integer) data[2]) != 0) {
((Skull) (state)).setSkullType(SkullType.values()[(int) data[2]]);
}
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to restore skull: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
2015-05-21 10:42:00 +02:00
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate skull: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : hopperContents.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Hopper) {
((Hopper) (state)).getInventory().setContents(hopperContents.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate hopper: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate hopper: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : noteBlockContents.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof NoteBlock) {
((NoteBlock) (state)).setNote(noteBlockContents.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate note block: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate note block: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : brewTime.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof BrewingStand) {
((BrewingStand) (state)).setBrewingTime(brewTime.get(loc));
} else {
PS.log("&c[WARN] Plot clear failed to restore brewing stand cooking: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to restore brewing stand cooking: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : spawnerData.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof CreatureSpawner) {
((CreatureSpawner) (state)).setCreatureTypeId(spawnerData.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to restore spawner type: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to restore spawner type: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : cmdData.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof CommandBlock) {
((CommandBlock) (state)).setCommand(cmdData.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to restore command block: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to restore command block: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : brewingStandContents.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof BrewingStand) {
((BrewingStand) (state)).getInventory().setContents(brewingStandContents.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate brewing stand: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate brewing stand: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : furnaceTime.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Furnace) {
final Short[] time = furnaceTime.get(loc);
((Furnace) (state)).setBurnTime(time[0]);
((Furnace) (state)).setCookTime(time[1]);
} else {
PS.log("&c[WARN] Plot clear failed to restore furnace cooking: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to restore furnace cooking: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : furnaceContents.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Furnace) {
((Furnace) (state)).getInventory().setContents(furnaceContents.get(loc));
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate furnace: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-05-21 10:42:00 +02:00
}
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate furnace: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
for (final BlockLoc loc : bannerBase.keySet()) {
2015-05-21 10:42:00 +02:00
try {
final Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
final BlockState state = block.getState();
if (state instanceof Banner) {
final Banner banner = (Banner) state;
final byte base = bannerBase.get(loc);
final ArrayList<Byte[]> colors = bannerColors.get(loc);
banner.setBaseColor(DyeColor.values()[base]);
for (final Byte[] color : colors) {
banner.addPattern(new Pattern(DyeColor.getByDyeData(color[1]), PatternType.values()[color[0]]));
}
state.update(true);
} else {
PS.log("&c[WARN] Plot clear failed to regenerate banner: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
2015-05-21 10:42:00 +02:00
} catch (final Exception e) {
PS.log("&c[WARN] Plot clear failed to regenerate banner: " + loc.x + x_offset + "," + loc.y + "," + loc.z + z_offset);
2015-02-23 06:29:45 +01:00
}
}
}
2015-05-21 10:42:00 +02:00
2015-02-23 06:29:45 +01:00
public static void saveBlocks(final World world, final int maxY, final int x, final int z) {
2015-02-23 08:08:49 +01:00
saveBlocks(world, maxY, x, z, 0, 0);
}
2015-05-21 10:42:00 +02:00
public static void saveBlocks(final World world, final int maxY, final int x, final int z, final int offset_x, final int offset_z) {
2015-02-23 06:29:45 +01:00
final HashMap<Short, Short> ids = new HashMap<>();
final HashMap<Short, Byte> datas = new HashMap<>();
2015-02-26 05:43:01 +01:00
for (short y = 0; y < maxY; y++) {
2015-02-23 06:29:45 +01:00
final Block block = world.getBlockAt(x, y, z);
final short id = (short) block.getTypeId();
if (id != 0) {
ids.put(y, id);
final byte data = block.getData();
if (data != 0) {
datas.put(y, data);
}
BlockLoc bl;
switch (id) {
case 54:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final InventoryHolder chest = (InventoryHolder) block.getState();
final ItemStack[] inventory = chest.getInventory().getContents().clone();
chestContents.put(bl, inventory);
break;
case 52:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final CreatureSpawner spawner = (CreatureSpawner) block.getState();
final String type = spawner.getCreatureTypeId();
if ((type != null) && (type.length() != 0)) {
spawnerData.put(bl, type);
}
break;
case 137:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final CommandBlock cmd = (CommandBlock) block.getState();
final String string = cmd.getCommand();
if ((string != null) && (string.length() > 0)) {
cmdData.put(bl, string);
}
break;
case 63:
case 68:
case 323:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final Sign sign = (Sign) block.getState();
sign.getLines();
signContents.put(bl, sign.getLines().clone());
break;
case 61:
case 62:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final Furnace furnace = (Furnace) block.getState();
final short burn = furnace.getBurnTime();
final short cook = furnace.getCookTime();
final ItemStack[] invFur = furnace.getInventory().getContents().clone();
furnaceContents.put(bl, invFur);
if (cook != 0) {
furnaceTime.put(bl, new Short[] { burn, cook });
}
break;
case 23:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final Dispenser dispenser = (Dispenser) block.getState();
final ItemStack[] invDis = dispenser.getInventory().getContents().clone();
dispenserContents.put(bl, invDis);
break;
case 158:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final Dropper dropper = (Dropper) block.getState();
final ItemStack[] invDro = dropper.getInventory().getContents().clone();
dropperContents.put(bl, invDro);
break;
case 117:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final BrewingStand brewingStand = (BrewingStand) block.getState();
final short time = (short) brewingStand.getBrewingTime();
if (time > 0) {
brewTime.put(bl, time);
}
final ItemStack[] invBre = brewingStand.getInventory().getContents().clone();
brewingStandContents.put(bl, invBre);
break;
case 25:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final NoteBlock noteBlock = (NoteBlock) block.getState();
final Note note = noteBlock.getNote();
noteBlockContents.put(bl, note);
break;
case 138:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final Beacon beacon = (Beacon) block.getState();
final ItemStack[] invBea = beacon.getInventory().getContents().clone();
beaconContents.put(bl, invBea);
break;
case 84:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final Jukebox jukebox = (Jukebox) block.getState();
final Material playing = jukebox.getPlaying();
if (playing != null) {
jukeDisc.put(bl, (short) playing.getId());
}
break;
case 154:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final Hopper hopper = (Hopper) block.getState();
final ItemStack[] invHop = hopper.getInventory().getContents().clone();
hopperContents.put(bl, invHop);
break;
case 397:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final Skull skull = (Skull) block.getState();
final String o = skull.getOwner();
final byte skulltype = getOrdinal(SkullType.values(), skull.getSkullType());
skull.getRotation();
final short rot = getOrdinal(BlockFace.values(), skull.getRotation());
skullData.put(bl, new Object[] { o, rot, skulltype });
break;
case 176:
case 177:
2015-02-23 08:08:49 +01:00
bl = new BlockLoc(x + offset_x, y, z + offset_z);
2015-02-23 06:29:45 +01:00
final Banner banner = (Banner) block.getState();
final byte base = getOrdinal(DyeColor.values(), banner.getBaseColor());
final ArrayList<Byte[]> types = new ArrayList<>();
for (final Pattern pattern : banner.getPatterns()) {
types.add(new Byte[] { getOrdinal(PatternType.values(), pattern.getPattern()), pattern.getColor().getDyeData() });
}
bannerBase.put(bl, base);
bannerColors.put(bl, types);
break;
}
}
}
2015-03-31 05:34:18 +02:00
final PlotLoc loc = new PlotLoc(x, z);
2015-02-23 06:29:45 +01:00
GENERATE_BLOCKS.put(loc, ids);
GENERATE_DATA.put(loc, datas);
}
private static byte getOrdinal(final Object[] list, final Object value) {
for (byte i = 0; i < list.length; i++) {
if (list[i].equals(value)) {
return i;
}
}
return 0;
}
@Override
public void clearAllEntities(final Plot plot) {
final List<Entity> entities = BukkitUtil.getEntities(plot.world);
for (final Entity entity : entities) {
final PlotId id = MainUtil.getPlotId(BukkitUtil.getLocation(entity));
if (plot.id.equals(id)) {
if (entity instanceof Player) {
final Player player = (Player) entity;
2015-05-21 10:42:00 +02:00
final PlotPlayer pp = BukkitUtil.getPlayer(player);
2015-04-26 08:29:58 +02:00
pp.teleport(MainUtil.getDefaultHome(plot));
2015-02-23 06:29:45 +01:00
} else {
entity.remove();
}
}
}
}
2015-05-21 10:42:00 +02:00
2015-02-23 06:29:45 +01:00
@Override
public boolean loadChunk(final String world, final ChunkLoc loc) {
return BukkitUtil.getWorld(world).getChunkAt(loc.x, loc.z).load(false);
}
2015-05-21 10:42:00 +02:00
2015-02-26 12:00:46 +01:00
@Override
public boolean unloadChunk(final String world, final ChunkLoc loc) {
return BukkitUtil.getWorld(world).getChunkAt(loc.x, loc.z).unload(true, true);
}
2015-05-21 10:42:00 +02:00
public static void swapChunk(final World world, final Chunk pos1, final Chunk pos2, final RegionWrapper r1, final RegionWrapper r2) {
2015-02-23 08:08:49 +01:00
initMaps();
2015-05-21 10:42:00 +02:00
final int relX = (r2.minX - r1.minX);
final int relZ = (r2.minZ - r1.minZ);
2015-02-23 09:53:37 +01:00
saveEntitiesIn(pos1, r1, relX, relZ, true);
saveEntitiesIn(pos2, r2, -relX, -relZ, true);
2015-05-21 10:42:00 +02:00
final int sx = pos1.getX() << 4;
final int sz = pos1.getZ() << 4;
final int maxY = world.getMaxHeight();
2015-02-23 08:29:50 +01:00
for (int x = Math.max(r1.minX, sx); x <= Math.min(r1.maxX, sx + 15); x++) {
2015-05-21 10:42:00 +02:00
for (int z = Math.max(r1.minZ, sz); z <= Math.min(r1.maxZ, sz + 15); z++) {
2015-02-23 08:08:49 +01:00
saveBlocks(world, maxY, sx, sz, relX, relZ);
for (int y = 0; y < maxY; y++) {
2015-05-21 10:42:00 +02:00
final Block block1 = world.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 int id2 = block2.getTypeId();
final byte data2 = block2.getData();
2015-02-23 08:08:49 +01:00
if (id1 == 0) {
if (id2 != 0) {
BukkitSetBlockManager.setBlockManager.set(world, x, y, z, id2, data2);
2015-02-23 08:29:50 +01:00
BukkitSetBlockManager.setBlockManager.set(world, xx, y, zz, 0, (byte) 0);
2015-02-23 08:08:49 +01:00
}
2015-05-21 10:42:00 +02:00
} else if (id2 == 0) {
2015-02-23 08:08:49 +01:00
if (id1 != 0) {
BukkitSetBlockManager.setBlockManager.set(world, xx, y, zz, id1, data1);
2015-02-23 08:29:50 +01:00
BukkitSetBlockManager.setBlockManager.set(world, x, y, z, 0, (byte) 0);
2015-02-23 08:08:49 +01:00
}
2015-05-21 10:42:00 +02:00
} else if (id1 == id2) {
2015-02-23 08:08:49 +01:00
if (data1 != data2) {
block1.setData(data2);
block2.setData(data1);
}
2015-05-21 10:42:00 +02:00
} else {
2015-02-23 08:08:49 +01:00
BukkitSetBlockManager.setBlockManager.set(world, x, y, z, id2, data2);
BukkitSetBlockManager.setBlockManager.set(world, xx, y, zz, id1, data1);
}
2015-05-21 10:42:00 +02:00
2015-02-23 08:08:49 +01:00
}
}
}
restoreBlocks(world, 0, 0);
restoreEntities(world, 0, 0);
}
2015-05-21 10:42:00 +02:00
2015-02-23 06:29:45 +01:00
@Override
2015-02-23 08:08:49 +01:00
public void swap(final String worldname, final PlotId pos1, final PlotId pos2) {
2015-05-21 10:42:00 +02:00
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);
2015-03-22 14:48:02 +01:00
swap(worldname, bot1, top1, bot2, top2);
2015-05-21 10:42:00 +02:00
2015-03-22 14:48:02 +01:00
clearAllEntities(MainUtil.getPlot(worldname, pos1));
clearAllEntities(MainUtil.getPlot(worldname, pos2));
}
2015-05-21 10:42:00 +02:00
2015-03-22 14:48:02 +01:00
@Override
2015-05-21 10:42:00 +02:00
public void swap(final String worldname, final Location bot1, final Location top1, final Location bot2, final Location top2) {
2015-02-23 08:08:49 +01:00
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());
2015-05-21 10:42:00 +02:00
2015-02-23 08:08:49 +01:00
final int relX = bot2.getX() - bot1.getX();
final int relZ = bot2.getZ() - bot1.getZ();
2015-05-21 10:42:00 +02:00
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));
2015-02-23 08:08:49 +01:00
swapChunk(world, chunk1, chunk2, region1, region2);
}
}
2015-02-23 06:29:45 +01:00
// FIXME swap plots
}
@Override
2015-05-21 10:42:00 +02:00
public int[] countEntities(final Plot plot) {
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 int bx = bot.getX() >> 4;
final int bz = bot.getZ() >> 4;
final int tx = top.getX() >> 4;
final int tz = top.getZ() >> 4;
final int size = (tx - bx) << 4;
final HashSet<Chunk> chunks = new HashSet<>();
for (int X = bx; X <= tx; X++) {
for (int Z = bz; Z <= tz; Z++) {
chunks.add(world.getChunkAt(X, Z));
}
}
2015-05-21 10:42:00 +02:00
boolean doWhole = false;
List<Entity> entities = null;
if (size > 200) {
entities = world.getEntities();
if (entities.size() < (16 + ((size * size) / 64))) {
doWhole = true;
2015-03-20 14:09:51 +01:00
}
2015-05-21 10:42:00 +02:00
}
if (doWhole) {
for (final Entity entity : entities) {
if (!((entity instanceof Creature) || (entity instanceof Vehicle))) {
continue;
}
2015-05-21 10:42:00 +02:00
final org.bukkit.Location loc = entity.getLocation();
final Chunk chunk = loc.getChunk();
if (chunks.contains(chunk)) {
final int X = chunk.getX();
final int Z = chunk.getX();
if ((X > bx) && (X < tx) && (Z > bz) && (Z < tz)) {
2015-04-14 16:35:01 +02:00
count(count, entity);
2015-05-21 10:42:00 +02:00
} else {
final PlotId id = MainUtil.getPlotId(BukkitUtil.getLocation(loc));
if (plot.id.equals(id)) {
count(count, entity);
}
}
}
}
2015-05-21 10:42:00 +02:00
} else {
for (final Chunk chunk : chunks) {
final int X = chunk.getX();
final int Z = chunk.getX();
final Entity[] ents = chunk.getEntities();
for (final Entity entity : ents) {
if (!((entity instanceof Creature) || (entity instanceof Vehicle))) {
continue;
}
if ((X == bx) || (X == tx) || (Z == bz) || (Z == tz)) {
final PlotId id = MainUtil.getPlotId(BukkitUtil.getLocation(entity));
if (plot.id.equals(id)) {
count(count, entity);
}
} else {
2015-04-14 16:35:01 +02:00
count(count, entity);
}
2015-05-21 10:42:00 +02:00
}
}
}
2015-05-21 10:42:00 +02:00
return count;
}
2015-05-21 10:42:00 +02:00
private void count(final int[] count, final Entity entity) {
2015-04-14 16:35:01 +02:00
count[0]++;
if (entity instanceof Creature) {
count[3]++;
if (entity instanceof Animals) {
count[1]++;
2015-05-21 10:42:00 +02:00
} else {
2015-04-14 16:35:01 +02:00
count[2]++;
}
2015-05-21 10:42:00 +02:00
} else {
2015-04-14 16:35:01 +02:00
count[4]++;
}
}
@Override
2015-05-21 10:42:00 +02:00
public void setChunk(final ChunkWrapper loc, final PlotBlock[][] blocks) {
CURRENT_PLOT_CLEAR = new RegionWrapper(0, 0, 0, 0);
final World world = Bukkit.getWorld(loc.world);
final Chunk chunk = world.getChunkAt(loc.x, loc.z);
final int cx = chunk.getX();
final int cz = chunk.getZ();
if (!chunk.isLoaded()) {
chunk.load(true);
}
initMaps();
final int absX = cx << 4;
final int absZ = cz << 4;
2015-05-21 10:42:00 +02:00
final boolean save = false;
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
saveBlocks(world, 255, absX + x, absZ + z);
2015-05-21 10:42:00 +02:00
final PlotLoc pl = new PlotLoc(absX + x, absZ + z);
final HashMap<Short, Short> ids = GENERATE_BLOCKS.get(pl);
final HashMap<Short, Short> datas = GENERATE_BLOCKS.get(pl);
for (int i = 0; i < blocks.length; i++) {
if (blocks[i] != null) {
2015-05-21 10:42:00 +02:00
final short y0 = (short) (i << 4);
for (short y = y0; y < (y0 + 16); y++) {
final int j = ((y & 0xF) << 8) | (z << 4) | x;
final PlotBlock block = blocks[i][j];
if (block != null) {
ids.put(y, block.id);
if (block.data != 0) {
datas.put(y, block.id);
}
}
}
}
}
}
}
if (save) {
saveEntitiesOut(chunk, CURRENT_PLOT_CLEAR);
}
ChunkLoc chunkLoc = new ChunkLoc(chunk.getX(), chunk.getZ());
regenerateChunk(world.getName(), chunkLoc);
if (save) {
restoreBlocks(world, 0, 0);
restoreEntities(world, 0, 0);
}
MainUtil.update(world.getName(), chunkLoc);
BukkitSetBlockManager.setBlockManager.update(Arrays.asList(new Chunk[] { chunk }));
CURRENT_PLOT_CLEAR = null;
}
2015-05-21 10:42:00 +02:00
2015-02-23 06:29:45 +01:00
}