diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java index 901a741ae..9127b6c7b 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java @@ -39,10 +39,10 @@ import java.util.*; import static java.util.Objects.requireNonNull; public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { + private static int[] ordinalToIbdID; private final Set chunksToSave; private final CEWorld ceWorld; - private static int[] ordinalToIbdID; - private static final Set BROKEN_CHUNKS = Collections.synchronizedSet(new HashSet<>()); + private final Set brokenChunks = Collections.synchronizedSet(new HashSet<>()); protected FastAsyncWorldEditDelegate(EditSessionEvent event) { super(event.getExtent()); @@ -85,7 +85,9 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { for (int i = 0; i < ceSections.length; i++) { CESection ceSection = ceSections[i]; Object section = sections[i]; - BukkitInjector.injectLevelChunkSection(section, ceSection, ceChunk, new SectionPos(pos.x, ceChunk.sectionY(i), pos.z)); + int finalI = i; + BukkitInjector.injectLevelChunkSection(section, ceSection, ceChunk, new SectionPos(pos.x, ceChunk.sectionY(i), pos.z), + (injected) -> sections[finalI] = injected); } } } @@ -143,8 +145,8 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { @Override protected Operation commitBefore() { saveAllChunks(); - List chunks = new ArrayList<>(BROKEN_CHUNKS); - BROKEN_CHUNKS.clear(); + List chunks = new ArrayList<>(this.brokenChunks); + this.brokenChunks.clear(); Object worldServer = this.ceWorld.world().serverWorld(); Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(worldServer); for (ChunkPos chunk : chunks) { @@ -172,7 +174,7 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { int chunkZ = blockZ >> 4; int newStateId = ordinalToIbdID[newBlock.getOrdinal()]; int oldStateId = ordinalToIbdID[oldBlock.getOrdinal()]; - BROKEN_CHUNKS.add(ChunkPos.of(chunkX, chunkZ)); + this.brokenChunks.add(ChunkPos.of(chunkX, chunkZ)); //CraftEngine.instance().debug(() -> "Processing block at " + blockX + ", " + blockY + ", " + blockZ + ": " + oldStateId + " -> " + newStateId); if (BlockStateUtils.isVanillaBlock(newStateId) && BlockStateUtils.isVanillaBlock(oldStateId)) return; try { diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index c4d0b734f..b25083cec 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -353,8 +353,15 @@ chunk-system: # 4 = LZ4 | Blazing-Fast Blazing-Fast Low Low | # 5 = ZSTD | Medium-Fast Fast High Medium | compression-method: 4 - # This might not work for some server forks that modify how Minecraft saves chunks. - fast-palette-injection: false + # Settings for injection + injection: + # Requires a restart to apply + # SECTION: Inject the LevelChunkSection (Faster, but may conflict with some plugins) + # PALETTE: Inject the PalettedContainer + target: PALETTE + # Enables faster injection method + # Note: May not work with certain server forks that alter chunk saving behavior + use-fast-method: false # Auto-convert custom blocks -> vanilla blocks when unloading chunks # # - When ENABLED (true): 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 501519f00..0bb780dd4 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 @@ -51,7 +51,7 @@ import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.SectionPos; import net.momirealms.craftengine.core.world.chunk.CEChunk; import net.momirealms.craftengine.core.world.chunk.CESection; -import net.momirealms.craftengine.core.world.chunk.InjectedPalettedContainerHolder; +import net.momirealms.craftengine.core.world.chunk.InjectedHolder; import net.momirealms.craftengine.shared.ObjectHolder; import net.momirealms.craftengine.shared.block.*; import org.bukkit.inventory.ItemStack; @@ -69,12 +69,14 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.Callable; +import java.util.function.Consumer; public class BukkitInjector { private static final ByteBuddy byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V17); private static final BukkitBlockShape STONE_SHAPE = new BukkitBlockShape(Reflections.instance$Blocks$STONE$defaultState); private static Class clazz$InjectedPalettedContainer; + private static Class clazz$InjectedLevelChunkSection; private static VarHandle varHandle$InjectedPalettedContainer$target; @@ -100,17 +102,14 @@ public class BukkitInjector { clazz$InjectedPalettedContainer = byteBuddy .subclass(Reflections.clazz$PalettedContainer) .name("net.minecraft.world.level.chunk.InjectedPalettedContainer") - .implement(InjectedPalettedContainerHolder.class) - .defineField("target", Reflections.clazz$PalettedContainer, Visibility.PRIVATE) - .defineField("ceworld", CEWorld.class, Visibility.PRIVATE) + .implement(InjectedHolder.Palette.class) + .defineField("target", Reflections.clazz$PalettedContainer, Visibility.PUBLIC) .defineField("cesection", CESection.class, Visibility.PRIVATE) .defineField("cechunk", CEChunk.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))) - // TODO Requires Paper Patch - //.and(ElementMatchers.not(ElementMatchers.named("get").and(ElementMatchers.takesArguments(int.class)).and(ElementMatchers.returns(Object.class)))) ) .intercept(MethodDelegation.toField("target")) .method(ElementMatchers.is(Reflections.method$PalettedContainer$getAndSet)) @@ -121,16 +120,33 @@ public class BukkitInjector { .intercept(FieldAccessor.ofField("cesection")) .method(ElementMatchers.named("ceChunk")) .intercept(FieldAccessor.ofField("cechunk")) - .method(ElementMatchers.named("ceWorld")) - .intercept(FieldAccessor.ofField("ceworld")) .method(ElementMatchers.named("cePos")) .intercept(FieldAccessor.ofField("cepos")) .make() .load(BukkitInjector.class.getClassLoader()) .getLoaded(); - varHandle$InjectedPalettedContainer$target = Objects.requireNonNull(ReflectionUtils.findVarHandle(clazz$InjectedPalettedContainer, "target", Reflections.clazz$PalettedContainer)); + // Level Chunk Section + clazz$InjectedLevelChunkSection = byteBuddy + .subclass(Reflections.clazz$LevelChunkSection) + .name("net.minecraft.world.level.chunk.InjectedLevelChunkSection") + .implement(InjectedHolder.Section.class) + .defineField("cesection", CESection.class, Visibility.PRIVATE) + .defineField("cechunk", CEChunk.class, Visibility.PRIVATE) + .defineField("cepos", SectionPos.class, Visibility.PRIVATE) + .method(ElementMatchers.is(Reflections.method$LevelChunkSection$setBlockState)) + .intercept(MethodDelegation.to(SetBlockStateInterceptor.INSTANCE)) + .method(ElementMatchers.named("ceSection")) + .intercept(FieldAccessor.ofField("cesection")) + .method(ElementMatchers.named("ceChunk")) + .intercept(FieldAccessor.ofField("cechunk")) + .method(ElementMatchers.named("cePos")) + .intercept(FieldAccessor.ofField("cepos")) + .make() + .load(BukkitInjector.class.getClassLoader()) + .getLoaded(); + // State Predicate DynamicType.Unloaded alwaysTrue = byteBuddy .subclass(Reflections.clazz$StatePredicate) @@ -388,23 +404,33 @@ public class BukkitInjector { // } // } - public synchronized static void injectLevelChunkSection(Object targetSection, CESection ceSection, CEChunk chunk, SectionPos pos) { + public synchronized static void injectLevelChunkSection(Object targetSection, CESection ceSection, CEChunk chunk, SectionPos pos, Consumer callback) { try { - Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection); - if (!(container instanceof InjectedPalettedContainerHolder)) { - InjectedPalettedContainerHolder injectedObject; - if (Config.fastPaletteInjection()) { - injectedObject = FastNMS.INSTANCE.createInjectedPalettedContainerHolder(container); - } else { - injectedObject = (InjectedPalettedContainerHolder) Reflections.UNSAFE.allocateInstance(clazz$InjectedPalettedContainer); - varHandle$InjectedPalettedContainer$target.set(injectedObject, container); + if (Config.injectionTarget()) { + Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection); + if (!(container instanceof InjectedHolder.Palette)) { + InjectedHolder.Palette injectedObject; + if (Config.fastInjection()) { + injectedObject = FastNMS.INSTANCE.createInjectedPalettedContainerHolder(container); + } else { + injectedObject = (InjectedHolder.Palette) Reflections.UNSAFE.allocateInstance(clazz$InjectedPalettedContainer); + varHandle$InjectedPalettedContainer$target.set(injectedObject, container); + } + injectedObject.ceChunk(chunk); + injectedObject.ceSection(ceSection); + injectedObject.cePos(pos); + Reflections.varHandle$PalettedContainer$data.setVolatile(injectedObject, Reflections.varHandle$PalettedContainer$data.get(container)); + Reflections.field$LevelChunkSection$states.set(targetSection, injectedObject); + } + } else { + InjectedHolder.Section injectedObject; + if (true) { + injectedObject = FastNMS.INSTANCE.createInjectedLevelChunkSectionHolder(targetSection); } - injectedObject.ceWorld(chunk.world()); injectedObject.ceChunk(chunk); injectedObject.ceSection(ceSection); injectedObject.cePos(pos); - Reflections.varHandle$PalettedContainer$data.setVolatile(injectedObject, Reflections.varHandle$PalettedContainer$data.get(container)); - Reflections.field$LevelChunkSection$states.set(targetSection, injectedObject); + callback.accept(injectedObject); } } catch (Exception e) { CraftEngine.instance().logger().severe("Failed to inject chunk section", e); @@ -412,19 +438,30 @@ public class BukkitInjector { } public static boolean isSectionInjected(Object section) { - Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(section); - return container instanceof InjectedPalettedContainerHolder; + if (Config.injectionTarget()) { + Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(section); + return container instanceof InjectedHolder.Palette; + } else { + return section instanceof InjectedHolder.Section; + } } - public synchronized static void uninjectLevelChunkSection(Object section) { - try { + public synchronized static Object uninjectLevelChunkSection(Object section) { + if (Config.injectionTarget()) { Object states = FastNMS.INSTANCE.field$LevelChunkSection$states(section); - if (states instanceof InjectedPalettedContainerHolder holder) { - Reflections.field$LevelChunkSection$states.set(section, holder.target()); + if (states instanceof InjectedHolder.Palette holder) { + try { + Reflections.field$LevelChunkSection$states.set(section, holder.target()); + } catch (ReflectiveOperationException e) { + CraftEngine.instance().logger().severe("Failed to uninject palette", e); + } + } + } else { + if (section instanceof InjectedHolder.Section holder) { + return FastNMS.INSTANCE.constructor$LevelChunkSection(holder); } - } catch (ReflectiveOperationException e) { - CraftEngine.instance().logger().severe("Failed to inject chunk section", e); } + return section; } public static class GetRecipeForMethodInterceptor1_20 { @@ -682,58 +719,78 @@ public class BukkitInjector { } } + public static class SetBlockStateInterceptor { + public static final SetBlockStateInterceptor INSTANCE = new SetBlockStateInterceptor(); + + @RuntimeType + public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable superMethod) throws Exception { + InjectedHolder.Section holder = (InjectedHolder.Section) thisObj; + int x = (int) args[0]; + int y = (int) args[1]; + int z = (int) args[2]; + Object newState = args[3]; + Object previousState = superMethod.call(); + compareAndUpdateBlockState(x, y, z, newState, previousState, holder); + return previousState; + } + } + public static class GetAndSetInterceptor { public static final GetAndSetInterceptor INSTANCE = new GetAndSetInterceptor(); @RuntimeType public Object intercept(@This Object thisObj, @AllArguments Object[] args) { - InjectedPalettedContainerHolder holder = (InjectedPalettedContainerHolder) thisObj; + InjectedHolder.Palette holder = (InjectedHolder.Palette) thisObj; Object targetStates = holder.target(); int x = (int) args[0]; int y = (int) args[1]; int z = (int) args[2]; - Object previousState = FastNMS.INSTANCE.method$PalettedContainer$getAndSet(targetStates, x, y, z, args[3]); - try { - Object newState = args[3]; - int stateId = BlockStateUtils.blockStateToId(newState); - CESection section = holder.ceSection(); - // 如果是原版方块 - if (BlockStateUtils.isVanillaBlock(stateId)) { - // 那么应该情况自定义块 - ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE); - // 如果先前不是空气则标记 - if (!previous.isEmpty()) { - holder.ceChunk().setDirty(true); - } - if (Config.enableLightSystem() && Config.forceUpdateLight()) { - updateLightIfChanged(holder, previousState, newState, null, y, z, x); - } - } else { - ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); - ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState); - // 如果之前的自定义块(空气)和当前自定义块不同 - if (previousImmutableBlockState != immutableBlockState) { - holder.ceChunk().setDirty(true); - if (Config.enableLightSystem() && !immutableBlockState.isEmpty()) { - updateLightIfChanged(holder, previousState, newState, immutableBlockState.vanillaBlockState().handle(), y, z, x); - } - } - } - } catch (Exception e) { - CraftEngine.instance().logger().warn("Failed to intercept setBlockState", e); - } + Object newState = args[3]; + Object previousState = FastNMS.INSTANCE.method$PalettedContainer$getAndSet(targetStates, x, y, z, newState); + compareAndUpdateBlockState(x, y, z, newState, previousState, holder); return previousState; } + } - private void updateLightIfChanged(@This InjectedPalettedContainerHolder thisObj, Object previousBlockState, Object newState, @Nullable Object clientSideNewState, int y, int z, int x) throws ReflectiveOperationException { - int previousLight = BlockStateUtils.getLightEmission(previousBlockState); - int newLight = BlockStateUtils.getLightEmission(newState); - if (previousLight != newLight || (clientSideNewState != null && (BlockStateUtils.isOcclude(newState) != BlockStateUtils.isOcclude(clientSideNewState)))) { - CEWorld world = thisObj.ceWorld(); - SectionPos sectionPos = thisObj.cePos(); - Set posSet = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, Math.max(newLight, previousLight)); - world.sectionLightUpdated(posSet); + protected static void compareAndUpdateBlockState(int x, int y, int z, Object newState, Object previousState, InjectedHolder holder) { + try { + int stateId = BlockStateUtils.blockStateToId(newState); + CESection section = holder.ceSection(); + // 如果是原版方块 + if (BlockStateUtils.isVanillaBlock(stateId)) { + // 那么应该情况自定义块 + ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE); + // 如果先前不是空气则标记 + if (!previous.isEmpty()) { + holder.ceChunk().setDirty(true); + } + if (Config.enableLightSystem() && Config.forceUpdateLight()) { + updateLightIfChanged(holder, previousState, newState, null, y, z, x); + } + } else { + ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); + ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState); + // 如果之前的自定义块(空气)和当前自定义块不同 + if (previousImmutableBlockState != immutableBlockState) { + holder.ceChunk().setDirty(true); + if (Config.enableLightSystem() && !immutableBlockState.isEmpty()) { + updateLightIfChanged(holder, previousState, newState, immutableBlockState.vanillaBlockState().handle(), y, z, x); + } + } } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to intercept setBlockState", e); + } + } + + protected static void updateLightIfChanged(@This InjectedHolder thisObj, Object previousBlockState, Object newState, @Nullable Object clientSideNewState, int y, int z, int x) throws ReflectiveOperationException { + int previousLight = BlockStateUtils.getLightEmission(previousBlockState); + int newLight = BlockStateUtils.getLightEmission(newState); + if (previousLight != newLight || (clientSideNewState != null && (BlockStateUtils.isOcclude(newState) != BlockStateUtils.isOcclude(clientSideNewState)))) { + CEWorld world = thisObj.ceChunk().world(); + SectionPos sectionPos = thisObj.cePos(); + Set posSet = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, Math.max(newLight, previousLight)); + world.sectionLightUpdated(posSet); } } 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 85165e2e5..ed7918dd2 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 @@ -1928,7 +1928,6 @@ public class Reflections { // field$ChunkAccess$blockEntities = targetField; // } - @Deprecated public static final Method method$LevelChunkSection$setBlockState = requireNonNull( ReflectionUtils.getMethod( clazz$LevelChunkSection, clazz$BlockState, int.class, int.class, int.class, clazz$BlockState, boolean.class 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 e6bd597df..ffc0b77bf 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 @@ -282,7 +282,11 @@ public class BukkitWorldManager implements WorldManager, Listener { for (int i = 0; i < ceSections.length; i++) { CESection ceSection = ceSections[i]; Object section = sections[i]; - BukkitInjector.uninjectLevelChunkSection(section); + Object uninjectedSection = BukkitInjector.uninjectLevelChunkSection(section); + if (uninjectedSection != section) { + sections[i] = uninjectedSection; + section = uninjectedSection; + } if (!ceSection.statesContainer().isEmpty()) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { @@ -383,7 +387,9 @@ public class BukkitWorldManager implements WorldManager, Listener { } } } - BukkitInjector.injectLevelChunkSection(section, ceSection, ceChunk, new SectionPos(pos.x, ceChunk.sectionY(i), pos.z)); + int finalI = i; + BukkitInjector.injectLevelChunkSection(section, ceSection, ceChunk, new SectionPos(pos.x, ceChunk.sectionY(i), pos.z), + (injected) -> sections[finalI] = injected); } if (Config.enableRecipeSystem()) { @SuppressWarnings("unchecked") diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index be4757d67..e595457bf 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -23,6 +23,7 @@ import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.MiscUtils; import net.momirealms.craftengine.core.util.ReflectionUtils; +import net.momirealms.craftengine.core.world.InjectionTarget; import net.momirealms.craftengine.core.world.chunk.storage.CompressionMethod; import java.io.File; @@ -46,6 +47,7 @@ public class Config { private final String configVersion; private YamlDocument config; + protected boolean firstTime = true; protected boolean debug; protected boolean checkUpdate; protected boolean metrics; @@ -100,7 +102,8 @@ public class Config { protected boolean chunk_system$restore_custom_blocks_on_chunk_load; protected boolean chunk_system$sync_custom_blocks_on_chunk_load; protected int chunk_system$delay_serialization; - protected boolean chunk_system$fast_paletted_injection; + protected boolean chunk_system$injection$use_fast_method; + protected boolean chunk_system$injection$target; protected boolean furniture$handle_invalid_furniture_on_chunk_load$enable; protected Map furniture$handle_invalid_furniture_on_chunk_load$mapping; @@ -272,7 +275,10 @@ public class Config { chunk_system$restore_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.restore-custom-blocks-on-chunk-load", true); chunk_system$sync_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.sync-custom-blocks-on-chunk-load", false); chunk_system$delay_serialization = config.getInt("chunk-system.delay-serialization", 20); - chunk_system$fast_paletted_injection = config.getBoolean("chunk-system.fast-palette-injection", false); + chunk_system$injection$use_fast_method = config.getBoolean("chunk-system.injection.use-fast-method", false); + if (firstTime) { + chunk_system$injection$target = config.getEnum("chunk-system.injection.target", InjectionTarget.class, InjectionTarget.PALETTE) == InjectionTarget.PALETTE; + } // furniture furniture$handle_invalid_furniture_on_chunk_load$enable = config.getBoolean("furniture.handle-invalid-furniture-on-chunk-load.enable", false); @@ -342,6 +348,8 @@ public class Config { plugin.logger().warn("Failed to set max chain update", e); } } + + firstTime = false; } private static float getVersion(String version) { @@ -695,8 +703,12 @@ public class Config { return instance.chunk_system$delay_serialization; } - public static boolean fastPaletteInjection() { - return instance.chunk_system$fast_paletted_injection; + public static boolean fastInjection() { + return instance.chunk_system$injection$use_fast_method; + } + + public static boolean injectionTarget() { + return instance.chunk_system$injection$target; } public YamlDocument loadOrCreateYamlData(String fileName) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/InjectionTarget.java b/core/src/main/java/net/momirealms/craftengine/core/world/InjectionTarget.java new file mode 100644 index 000000000..35149a464 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/world/InjectionTarget.java @@ -0,0 +1,6 @@ +package net.momirealms.craftengine.core.world; + +public enum InjectionTarget { + SECTION, + PALETTE +} 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/InjectedHolder.java similarity index 62% rename from core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedPalettedContainerHolder.java rename to core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedHolder.java index f8d67784d..a625a0a47 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/InjectedHolder.java @@ -1,11 +1,8 @@ package net.momirealms.craftengine.core.world.chunk; -import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.SectionPos; -public interface InjectedPalettedContainerHolder { - - Object target(); +public interface InjectedHolder { CESection ceSection(); @@ -15,11 +12,15 @@ public interface InjectedPalettedContainerHolder { void ceChunk(CEChunk chunk); - CEWorld ceWorld(); - - void ceWorld(CEWorld world); - SectionPos cePos(); void cePos(SectionPos pos); + + interface Section extends InjectedHolder { + } + + interface Palette extends InjectedHolder { + + Object target(); + } } diff --git a/gradle.properties b/gradle.properties index 980c2704a..3bb3ebc45 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,8 +2,8 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.53-beta.4 -config_version=31 +project_version=0.0.53-beta.6 +config_version=32 lang_version=12 project_group=net.momirealms latest_supported_version=1.21.5 @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.15 -nms_helper_version=0.64.6 +nms_helper_version=0.65.11 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23