diff --git a/bukkit/compatibility/build.gradle.kts b/bukkit/compatibility/build.gradle.kts index b0cd5fa25..db481a7c5 100644 --- a/bukkit/compatibility/build.gradle.kts +++ b/bukkit/compatibility/build.gradle.kts @@ -26,9 +26,6 @@ dependencies { compileOnly("pers.neige.neigeitems:NeigeItems:1.21.42") // Placeholder compileOnly("me.clip:placeholderapi:${rootProject.properties["placeholder_api_version"]}") - // WorldEdit - compileOnly("com.sk89q.worldedit:worldedit-core:7.2.19") - compileOnly("com.sk89q.worldedit:worldedit-bukkit:7.2.19") // SlimeWorld compileOnly("com.infernalsuite.asp:api:4.0.0-SNAPSHOT") // ModelEngine @@ -44,6 +41,10 @@ dependencies { compileOnly("com.viaversion:viaversion-api:5.3.2") // Skript compileOnly("com.github.SkriptLang:Skript:2.11.0") + // FAWE + compileOnly(platform("com.intellectualsites.bom:bom-newest:1.52")) + compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core") + compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false } } java { 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 new file mode 100644 index 000000000..d5f7e2d6f --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java @@ -0,0 +1,87 @@ +package net.momirealms.craftengine.bukkit.compatibility.worldedit; + +import com.fastasyncworldedit.core.configuration.Settings; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.event.extent.EditSessionEvent; +import com.sk89q.worldedit.extent.AbstractDelegateExtent; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.eventbus.Subscribe; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.core.block.EmptyBlock; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import org.bukkit.Bukkit; + +public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { + protected FastAsyncWorldEditDelegate(Extent extent) { + super(extent); + } + + public static void init() { + Settings.settings().EXTENT.ALLOWED_PLUGINS.add(FastAsyncWorldEditDelegate.class.getCanonicalName()); + WorldEdit.getInstance().getEventBus().register(new Object() { + @Subscribe + @SuppressWarnings("unused") + public void onEditSessionEvent(EditSessionEvent event) { + if (event.getStage() != EditSession.Stage.BEFORE_HISTORY) return; + event.setExtent(new FastAsyncWorldEditDelegate(event.getExtent())); + } + }); + } + + @Override + public int setBlocks(final Region region, final Pattern pattern) { + this.processBlocks(region, pattern); + return super.setBlocks(region, pattern); + } + + @Override + public int replaceBlocks(Region region, Mask mask, Pattern pattern) { + this.processBlocks(region, pattern); + return super.replaceBlocks(region, mask, pattern); + } + + private void processBlocks(Region region, Pattern pattern) { + try { + for (BlockVector3 position : region) { + BaseBlock blockState = pattern.applyBlock(position); + BlockState oldBlockState = getBlock(position); + int blockX = position.x(); + int blockY = position.y(); + int blockZ = position.z(); + int chunkX = blockX >> 4; + int chunkZ = blockZ >> 4; + int stateId = BlockStateUtils.blockDataToId(Bukkit.createBlockData(blockState.getAsString())); + int oldStateId = BlockStateUtils.blockDataToId(Bukkit.createBlockData(oldBlockState.getAsString())); + if (BlockStateUtils.isVanillaBlock(stateId) && BlockStateUtils.isVanillaBlock(oldStateId)) continue; + var weWorld = region.getWorld(); + if (weWorld == null) continue; + var world = Bukkit.getWorld(weWorld.getName()); + if (world == null) continue; + var ceWorld = CraftEngine.instance().worldManager().getWorld(world.getUID()); + if (ceWorld == null) continue; + var ceChunk = ceWorld.getChunkAtIfLoaded(chunkX, chunkZ); + if (ceChunk == null) { + world.loadChunk(chunkX, chunkZ); + ceChunk = ceWorld.getChunkAtIfLoaded(chunkX, chunkZ); + if (ceChunk == null) continue; + } + var immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(stateId); + if (immutableBlockState == null) { + ceChunk.setBlockState(blockX, blockY, blockZ, EmptyBlock.STATE); + } else { + ceChunk.setBlockState(blockX, blockY, blockZ, immutableBlockState); + } + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Error when recording FastAsyncWorldEdit operation blocks", e); + } + } +} diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/WorldEditBlockRegister.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/WorldEditBlockRegister.java index 2066c2bc1..dd0951843 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/WorldEditBlockRegister.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/WorldEditBlockRegister.java @@ -30,8 +30,12 @@ public class WorldEditBlockRegister { this.isFAWE = isFAWE; CEBlockParser blockParser = new CEBlockParser(WorldEdit.getInstance()); WorldEdit.getInstance().getBlockFactory().register(blockParser); + if (isFAWE) { + FastAsyncWorldEditDelegate.init(); + } } + @SuppressWarnings("deprecation") public void register(Key id) throws ReflectiveOperationException { BlockType blockType = new BlockType(id.toString(), blockState -> blockState); this.field$BlockType$blockMaterial.set(blockType, LazyReference.from(() -> new BukkitBlockRegistry.BukkitBlockMaterial(null, Material.STONE))); @@ -45,6 +49,7 @@ public class WorldEditBlockRegister { } @Override + @SuppressWarnings("deprecation") public Stream getSuggestions(String input) { Set namespacesInUse = manager.namespacesInUse();