diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index 7958debae..49515e11d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -140,8 +140,8 @@ public class BukkitBlockManager extends AbstractBlockManager { this.appearanceToRealState.clear(); this.blockStateOverrides.clear(); this.modBlockStates.clear(); - if (EmptyBlock.INSTANCE != null) - Arrays.fill(this.stateId2ImmutableBlockStates, EmptyBlock.INSTANCE.defaultState()); + if (EmptyBlock.STATE != null) + Arrays.fill(this.stateId2ImmutableBlockStates, EmptyBlock.STATE); } @Override diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java index 3ac1d4ccb..f13cef635 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/ConcretePowderBlockBehavior.java @@ -57,7 +57,7 @@ public class ConcretePowderBlockBehavior extends FallingBlockBehavior { } else { CraftEngine.instance().logger().warn("Failed to create solid block " + this.targetBlock + " in ConcretePowderBlockBehavior"); this.defaultBlockState = Reflections.instance$Blocks$STONE$defaultState; - this.defaultImmutableBlockState = EmptyBlock.INSTANCE.defaultState(); + this.defaultImmutableBlockState = EmptyBlock.STATE; } return this.defaultBlockState; } 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 11911a153..697399b11 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 @@ -690,7 +690,7 @@ public class BukkitInjector { // 如果是原版方块 if (BlockStateUtils.isVanillaBlock(stateId)) { // 那么应该情况自定义块 - ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.INSTANCE.defaultState()); + ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE); // 如果先前不是空气则标记 if (!previous.isEmpty()) { holder.ceChunk().setDirty(true); 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 bc3d7f7e8..2be540150 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 @@ -264,29 +264,31 @@ public class BukkitWorldManager implements WorldManager, Listener { ChunkPos pos = new ChunkPos(chunk.getX(), chunk.getZ()); CEChunk ceChunk = world.getChunkAtIfLoaded(chunk.getX(), chunk.getZ()); if (ceChunk != null) { - try { - world.worldDataStorage().writeChunkAt(pos, ceChunk, false); - } catch (IOException e) { - this.plugin.logger().warn("Failed to write chunk tag at " + chunk.getX() + " " + chunk.getZ(), e); - } finally { - if (Config.restoreVanillaBlocks()) { - CESection[] ceSections = ceChunk.sections(); - Object worldServer = FastNMS.INSTANCE.field$CraftChunk$worldServer(chunk); - Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(worldServer); - Object levelChunk = FastNMS.INSTANCE.method$ServerChunkCache$getChunkAtIfLoadedMainThread(chunkSource, chunk.getX(), chunk.getZ()); - Object[] sections = FastNMS.INSTANCE.method$ChunkAccess$getSections(levelChunk); - for (int i = 0; i < ceSections.length; i++) { - CESection ceSection = ceSections[i]; - Object section = sections[i]; - BukkitInjector.uninjectLevelChunkSection(section); - if (ceSection.statesContainer().isEmpty()) continue; - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - for (int y = 0; y < 16; y++) { - ImmutableBlockState customState = ceSection.getBlockState(x, y, z); - if (!customState.isEmpty() && customState.vanillaBlockState() != null) { - FastNMS.INSTANCE.method$LevelChunkSection$setBlockState(section, x, y, z, customState.vanillaBlockState().handle(), false); - } + if (ceChunk.dirty()) { + try { + world.worldDataStorage().writeChunkAt(pos, ceChunk, false); + ceChunk.setDirty(false); + } catch (IOException e) { + this.plugin.logger().warn("Failed to write chunk tag at " + chunk.getX() + " " + chunk.getZ(), e); + } + } + if (Config.restoreVanillaBlocks()) { + CESection[] ceSections = ceChunk.sections(); + Object worldServer = FastNMS.INSTANCE.field$CraftChunk$worldServer(chunk); + Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(worldServer); + Object levelChunk = FastNMS.INSTANCE.method$ServerChunkCache$getChunkAtIfLoadedMainThread(chunkSource, chunk.getX(), chunk.getZ()); + Object[] sections = FastNMS.INSTANCE.method$ChunkAccess$getSections(levelChunk); + for (int i = 0; i < ceSections.length; i++) { + CESection ceSection = ceSections[i]; + Object section = sections[i]; + BukkitInjector.uninjectLevelChunkSection(section); + if (ceSection.statesContainer().isEmpty()) continue; + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + for (int y = 0; y < 16; y++) { + ImmutableBlockState customState = ceSection.getBlockState(x, y, z); + if (!customState.isEmpty() && customState.vanillaBlockState() != null) { + FastNMS.INSTANCE.method$LevelChunkSection$setBlockState(section, x, y, z, customState.vanillaBlockState().handle(), false); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/EmptyBlock.java b/core/src/main/java/net/momirealms/craftengine/core/block/EmptyBlock.java index 84d079d37..4f827823b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/EmptyBlock.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/EmptyBlock.java @@ -7,10 +7,12 @@ import java.util.Map; public class EmptyBlock extends CustomBlock { public static EmptyBlock INSTANCE; + public static ImmutableBlockState STATE; public EmptyBlock(Key id, Holder.Reference holder) { super(id, holder, Map.of(), Map.of(), Map.of(), BlockSettings.of(), null, null); INSTANCE = this; + STATE = defaultState(); } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/ImmutableBlockState.java b/core/src/main/java/net/momirealms/craftengine/core/block/ImmutableBlockState.java index 928e11df0..4f6ca3a96 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/ImmutableBlockState.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/ImmutableBlockState.java @@ -51,7 +51,7 @@ public class ImmutableBlockState extends BlockStateHolder { } public boolean isEmpty() { - return this == EmptyBlock.INSTANCE.defaultState(); + return this == EmptyBlock.STATE; } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java index d35de426e..cfa239665 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/CEChunk.java @@ -67,7 +67,7 @@ public class CEChunk { for (int i = 0; i < sections.length; ++i) { if (sections[i] == null) { sections[i] = new CESection(world.worldHeight().getSectionYFromSectionIndex(i), - new PalettedContainer<>(null, EmptyBlock.INSTANCE.defaultState(), PalettedContainer.PaletteProvider.CUSTOM_BLOCK_STATE)); + new PalettedContainer<>(null, EmptyBlock.STATE, PalettedContainer.PaletteProvider.CUSTOM_BLOCK_STATE)); } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PackedIntegerArray.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PackedIntegerArray.java index 9601bf068..554224f8a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PackedIntegerArray.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PackedIntegerArray.java @@ -1,5 +1,7 @@ package net.momirealms.craftengine.core.world.chunk; +import net.momirealms.craftengine.core.block.ImmutableBlockState; + import java.util.function.IntConsumer; public class PackedIntegerArray implements PaletteStorage { diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PalettedContainer.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PalettedContainer.java index 34229ca81..de064dbe6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PalettedContainer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/PalettedContainer.java @@ -69,7 +69,7 @@ public class PalettedContainer implements PaletteResizeListener, ReadableC public boolean isEmpty() { Data data = this.data; if (data.palette instanceof SingularPalette singularPalette) { - return singularPalette.get(0) == EmptyBlock.INSTANCE; + return singularPalette.get(0) == EmptyBlock.STATE; } return false; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultSectionSerializer.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultSectionSerializer.java index 2505618b3..5ccdf2a3f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultSectionSerializer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/serialization/DefaultSectionSerializer.java @@ -31,7 +31,7 @@ public class DefaultSectionSerializer { ReadableContainer.Serialized serialized = section.statesContainer().serialize(null, PalettedContainer.PaletteProvider.CUSTOM_BLOCK_STATE); ListTag palettes = new ListTag(); List states = serialized.paletteEntries(); - if (states.size() == 1 && states.get(0) == EmptyBlock.INSTANCE.defaultState()) { + if (states.size() == 1 && states.get(0) == EmptyBlock.STATE) { return null; } CompoundTag sectionNbt = new CompoundTag();