mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-23 01:37:37 +00:00
Workaround for replacing PlayerChunkMap#visibleChunks field
I run a fork of paper which replaces the visibleChunks and updatingChunks field for gc performance reasons - visibleChunks is updated via cloning updatingChunks, and at high chunk counts this causes gc issues due to the humongous allocation. Unfortunately the only solution is to not clone the map - which is why the field is removed. Instead of BukkitAdapter#getPlayerChunk using the visibleChunks field, it now uses a MethodHandle for PlayerChunkMap#getVisibleChunk. This method is present on spigot & paper (only protected on spigot - which is why reflection is required), and I preserve the same thread-safety it provides in my fork - so this solution will not break compatibility with craftbukkit, spigot, and paper.
This commit is contained in:
parent
3a050fba3b
commit
0d18b15393
@ -12,6 +12,10 @@ import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import net.jpountz.util.UnsafeUtils;
|
||||
import net.minecraft.server.v1_15_R1.*;
|
||||
@ -40,6 +44,8 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
||||
private final static Field fieldDirtyCount;
|
||||
private final static Field fieldDirtyBits;
|
||||
|
||||
private final static MethodHandle methodGetVisibleChunk;
|
||||
|
||||
private static final int CHUNKSECTION_BASE;
|
||||
private static final int CHUNKSECTION_SHIFT;
|
||||
|
||||
@ -66,6 +72,10 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
||||
fieldDirtyBits = PlayerChunk.class.getDeclaredField("r");
|
||||
fieldDirtyBits.setAccessible(true);
|
||||
|
||||
Method declaredGetVisibleChunk = PlayerChunkMap.class.getDeclaredMethod("getVisibleChunk", long.class);
|
||||
declaredGetVisibleChunk.setAccessible(true);
|
||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(declaredGetVisibleChunk);
|
||||
|
||||
Field tmp = DataPaletteBlock.class.getDeclaredField("j");
|
||||
ReflectionUtils.setAccessibleNonFinal(tmp);
|
||||
fieldLock = tmp;
|
||||
@ -136,8 +146,11 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
||||
|
||||
public static PlayerChunk getPlayerChunk(WorldServer nmsWorld, final int cx, final int cz) {
|
||||
PlayerChunkMap chunkMap = nmsWorld.getChunkProvider().playerChunkMap;
|
||||
PlayerChunk playerChunk = chunkMap.visibleChunks.get(ChunkCoordIntPair.pair(cx, cz));
|
||||
return playerChunk;
|
||||
try {
|
||||
return (PlayerChunk)methodGetVisibleChunk.invoke(chunkMap, ChunkCoordIntPair.pair(cx, cz));
|
||||
} catch (Throwable thr) {
|
||||
throw new RuntimeException(thr);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendChunk(WorldServer nmsWorld, int X, int Z, int mask) {
|
||||
|
Loading…
Reference in New Issue
Block a user