From 37f3726ccc818d0f52cc9dbc66716bb8fe21bec8 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Sat, 10 Sep 2022 13:55:56 +0200 Subject: [PATCH] Add ColorReplaceCommand Add TypeReplaceCommand WIP Signed-off-by: yoyosource --- .../worldedit/ColorReplaceCommand.java | 81 ++++++++++++++ .../features/worldedit/SpecialReplace.java | 66 +++++++++++ .../worldedit/TypeReplaceCommand.java | 105 ++++++++++++++++++ .../bausystem/utils/WorldEditUtils.java | 7 +- 4 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/ColorReplaceCommand.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SpecialReplace.java create mode 100644 BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/TypeReplaceCommand.java diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/ColorReplaceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/ColorReplaceCommand.java new file mode 100644 index 00000000..69234184 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/ColorReplaceCommand.java @@ -0,0 +1,81 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.worldedit; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; +import de.steamwar.bausystem.linkage.LinkageType; +import de.steamwar.bausystem.linkage.Linked; +import de.steamwar.bausystem.region.Color; +import de.steamwar.bausystem.utils.WorldEditUtils; +import de.steamwar.command.SWCommand; +import lombok.SneakyThrows; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +@Linked(LinkageType.COMMAND) +public class ColorReplaceCommand extends SWCommand { + + public ColorReplaceCommand() { + super("/colorreplace", "/cr"); + } + + private Set types = new HashSet<>(); + { + for (Material value : Material.values()) { + if (value.name().startsWith("WHITE_")) { + types.add(value.name().substring(6)); + } + } + } + + @Register + @SneakyThrows + public void genericCommand(Player player, Color from, Color to) { + if (from == to) { + BukkitAdapter.adapt(player).printInfo(TranslatableComponent.of("worldedit.replace.replaced", new Component[]{TextComponent.of(0)})); + return; + } + + World world = player.getWorld(); + + Set toReplace = types.stream().map(s -> "minecraft:" + from.name().toLowerCase() + "_" + s.toLowerCase()).collect(Collectors.toSet()); + String fromString = "minecraft:" + from.name().toLowerCase() + "_"; + String toString = "minecraft:" + to.name().toLowerCase() + "_"; + + Region region = WorldEditUtils.getRegion(player); + EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(BukkitAdapter.adapt(world), -1, BukkitAdapter.adapt(player)); + + SpecialReplace specialReplace = new SpecialReplace(editSession, toReplace, s -> s.replace(fromString, toString)); + int affected = editSession.replaceBlocks(region, specialReplace, specialReplace); + editSession.flushSession(); + BukkitAdapter.adapt(player).printInfo(TranslatableComponent.of("worldedit.replace.replaced", new Component[]{TextComponent.of(affected)})); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SpecialReplace.java b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SpecialReplace.java new file mode 100644 index 00000000..59c20b86 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/SpecialReplace.java @@ -0,0 +1,66 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.worldedit; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.mask.Mask2D; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.block.BaseBlock; +import org.bukkit.Bukkit; + +import javax.annotation.Nullable; +import java.util.Set; +import java.util.function.Function; + +public class SpecialReplace implements Mask, Pattern { + + private EditSession editSession; + private Set toReplace; + private Function replacer; + + public SpecialReplace(EditSession editSession, Set toReplace, Function replacer) { + this.editSession = editSession; + this.toReplace = toReplace; + this.replacer = replacer; + } + + @Override + public boolean test(BlockVector3 blockVector3) { + return toReplace.contains(editSession.getFullBlock(blockVector3).getBlockType().getId()); + } + + @Nullable + @Override + public Mask2D toMask2D() { + return null; + } + + @Override + public BaseBlock applyBlock(BlockVector3 position) { + try { + return BukkitAdapter.adapt(Bukkit.createBlockData(replacer.apply(BukkitAdapter.adapt(editSession.getFullBlock(position)).getAsString()))).toBaseBlock(); + } catch (IllegalArgumentException e) { + return editSession.getFullBlock(position); + } + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/TypeReplaceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/TypeReplaceCommand.java new file mode 100644 index 00000000..ab82aa4c --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/worldedit/TypeReplaceCommand.java @@ -0,0 +1,105 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bausystem.features.worldedit; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; +import de.steamwar.bausystem.linkage.LinkageType; +import de.steamwar.bausystem.linkage.Linked; +import de.steamwar.bausystem.region.Color; +import de.steamwar.bausystem.utils.WorldEditUtils; +import de.steamwar.command.SWCommand; +import lombok.SneakyThrows; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +@Linked(LinkageType.COMMAND) +public class TypeReplaceCommand extends SWCommand { + + private enum Type { + OAK, + SPRUCE, + BIRCH, + JUNGLE, + ACACIA, + DARK_OAK, + CRIMSON, + WARPED, + MANGROVE, + STONE, + COBBLE, + MOSSY_COBBLE, + SANDSTONE, + RED_SANDSTONE, + BRICK, + STONE_BRICK, + NETHER_BRICK, + QUARTZ, + PURPUR, + BLACKSTONE, + } + + public TypeReplaceCommand() { + super("/typereplace", "/tr"); + } + + private Set types = new HashSet<>(); + { + types.add(""); + types.add("STAIRS"); + types.add("SLAB"); + types.add("FENCE"); + types.add("FENCE_GATE"); + types.add("WALL"); + } + + @Register + @SneakyThrows + public void genericCommand(Player player, Type from, Type to) { + if (from == to) { + BukkitAdapter.adapt(player).printInfo(TranslatableComponent.of("worldedit.replace.replaced", new Component[]{TextComponent.of(0)})); + return; + } + + World world = player.getWorld(); + + Set toReplace = types.stream().map(s -> "minecraft:" + from.name().toLowerCase() + "_" + s.toLowerCase()).collect(Collectors.toSet()); + String fromString = "minecraft:" + from.name().toLowerCase() + "_"; + String toString = "minecraft:" + to.name().toLowerCase() + "_"; + + Region region = WorldEditUtils.getRegion(player); + EditSession editSession = WorldEdit.getInstance().getEditSessionFactory().getEditSession(BukkitAdapter.adapt(world), -1, BukkitAdapter.adapt(player)); + + SpecialReplace specialReplace = new SpecialReplace(editSession, toReplace, s -> s.replace(fromString, toString)); + int affected = editSession.replaceBlocks(region, specialReplace, specialReplace); + editSession.flushSession(); + BukkitAdapter.adapt(player).printInfo(TranslatableComponent.of("worldedit.replace.replaced", new Component[]{TextComponent.of(affected)})); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/utils/WorldEditUtils.java b/BauSystem_Main/src/de/steamwar/bausystem/utils/WorldEditUtils.java index 057628d7..af281501 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/utils/WorldEditUtils.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/utils/WorldEditUtils.java @@ -24,6 +24,7 @@ import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.RegionSelector; import de.steamwar.bausystem.shared.Pair; import lombok.SneakyThrows; @@ -32,8 +33,6 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; -import java.util.Iterator; - @UtilityClass public class WorldEditUtils { @@ -46,12 +45,12 @@ public class WorldEditUtils { } @SneakyThrows - public Iterator getSelectionIterator(Player player) { + public Region getRegion(Player player) { RegionSelector regionSelector = WorldEdit.getInstance() .getSessionManager() .get(BukkitAdapter.adapt(player)) .getRegionSelector(BukkitAdapter.adapt(player.getWorld())); - return regionSelector.getRegion().iterator(); + return regionSelector.getRegion(); } public Pair getSelection(Player player) {