From 93d09c73ee879b8db18ba13eee8adf96f31873c2 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Tue, 6 May 2025 18:57:48 +0800 Subject: [PATCH] =?UTF-8?q?refactor(core):=20=E5=AE=8C=E5=85=A8=E5=85=BC?= =?UTF-8?q?=E5=AE=B9fawe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../worldedit/FastAsyncWorldEditDelegate.java | 37 ++++++++++++++++++- .../plugin/injector/BukkitInjector.java | 2 - 2 files changed, 36 insertions(+), 3 deletions(-) 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 7f82fe30b..baf70618d 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 @@ -18,6 +18,8 @@ import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector; import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.core.block.EmptyBlock; import net.momirealms.craftengine.core.block.ImmutableBlockState; @@ -25,7 +27,9 @@ import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.ReflectionUtils; import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.ChunkPos; +import net.momirealms.craftengine.core.world.SectionPos; import net.momirealms.craftengine.core.world.chunk.CEChunk; +import net.momirealms.craftengine.core.world.chunk.CESection; import org.bukkit.Bukkit; import java.io.IOException; @@ -40,6 +44,7 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { private final Set chunksToSave; private final CEWorld ceWorld; private static int[] ordinalToIbdID; + private static final Set chunksNeedInjection = new HashSet<>(); protected FastAsyncWorldEditDelegate(EditSessionEvent event) { super(event.getExtent()); @@ -58,7 +63,7 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { assert ordinalToIbdIDMethod != null; ordinalToIbdID = (int[]) ordinalToIbdIDMethod.invoke(adapter); } catch (ReflectiveOperationException e) { - throw new RuntimeException("Failed to init FAWE compatibility", e); + throw new RuntimeException("Failed to init FastAsyncWorldEdit compatibility", e); } WorldEdit.getInstance().getEventBus().register(new Object() { @Subscribe @@ -66,11 +71,40 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { public void onEditSessionEvent(EditSessionEvent event) { if (event.getStage() == EditSession.Stage.BEFORE_CHANGE) { event.setExtent(new FastAsyncWorldEditDelegate(event)); + } else if (event.getStage() == EditSession.Stage.BEFORE_HISTORY) { + event.setExtent(new AbstractDelegateExtent(event.getExtent()) { + @Override + public Operation commit() { + Set processedChunk = new HashSet<>(); + org.bukkit.World world = Bukkit.getWorld(requireNonNull(event.getWorld()).getName()); + CEWorld ceWorld = CraftEngine.instance().worldManager().getWorld(requireNonNull(world).getUID()); + chunksNeedInjection.forEach(ceChunk -> { + injectLevelChunk(requireNonNull(ceWorld), ceChunk); + processedChunk.add(ceChunk); + }); + processedChunk.forEach(chunksNeedInjection::remove); + return super.commit(); + } + }); } } }); } + private static void injectLevelChunk(CEWorld ceWorld, CEChunk ceChunk) { + ChunkPos pos = ceChunk.chunkPos(); + CESection[] ceSections = ceChunk.sections(); + Object worldServer = ceWorld.world().serverWorld(); + Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(worldServer); + Object levelChunk = FastNMS.INSTANCE.method$ServerChunkCache$getChunkAtIfLoadedMainThread(chunkSource, pos.x, pos.z); + 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.injectLevelChunkSection(section, ceSection, ceWorld, ceChunk, new SectionPos(pos.x, ceChunk.sectionY(i), pos.z)); + } + } + @Override public int setBlocks(final Set vset, final Pattern pattern) { this.processBlocks(vset, pattern); @@ -165,6 +199,7 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { try { for (CEChunk ceChunk : this.chunksToSave) { CraftEngine.instance().debug(() -> "Saving chunk " + ceChunk.chunkPos()); + chunksNeedInjection.add(ceChunk); this.ceWorld.worldDataStorage().writeChunkAt(ceChunk.chunkPos(), ceChunk, true); } this.chunksToSave.clear(); 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 79ddd56c3..9035d930c 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 @@ -712,8 +712,6 @@ public class BukkitInjector { ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId); ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState); // 如果之前的自定义块(空气)和当前自定义块不同 - System.out.println("1:" + immutableBlockState); - System.out.println("2:" + previousImmutableBlockState); if (previousImmutableBlockState != immutableBlockState) { holder.ceChunk().setDirty(true); if (Config.enableLightSystem() && !immutableBlockState.isEmpty()) {