Merge pull request #585 from aurorasmiles/fixnms

Fixes NMS on 1.16.2
Dieser Commit ist enthalten in:
NotMyFault 2020-08-26 16:24:37 +02:00 committet von GitHub
Commit 32ee30d593
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23

Datei anzeigen

@ -13,6 +13,8 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib; 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.jpountz.util.UnsafeUtils;
import net.minecraft.server.v1_16_R2.Block; import net.minecraft.server.v1_16_R2.Block;
import net.minecraft.server.v1_16_R2.Chunk; 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.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function; import java.util.function.Function;
@ -58,8 +63,8 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
public static final Field fieldTickingBlockCount; public static final Field fieldTickingBlockCount;
public static final Field fieldNonEmptyBlockCount; public static final Field fieldNonEmptyBlockCount;
private static final Field fieldDirtyCount; private static final Field fieldDirty;
private static final Field fieldDirtyBits; private static final Field fieldDirtyBlocks;
private static final MethodHandle methodGetVisibleChunk; private static final MethodHandle methodGetVisibleChunk;
@ -68,6 +73,8 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
private static final Field fieldLock; private static final Field fieldLock;
private static final Constructor shortArraySetConstructor;
static { static {
try { try {
fieldSize = DataPaletteBlock.class.getDeclaredField("i"); fieldSize = DataPaletteBlock.class.getDeclaredField("i");
@ -87,10 +94,10 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount"); fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
fieldNonEmptyBlockCount.setAccessible(true); fieldNonEmptyBlockCount.setAccessible(true);
fieldDirtyCount = PlayerChunk.class.getDeclaredField("s"); fieldDirty = PlayerChunk.class.getDeclaredField("p");
fieldDirtyCount.setAccessible(true); fieldDirty.setAccessible(true);
fieldDirtyBits = PlayerChunk.class.getDeclaredField("r"); fieldDirtyBlocks = PlayerChunk.class.getDeclaredField("dirtyBlocks");
fieldDirtyBits.setAccessible(true); fieldDirtyBlocks.setAccessible(true);
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class); Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
declaredGetVisibleChunk.setAccessible(true); declaredGetVisibleChunk.setAccessible(true);
@ -107,6 +114,8 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
if ((scale & (scale - 1)) != 0) if ((scale & (scale - 1)) != 0)
throw new Error("data type scale not a power of two"); throw new Error("data type scale not a power of two");
CHUNKSECTION_SHIFT = 31 - Integer.numberOfLeadingZeros(scale); 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) { } catch (RuntimeException e) {
throw e; throw e;
} catch (Throwable rethrow) { } catch (Throwable rethrow) {
@ -181,18 +190,20 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
if (playerChunk.hasBeenLoaded()) { if (playerChunk.hasBeenLoaded()) {
TaskManager.IMP.sync(() -> { TaskManager.IMP.sync(() -> {
try { try {
int dirtyBits = fieldDirtyBits.getInt(playerChunk); Set<Short>[] dirtyblocks = (Set<Short>[]) fieldDirtyBlocks.get(playerChunk);
if (dirtyBits == 0) { if (Arrays.stream(dirtyblocks).allMatch(e -> e == null || e.isEmpty())) {
nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk); nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk);
} }
if (mask == 0) { for (int i = 0; i < 16; i++) {
dirtyBits = 65535; if (dirtyblocks[i] == null) dirtyblocks[i] = (Set<Short>) shortArraySetConstructor.newInstance();
} else { for (int x = 0; x < 16; x++)
dirtyBits |= mask; 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, dirtyBits); fieldDirtyBlocks.set(playerChunk, dirtyblocks);
fieldDirtyCount.set(playerChunk, 64); fieldDirty.setBoolean(playerChunk, true);
if (lighting) { if (lighting) {
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ); ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);
@ -205,6 +216,10 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} }
return null; return null;
}); });