diff --git a/build.gradle.kts b/build.gradle.kts index a9cc2d2..9066c5b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,7 +21,7 @@ repositories { maven("https://repo.mineinabyss.com/releases") maven("https://papermc.io/repo/repository/maven-public/") //Paper maven("https://repo.codemc.org/repository/maven-public/") -// maven("https://mvn.intellectualsites.com/content/repositories/releases/") // FAWE + maven("https://mvn.intellectualsites.com/content/repositories/releases/") // FAWE maven("https://jitpack.io") } @@ -30,7 +30,10 @@ val kotlinVersion: String by project dependencies { compileOnly("com.destroystokyo.paper:paper-api:$serverVersion") -// compileOnly("com.intellectualsites.fawe:FAWE-Bukkit:1.16-637") + + compileOnly("com.fastasyncworldedit:FAWE-Bukkit:1.17-47") { isTransitive = false } + compileOnly("com.fastasyncworldedit:FAWE-Core:1.17-47") + compileOnly(kotlin("stdlib-jdk8")) kotlinSpice("$kotlinVersion+") diff --git a/src/main/java/com/derongan/minecraft/deeperworld/DeeperCommandExecutor.kt b/src/main/java/com/derongan/minecraft/deeperworld/DeeperCommandExecutor.kt index 1e407ae..39c4883 100644 --- a/src/main/java/com/derongan/minecraft/deeperworld/DeeperCommandExecutor.kt +++ b/src/main/java/com/derongan/minecraft/deeperworld/DeeperCommandExecutor.kt @@ -4,6 +4,12 @@ import com.derongan.minecraft.deeperworld.MinecraftConstants.FULL_DAY_TIME import com.derongan.minecraft.deeperworld.config.DeeperConfig import com.derongan.minecraft.deeperworld.services.WorldManager import com.derongan.minecraft.deeperworld.services.canMoveSections +import com.derongan.minecraft.deeperworld.synchronization.sync +import com.derongan.minecraft.deeperworld.world.section.correspondingSection +import com.derongan.minecraft.deeperworld.world.section.getCorrespondingLocation +import com.derongan.minecraft.deeperworld.world.section.section +import com.fastasyncworldedit.core.util.EditSessionBuilder +import com.fastasyncworldedit.core.util.TaskManager import com.mineinabyss.idofront.commands.CommandHolder import com.mineinabyss.idofront.commands.arguments.booleanArg import com.mineinabyss.idofront.commands.arguments.intArg @@ -14,6 +20,17 @@ import com.mineinabyss.idofront.commands.extensions.actions.playerAction import com.mineinabyss.idofront.messaging.error import com.mineinabyss.idofront.messaging.info import com.mineinabyss.idofront.messaging.success +import com.sk89q.worldedit.EditSession +import com.sk89q.worldedit.bukkit.WorldEditPlugin +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard +import com.sk89q.worldedit.function.operation.ForwardExtentCopy +import com.sk89q.worldedit.function.operation.Operation +import com.sk89q.worldedit.function.operation.Operations +import com.sk89q.worldedit.math.BlockVector3 +import com.sk89q.worldedit.regions.CuboidRegion +import com.sk89q.worldedit.session.ClipboardHolder +import com.sk89q.worldedit.world.World + @ExperimentalCommandDSL object DeeperCommandExecutor : IdofrontCommandExecutor() { @@ -64,6 +81,104 @@ object DeeperCommandExecutor : IdofrontCommandExecutor() { } } } + "sync"(desc = "Sync blocks in range") { + val range by intArg() + playerAction { + val section = + player.location.section ?: run { + sender.error("${player.name} is not in a managed section") + return@playerAction + } + + when { + DeeperContext.isFAWELoaded -> { + try { + val pos1 = BlockVector3.at( + (player.location.x + range), + (player.location.y + range), + (player.location.z + range) + ) + val pos2 = BlockVector3.at( + (player.location.x - range), + (player.location.y - range), + (player.location.z - range) + ) + + val region = CuboidRegion(pos1, pos2) + val clipboard = BlockArrayClipboard(region) + val wep = WorldEditPlugin.getInstance().bukkitImplAdapter; + val weWorld: World = wep.adapt(player.world) + val editSession: EditSession = EditSessionBuilder(weWorld) + .limitUnlimited() + .build() + + val loc = player.location + val linkedSection = + loc.correspondingSection ?: error("Corresponding Section not found") + + val linkedBlock = loc.getCorrespondingLocation(section, linkedSection)?.block + ?: error("Corresponding Location not found") + + val offset = if (pos2.y < 0) pos2.y else 0 + TaskManager.IMP.taskNowAsync { + player.success("Blocks syncing...") + editSession.use { editSession -> + // Copy + val forwardExtentCopy = + ForwardExtentCopy( + editSession, region, clipboard, region.minimumPoint + ) + forwardExtentCopy.isCopyingEntities = false + forwardExtentCopy.isCopyingBiomes = true + Operations.complete(forwardExtentCopy) + + // Paste + val operation: Operation = ClipboardHolder(clipboard) + .createPaste(editSession) + .to( + BlockVector3.at( + linkedBlock.x - range, + linkedBlock.y - range - offset, + linkedBlock.z - range + ) + ) + .build() + Operations.complete(operation) + } + player.success("Blocks synced (FAWE)") + } + } catch (e: Exception) { + player.error("""An error occurred: ${e.message}""") + } + } + range <= 100 -> { + // Get blocks in range specified + for (x in -range..range) { + for (y in -range..range) { + for (z in -range..range) { + val block = player.world.getBlockAt( + (player.location.x + x).toInt(), + (player.location.y + y).toInt(), + (player.location.z + z).toInt() + ) + + block.sync { original, corr -> + if (original.type != corr.type) { + corr.blockData = original.blockData.clone() + } + } + } + } + } + + player.success("Blocks synced") + } + else -> { + sender.error("Please use a range smaller than 100 blocks, or install FAWE to use a larger range") + } + } + } + } } "linfo"{ playerAction{ diff --git a/src/main/java/com/derongan/minecraft/deeperworld/DeeperContext.kt b/src/main/java/com/derongan/minecraft/deeperworld/DeeperContext.kt index 2971584..0a6e1de 100644 --- a/src/main/java/com/derongan/minecraft/deeperworld/DeeperContext.kt +++ b/src/main/java/com/derongan/minecraft/deeperworld/DeeperContext.kt @@ -5,4 +5,5 @@ package com.derongan.minecraft.deeperworld */ object DeeperContext { val isBlockLockerLoaded: Boolean = deeperWorld.server.pluginManager.isPluginEnabled("BlockLocker") + val isFAWELoaded: Boolean = deeperWorld.server.pluginManager.isPluginEnabled("FastAsyncWorldEdit") } \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7c7388c..42bfef5 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,7 +5,7 @@ authors: [Derongan] api-version: '1.16' description: A plugin for letting you create a deeper world. Or at least fake it. -softdepend: [Multiverse-Core, BlockLocker, KotlinSpice, ProtocolLib] +softdepend: [Multiverse-Core, BlockLocker, KotlinSpice, ProtocolLib, FastAsyncWorldEdit] commands: deeperworld: