From 6a6387256b9e6198b1bd1e75fa1679fa99010cf2 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Wed, 5 Apr 2017 09:59:40 +1000 Subject: [PATCH] Anvil commands for bukkit 1.10, 1.9 --- .../fawe/bukkit/v1_10/BukkitQueue_1_10.java | 76 ++++++++++++++++ .../fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java | 76 ++++++++++++++++ .../com/boydti/fawe/jnbt/anvil/MCAChunk.java | 10 +- .../com/boydti/fawe/jnbt/anvil/MCAFile.java | 2 - .../com/boydti/fawe/jnbt/anvil/MCAQueue.java | 91 +------------------ .../boydti/fawe/jnbt/anvil/MCAQueueMap.java | 8 +- 6 files changed, 164 insertions(+), 99 deletions(-) diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java index ef1a2796..01c477b7 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_10/BukkitQueue_1_10.java @@ -7,6 +7,7 @@ import com.boydti.fawe.bukkit.v0.BukkitQueue_0; import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.brush.visualization.VisualChunk; import com.boydti.fawe.object.visitor.FaweChunkVisitor; @@ -25,9 +26,11 @@ import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.ArrayDeque; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.UUID; @@ -57,6 +60,8 @@ import net.minecraft.server.v1_10_R1.PacketPlayOutMapChunk; import net.minecraft.server.v1_10_R1.PacketPlayOutMultiBlockChange; import net.minecraft.server.v1_10_R1.PlayerChunk; import net.minecraft.server.v1_10_R1.PlayerChunkMap; +import net.minecraft.server.v1_10_R1.RegionFile; +import net.minecraft.server.v1_10_R1.RegionFileCache; import net.minecraft.server.v1_10_R1.ServerNBTManager; import net.minecraft.server.v1_10_R1.TileEntity; import net.minecraft.server.v1_10_R1.WorldChunkManager; @@ -393,6 +398,77 @@ public class BukkitQueue_1_10 extends BukkitQueue_0() { + @Override + public void run(Object value) { + try { + synchronized (RegionFileCache.class) { + ArrayDeque chunks = new ArrayDeque<>(); + World world = getWorld(); + world.setKeepSpawnInMemory(false); + ChunkProviderServer provider = nmsWorld.getChunkProviderServer(); + if (unload) { // Unload chunks + int bcx = (allowed.minX >> 9) << 5; + int bcz = (allowed.minZ >> 9) << 5; + int tcx = 31 + (allowed.maxX >> 9) << 5; + int tcz = 31 + (allowed.maxZ >> 9) << 5; + Iterator iter = provider.a().iterator(); + while (iter.hasNext()) { + net.minecraft.server.v1_10_R1.Chunk chunk = iter.next(); + int cx = chunk.locX; + int cz = chunk.locZ; + if (cx >= bcx && cx <= tcx && cz >= bcz && cz <= tcz) { + chunks.add(chunk); + } + } + for (net.minecraft.server.v1_10_R1.Chunk chunk : chunks) { + provider.unload(chunk); + } + boolean autoSave = world.isAutoSave(); + world.setAutoSave(true); + for (int i = 0; i < 50 && !provider.getName().endsWith(" 0"); i++) { + provider.unloadChunks(); + } + world.setAutoSave(autoSave); + } + provider.c(); + if (unload) { // Unload regions + Map map = RegionFileCache.a; + Iterator> iter = map.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + RegionFile regionFile = entry.getValue(); + regionFile.c(); + iter.remove(); + } + } + whileLocked.run(); + // Load the chunks again + if (unload) { + for (net.minecraft.server.v1_10_R1.Chunk chunk : chunks) { + chunk = provider.loadChunk(chunk.locX, chunk.locZ); + if (chunk != null) { + sendChunk(chunk, 0); + } + } + } + + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + }); + return true; + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + @Override public void sendChunk(int x, int z, int bitMask) { net.minecraft.server.v1_10_R1.Chunk chunk = getCachedChunk(getWorld(), x, z); diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java index 252f79fb..968054c2 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java @@ -7,6 +7,7 @@ import com.boydti.fawe.bukkit.v0.BukkitQueue_0; import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.brush.visualization.VisualChunk; import com.boydti.fawe.object.number.LongAdder; @@ -25,15 +26,18 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.util.ArrayDeque; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import net.minecraft.server.v1_9_R2.Block; import net.minecraft.server.v1_9_R2.BlockPosition; +import net.minecraft.server.v1_9_R2.ChunkProviderServer; import net.minecraft.server.v1_9_R2.ChunkSection; import net.minecraft.server.v1_9_R2.DataBits; import net.minecraft.server.v1_9_R2.DataPaletteBlock; @@ -53,6 +57,8 @@ import net.minecraft.server.v1_9_R2.PacketPlayOutMapChunk; import net.minecraft.server.v1_9_R2.PacketPlayOutMultiBlockChange; import net.minecraft.server.v1_9_R2.PlayerChunk; import net.minecraft.server.v1_9_R2.PlayerChunkMap; +import net.minecraft.server.v1_9_R2.RegionFile; +import net.minecraft.server.v1_9_R2.RegionFileCache; import net.minecraft.server.v1_9_R2.ServerNBTManager; import net.minecraft.server.v1_9_R2.TileEntity; import net.minecraft.server.v1_9_R2.WorldData; @@ -254,6 +260,76 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0() { + @Override + public void run(Object value) { + try { + synchronized (RegionFileCache.class) { + ArrayDeque chunks = new ArrayDeque<>(); + World world = getWorld(); + world.setKeepSpawnInMemory(false); + ChunkProviderServer provider = nmsWorld.getChunkProviderServer(); + if (unload) { // Unload chunks + int bcx = (allowed.minX >> 9) << 5; + int bcz = (allowed.minZ >> 9) << 5; + int tcx = 31 + (allowed.maxX >> 9) << 5; + int tcz = 31 + (allowed.maxZ >> 9) << 5; + Iterator iter = provider.a().iterator(); + while (iter.hasNext()) { + net.minecraft.server.v1_9_R2.Chunk chunk = iter.next(); + int cx = chunk.locX; + int cz = chunk.locZ; + if (cx >= bcx && cx <= tcx && cz >= bcz && cz <= tcz) { + chunks.add(chunk); + } + } + for (net.minecraft.server.v1_9_R2.Chunk chunk : chunks) { + provider.unload(chunk); + } + boolean autoSave = world.isAutoSave(); + world.setAutoSave(true); + for (int i = 0; i < 50 && !provider.getName().endsWith(" 0"); i++) provider.unloadChunks(); + world.setAutoSave(autoSave); + } + provider.c(); + + if (unload) { // Unload regions + Map map = RegionFileCache.a; + Iterator> iter = map.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + RegionFile regionFile = entry.getValue(); + regionFile.c(); + iter.remove(); + } + } + whileLocked.run(); + // Load the chunks again + if (unload) { + for (net.minecraft.server.v1_9_R2.Chunk chunk : chunks) { + chunk = provider.loadChunk(chunk.locX, chunk.locZ); + if (chunk != null) { + sendChunk(chunk, 0); + } + } + } + + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + }); + return true; + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + @Override public void sendChunk(int x, int z, int bitMask) { net.minecraft.server.v1_9_R2.Chunk chunk = getCachedChunk(getWorld(), x, z); diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java index 9db1986c..c331eeb3 100644 --- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java @@ -220,11 +220,11 @@ public class MCAChunk extends FaweChunk { int offsetLayer = offsetY >> 4; int startLayer = minY >> 4; int endLayer = maxY >> 4; - for (int thisLayer = startLayer + offsetLayer, otherLayer = startLayer; thisLayer < endLayer; thisLayer++, otherLayer++) { + for (int thisLayer = startLayer + offsetLayer, otherLayer = startLayer; thisLayer <= endLayer; thisLayer++, otherLayer++) { byte[] otherIds = other.ids[otherLayer]; byte[] currentIds = ids[thisLayer]; int by = otherLayer << 4; - int ty = otherLayer >> 4; + int ty = by + 15; if (by >= minY && ty <= maxY) { if (otherIds != null) { ids[thisLayer] = otherIds; @@ -337,11 +337,15 @@ public class MCAChunk extends FaweChunk { return Integer.MIN_VALUE; } + /** + * Deprecated, use the toBytes method + * @return + */ + @Deprecated public CompoundTag toTag() { if (deleted) { return null; } - // TODO optimize this as it's slow // e.g. by precalculating the length HashMap level = new HashMap(); level.put("Entities", new ListTag(CompoundTag.class, new ArrayList(entities.values()))); diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java index 27918db4..c5bdff2c 100644 --- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAFile.java @@ -517,7 +517,6 @@ public class MCAFile { written = start + newBytes.length + 5; start += newSize << 12; } - // TODO this doesn't work if (!append.isEmpty()) { for (Int2ObjectMap.Entry entry : append.int2ObjectEntrySet()) { int pair = entry.getIntKey(); @@ -531,7 +530,6 @@ public class MCAFile { written = start + bytes.length + 5; start += newSize << 12; } - } raf.setLength(4096 * ((written + 4095) / 4096)); if (raf instanceof BufferedRandomAccessFile) { diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java index 30cb0537..ce7494b5 100644 --- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueue.java @@ -180,103 +180,14 @@ public class MCAQueue extends NMSMappedFaweQueue= regionTo.minY && (toChunk.getMaxLayer() << 4) + 15 <= regionTo.maxY)) { -// mcaChunk.setLoc(null, cx, cz); -// mcaChunk.setModified(); -// mcaFile.setChunk(mcaChunk); -// } else { -// // TODO -// } -// } -// } -// } -// } -// } else if ((oY & 15) == 0) { -// -// } else { -// -// } -// } else { -// } mcaFile.close(pool); from.clear(); } } + from.clear(); pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS); } -// [17:52:49 INFO]: RegionFrom 139,3,454->139,3,454 -// [17:52:49 INFO]: 8,31 | 132>132,502>502 -// [17:52:49 INFO]: Copy from 8,28 -// [17:52:49 INFO]: 128/139,448/454 -// [17:52:49 INFO]: Set 11>15,3>3,6>15 | -11,0,-6 - - public static void main(String[] args) { - int ox = 2; - int oz = 0; - int bx = 5; - int bz = 5; - int tx = 5; - int tz = 5; - int obx = bx - ox; - int obz = bz - oz; - int otx = tx - ox; - int otz = tz - oz; - - - int otherBCX = (obx) >> 4; - int otherBCZ = (obz) >> 4; - int otherTCX = (otx) >> 4; - int otherTCZ = (otz) >> 4; - - - for (int otherCZ = otherBCZ; otherCZ <= otherTCZ; otherCZ++) { - for (int otherCX = otherBCX; otherCX <= otherTCX; otherCX++) { - - int ocbx = otherCX << 4; - int ocbz = otherCZ << 4; - int octx = obx + 15; - int octz = obz + 15; - int offsetX, offsetZ; - - int minX = obx > ocbx ? (obx - ocbx) & 15 : 0; - int maxX = otx < octx ? (otx - ocbx) : 15; - - int minZ = obz > ocbz ? (obz - ocbz) & 15 : 0; - int maxZ = otz < octz ? (otz - ocbz) : 15; - - - - - } - } - } - public > T filterRegion(final T filter, final RegionWrapper region) { this.filterWorld(new MCAFilter() { @Override diff --git a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueueMap.java b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueueMap.java index 116222b8..dc10d08d 100644 --- a/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueueMap.java +++ b/core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAQueueMap.java @@ -34,6 +34,10 @@ public class MCAQueueMap implements IFaweQueueMap { private int lastFileX = Integer.MIN_VALUE; private int lastFileZ = Integer.MIN_VALUE; + private FaweChunk lastChunk; + private int lastX = Integer.MIN_VALUE; + private int lastZ = Integer.MIN_VALUE; + public MCAFile getMCAFile(int cx, int cz) { int mcaX = cx >> 5; int mcaZ = cz >> 5; @@ -74,10 +78,6 @@ public class MCAQueueMap implements IFaweQueueMap { } } - private FaweChunk lastChunk; - private int lastX = Integer.MIN_VALUE; - private int lastZ = Integer.MIN_VALUE; - @Override public FaweChunk getFaweChunk(int cx, int cz) { if (cx == lastX && cz == lastZ) {