fix: use servers removeGameEventListener instead of reimpl (#1881)

* fix: use servers removeGameEventListener instead of reimpl

* fix: 1.18.2 impl
This commit is contained in:
peaches 2022-07-25 11:49:10 -05:00 committed by GitHub
parent a1babd5ec9
commit 77a929f6a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 45 deletions

View File

@ -99,7 +99,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final Field fieldLock; private static final Field fieldLock;
private static final long fieldLockOffset; private static final long fieldLockOffset;
private static final Field fieldGameEventDispatcherSections; private static final MethodHandle methodRemoveGameEventListener;
private static final MethodHandle methodremoveTickingBlockEntity; private static final MethodHandle methodremoveTickingBlockEntity;
private static final Field fieldRemove; private static final Field fieldRemove;
@ -148,9 +148,12 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldLockOffset = -1; fieldLockOffset = -1;
} }
fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName( Method removeGameEventListener = LevelChunk.class.getDeclaredMethod(
"gameEventDispatcherSections", "t")); Refraction.pickName("removeGameEventListener", "d"),
fieldGameEventDispatcherSections.setAccessible(true); BlockEntity.class
);
removeGameEventListener.setAccessible(true);
methodRemoveGameEventListener = MethodHandles.lookup().unreflect(removeGameEventListener);
Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod(
Refraction.pickName( Refraction.pickName(
"removeBlockEntityTicker", "removeBlockEntityTicker",
@ -573,23 +576,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos());
if (blockEntity != null) { if (blockEntity != null) {
if (!levelChunk.level.isClientSide) { if (!levelChunk.level.isClientSide) {
Block block = beacon.getBlockState().getBlock(); methodRemoveGameEventListener.invoke(levelChunk, beacon);
if (block instanceof EntityBlock) {
GameEventListener gameEventListener = ((EntityBlock) block).getListener(levelChunk.level, beacon);
if (gameEventListener != null) {
int i = SectionPos.blockToSectionCoord(beacon.getBlockPos().getY());
GameEventDispatcher gameEventDispatcher = levelChunk.getEventDispatcher(i);
gameEventDispatcher.unregister(gameEventListener);
if (gameEventDispatcher.isEmpty()) {
try {
((Int2ObjectMap<GameEventDispatcher>) fieldGameEventDispatcherSections.get(levelChunk))
.remove(i);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
} }
fieldRemove.set(beacon, true); fieldRemove.set(beacon, true);
} }

View File

@ -62,6 +62,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -99,7 +101,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final Field fieldLock; private static final Field fieldLock;
private static final long fieldLockOffset; private static final long fieldLockOffset;
private static final Field fieldGameEventDispatcherSections; private static final MethodHandle methodRemoveGameEventListener;
private static final MethodHandle methodremoveTickingBlockEntity; private static final MethodHandle methodremoveTickingBlockEntity;
private static final Field fieldRemove; private static final Field fieldRemove;
@ -148,9 +150,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldLockOffset = -1; fieldLockOffset = -1;
} }
fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName( Method removeGameEventListener = LevelChunk.class.getDeclaredMethod(
"gameEventDispatcherSections", "t")); Refraction.pickName("removeGameEventListener", "a"),
fieldGameEventDispatcherSections.setAccessible(true); BlockEntity.class,
ServerLevel.class
);
removeGameEventListener.setAccessible(true);
methodRemoveGameEventListener = MethodHandles.lookup().unreflect(removeGameEventListener);
Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod(
Refraction.pickName( Refraction.pickName(
"removeBlockEntityTicker", "removeBlockEntityTicker",
@ -564,32 +571,13 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString());
} }
@SuppressWarnings("unchecked")
static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) {
try { try {
// Do the method ourselves to avoid trying to reflect generic method parameters
// similar to removeGameEventListener
if (levelChunk.loaded || levelChunk.level.isClientSide()) { if (levelChunk.loaded || levelChunk.level.isClientSide()) {
BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos());
if (blockEntity != null) { if (blockEntity != null) {
if (!levelChunk.level.isClientSide) { if (!levelChunk.level.isClientSide) {
Block block = beacon.getBlockState().getBlock(); methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level);
if (block instanceof EntityBlock) {
GameEventListener gameEventListener = ((EntityBlock) block).getListener(levelChunk.level, beacon);
if (gameEventListener != null) {
int i = SectionPos.blockToSectionCoord(beacon.getBlockPos().getY());
GameEventDispatcher gameEventDispatcher = levelChunk.getEventDispatcher(i);
gameEventDispatcher.unregister(gameEventListener);
if (gameEventDispatcher.isEmpty()) {
try {
((Int2ObjectMap<GameEventDispatcher>) fieldGameEventDispatcherSections.get(levelChunk))
.remove(i);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
} }
fieldRemove.set(beacon, true); fieldRemove.set(beacon, true);
} }