diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index c88b70609..d41a97e73 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -23,7 +23,6 @@ import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.type.NoteBlock; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java index 3f24226df..388f70160 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java @@ -9,7 +9,10 @@ import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy; import net.bytebuddy.implementation.FieldAccessor; import net.bytebuddy.implementation.FixedValue; import net.bytebuddy.implementation.MethodDelegation; -import net.bytebuddy.implementation.bind.annotation.*; +import net.bytebuddy.implementation.bind.annotation.AllArguments; +import net.bytebuddy.implementation.bind.annotation.RuntimeType; +import net.bytebuddy.implementation.bind.annotation.SuperCall; +import net.bytebuddy.implementation.bind.annotation.This; import net.bytebuddy.matcher.ElementMatchers; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.block.BukkitBlockShape; @@ -48,6 +51,7 @@ import org.jetbrains.annotations.Nullable; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.lang.invoke.VarHandle; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.List; @@ -62,6 +66,8 @@ public class BukkitInjector { private static Class clazz$InjectedPalettedContainer; + private static VarHandle varHandle$InjectedPalettedContainer$target; + private static Class clazz$OptimizedItemDisplay; private static Constructor constructor$OptimizedItemDisplay; @@ -83,10 +89,10 @@ public class BukkitInjector { .subclass(Reflections.clazz$PalettedContainer) .name("net.minecraft.world.level.chunk.InjectedPalettedContainer") .implement(InjectedPalettedContainerHolder.class) - .defineField("target", Object.class, Visibility.PUBLIC) - .defineField("cesection", CESection.class, Visibility.PUBLIC) - .defineField("ceworld", CEWorld.class, Visibility.PUBLIC) - .defineField("cepos", SectionPos.class, Visibility.PUBLIC) + .defineField("target", Reflections.clazz$PalettedContainer, Visibility.PRIVATE) + .defineField("cesection", CESection.class, Visibility.PRIVATE) + .defineField("ceworld", CEWorld.class, Visibility.PRIVATE) + .defineField("cepos", SectionPos.class, Visibility.PRIVATE) .method(ElementMatchers.any() .and(ElementMatchers.not(ElementMatchers.is(Reflections.method$PalettedContainer$getAndSet))) .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(Object.class))) @@ -105,6 +111,9 @@ public class BukkitInjector { .make() .load(BukkitInjector.class.getClassLoader()) .getLoaded(); + + varHandle$InjectedPalettedContainer$target = Objects.requireNonNull(ReflectionUtils.findVarHandle(clazz$InjectedPalettedContainer, "target", Reflections.clazz$PalettedContainer)); + // State Predicate DynamicType.Unloaded alwaysTrue = byteBuddy .subclass(Reflections.clazz$StatePredicate) @@ -311,11 +320,11 @@ public class BukkitInjector { Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection); if (!clazz$InjectedPalettedContainer.isInstance(container)) { InjectedPalettedContainerHolder injectedObject = (InjectedPalettedContainerHolder) Reflections.UNSAFE.allocateInstance(clazz$InjectedPalettedContainer); - injectedObject.target(container); + varHandle$InjectedPalettedContainer$target.set(injectedObject, container); injectedObject.ceSection(ceSection); injectedObject.ceWorld(ceWorld); injectedObject.cePos(pos); - Reflections.field$PalettedContainer$data.set(injectedObject, Reflections.field$PalettedContainer$data.get(container)); + Reflections.varHandle$PalettedContainer$data.setVolatile(injectedObject, Reflections.varHandle$PalettedContainer$data.get(container)); Reflections.field$LevelChunkSection$states.set(targetSection, injectedObject); } } catch (Exception e) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java index 332f66dbf..0cdb7db6e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockStateUtils.java @@ -11,7 +11,6 @@ import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.event.block.BlockPhysicsEvent; -import java.lang.reflect.InvocationTargetException; import java.util.IdentityHashMap; import java.util.List; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index aa0a81585..3c84df190 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.Nullable; import sun.misc.Unsafe; import java.io.BufferedReader; +import java.lang.invoke.VarHandle; import java.lang.reflect.*; import java.time.Instant; import java.util.*; @@ -1679,6 +1680,10 @@ public class Reflections { ) ); + public static final VarHandle varHandle$PalettedContainer$data = requireNonNull( + ReflectionUtils.findVarHandle(field$PalettedContainer$data) + ); + public static final Field field$PalettedContainer$Data$storage = requireNonNull( ReflectionUtils.getDeclaredField( clazz$PalettedContainer$Data, clazz$BitStorage, 0 diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java index eb4f7653f..8248c227f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java @@ -253,7 +253,7 @@ public class BukkitWorldManager implements WorldManager, Listener { Object section = sections[i]; if (ConfigManager.syncCustomBlocks()) { Object statesContainer = FastNMS.INSTANCE.field$LevelChunkSection$states(section); - Object data = Reflections.field$PalettedContainer$data.get(statesContainer); + Object data = Reflections.varHandle$PalettedContainer$data.get(statesContainer); Object palette = Reflections.field$PalettedContainer$Data$palette.get(data); boolean requiresSync = false; if (Reflections.clazz$SingleValuePalette.isInstance(palette)) { diff --git a/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java b/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java index 1eb473f1a..90a2b995d 100644 --- a/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java +++ b/client-mod/src/main/java/net/momirealms/craftengine/fabric/CraftEngineFabricMod.java @@ -3,7 +3,6 @@ package net.momirealms.craftengine.fabric; import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.block.BlockState; -import net.minecraft.block.piston.PistonBehavior; import net.minecraft.util.Identifier; import net.momirealms.craftengine.fabric.client.config.ModConfig; import net.momirealms.craftengine.fabric.util.BlockUtils; diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java index 28f2b5822..f83302bab 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java @@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; import java.lang.reflect.*; import java.util.ArrayList; import java.util.Arrays; @@ -467,4 +468,22 @@ public class ReflectionUtils { return LOOKUP.unreflect(method); } } + + public static VarHandle findVarHandle(Class clazz, String name, Class type) { + try { + return MethodHandles.privateLookupIn(clazz, LOOKUP) + .findVarHandle(clazz, name, type); + } catch (NoSuchFieldException | SecurityException | IllegalAccessException e) { + return null; + } + } + + public static VarHandle findVarHandle(Field field) { + try { + return MethodHandles.privateLookupIn(field.getDeclaringClass(), LOOKUP) + .findVarHandle(field.getDeclaringClass(), field.getName(), field.getType()); + } catch (IllegalAccessException | NoSuchFieldException e) { + return null; + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedPalettedContainerHolder.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedPalettedContainerHolder.java index 0dc9d1db8..a5cbc6e31 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedPalettedContainerHolder.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedPalettedContainerHolder.java @@ -7,8 +7,6 @@ public interface InjectedPalettedContainerHolder { Object target(); - void target(Object target); - CESection ceSection(); void ceSection(CESection section); diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java index 134ce71e2..54effc4b0 100644 --- a/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/CraftEngineBlock.java @@ -10,15 +10,16 @@ import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.ScheduledTickAccess; -import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.BonemealableBlock; +import net.minecraft.world.level.block.Fallable; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import net.momirealms.craftengine.mod.util.NoteBlockUtils; import net.momirealms.craftengine.shared.ObjectHolder; import net.momirealms.craftengine.shared.block.*; -import org.bukkit.craftbukkit.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; import org.jetbrains.annotations.NotNull; public class CraftEngineBlock