From 041029168f68b8a84d980570f2c797b867341e5c Mon Sep 17 00:00:00 2001 From: Aurora Date: Tue, 25 Aug 2020 20:43:07 +0200 Subject: [PATCH 1/2] Fix NMS in 1.16.2. Still not working properly. --- .../mc1_16_2/BukkitAdapter_1_16_2.java | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java index c596e12fe..4f379ffd6 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java @@ -13,6 +13,8 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; import io.papermc.lib.PaperLib; +import it.unimi.dsi.fastutil.shorts.ShortArraySet; +import it.unimi.dsi.fastutil.shorts.ShortSet; import net.jpountz.util.UnsafeUtils; import net.minecraft.server.v1_16_R2.Block; import net.minecraft.server.v1_16_R2.Chunk; @@ -35,11 +37,14 @@ import sun.misc.Unsafe; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; @@ -68,6 +73,8 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { private static final Field fieldLock; + private static final Constructor shortArraySetConstructor; + static { try { fieldSize = DataPaletteBlock.class.getDeclaredField("i"); @@ -87,9 +94,9 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount"); fieldNonEmptyBlockCount.setAccessible(true); - fieldDirtyCount = PlayerChunk.class.getDeclaredField("s"); + fieldDirtyCount = PlayerChunk.class.getDeclaredField("r"); fieldDirtyCount.setAccessible(true); - fieldDirtyBits = PlayerChunk.class.getDeclaredField("r"); + fieldDirtyBits = PlayerChunk.class.getDeclaredField("dirtyBlocks"); fieldDirtyBits.setAccessible(true); Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class); @@ -107,6 +114,8 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { if ((scale & (scale - 1)) != 0) throw new Error("data type scale not a power of two"); CHUNKSECTION_SHIFT = 31 - Integer.numberOfLeadingZeros(scale); + + shortArraySetConstructor = Class.forName(new String(new char[]{'i','t','.','u','n','i','m','i','.','d','s','i','.','f','a','s','t','u','t','i','l','.','s','h','o','r','t','s','.','S','h','o','r','t','A','r','r','a','y','S','e','t'})).getConstructor(); } catch (RuntimeException e) { throw e; } catch (Throwable rethrow) { @@ -181,18 +190,14 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { if (playerChunk.hasBeenLoaded()) { TaskManager.IMP.sync(() -> { try { - int dirtyBits = fieldDirtyBits.getInt(playerChunk); - if (dirtyBits == 0) { - nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); + Set[] dirtyblocks = (Set[]) fieldDirtyBits.get(playerChunk); + for (int i = 0; i < 16; i++) { + if (dirtyblocks[i] == null) dirtyblocks[i] = (Set) shortArraySetConstructor.newInstance(); + dirtyblocks[i].add((short) 0); + dirtyblocks[i].add((short) 1); } - if (mask == 0) { - dirtyBits = 65535; - } else { - dirtyBits |= mask; - } - - fieldDirtyBits.set(playerChunk, dirtyBits); - fieldDirtyCount.set(playerChunk, 64); + fieldDirtyBits.set(playerChunk, dirtyblocks); + nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); if (lighting) { ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); @@ -205,6 +210,10 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { } catch (IllegalAccessException e) { e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); } return null; }); From f969403b54f5442b57297897c7d51b9829f41832 Mon Sep 17 00:00:00 2001 From: Aurora Date: Wed, 26 Aug 2020 16:05:22 +0200 Subject: [PATCH 2/2] Fix NMS for Chunk Updates on 1.16.2 --- .../mc1_16_2/BukkitAdapter_1_16_2.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java index 4f379ffd6..adac97fe1 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitAdapter_1_16_2.java @@ -63,8 +63,8 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { public static final Field fieldTickingBlockCount; public static final Field fieldNonEmptyBlockCount; - private static final Field fieldDirtyCount; - private static final Field fieldDirtyBits; + private static final Field fieldDirty; + private static final Field fieldDirtyBlocks; private static final MethodHandle methodGetVisibleChunk; @@ -94,10 +94,10 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount"); fieldNonEmptyBlockCount.setAccessible(true); - fieldDirtyCount = PlayerChunk.class.getDeclaredField("r"); - fieldDirtyCount.setAccessible(true); - fieldDirtyBits = PlayerChunk.class.getDeclaredField("dirtyBlocks"); - fieldDirtyBits.setAccessible(true); + fieldDirty = PlayerChunk.class.getDeclaredField("p"); + fieldDirty.setAccessible(true); + fieldDirtyBlocks = PlayerChunk.class.getDeclaredField("dirtyBlocks"); + fieldDirtyBlocks.setAccessible(true); Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class); declaredGetVisibleChunk.setAccessible(true); @@ -190,14 +190,20 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter { if (playerChunk.hasBeenLoaded()) { TaskManager.IMP.sync(() -> { try { - Set[] dirtyblocks = (Set[]) fieldDirtyBits.get(playerChunk); + Set[] dirtyblocks = (Set[]) fieldDirtyBlocks.get(playerChunk); + if (Arrays.stream(dirtyblocks).allMatch(e -> e == null || e.isEmpty())) { + nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); + } for (int i = 0; i < 16; i++) { if (dirtyblocks[i] == null) dirtyblocks[i] = (Set) shortArraySetConstructor.newInstance(); - dirtyblocks[i].add((short) 0); - dirtyblocks[i].add((short) 1); + for (int x = 0; x < 16; x++) + for (int y = 0; y < 16; y++) + for (int z = 0; z < 16; z++) + dirtyblocks[i].add((short) ((x << 8) | (z << 4) | (y))); } - fieldDirtyBits.set(playerChunk, dirtyblocks); - nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); + + fieldDirtyBlocks.set(playerChunk, dirtyblocks); + fieldDirty.setBoolean(playerChunk, true); if (lighting) { ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);