From b1b536207b7833416c7c5037f352c28d1eb6e1b4 Mon Sep 17 00:00:00 2001 From: T14D3 <73843330+T14D3@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:08:40 +0100 Subject: [PATCH 1/3] Initial worldedit restriction support --- build.gradle | 5 ++ src/main/java/de/t14d3/zones/Zones.java | 6 ++ .../zones/integrations/WorldEditExtent.java | 28 ++++++++ .../zones/integrations/WorldEditSession.java | 70 +++++++++++++++++++ src/main/resources/plugin.yml | 1 + 5 files changed, 110 insertions(+) create mode 100644 src/main/java/de/t14d3/zones/integrations/WorldEditExtent.java create mode 100644 src/main/java/de/t14d3/zones/integrations/WorldEditSession.java diff --git a/build.gradle b/build.gradle index 931f2e0..6364101 100644 --- a/build.gradle +++ b/build.gradle @@ -20,10 +20,15 @@ repositories { name = "sonatype" url = "https://oss.sonatype.org/content/groups/public/" } + maven { + name = "EngineHub" + url = "https://maven.enginehub.org/repo/" + } } dependencies { compileOnly 'io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT' + compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.3.0' //paperweight.paperDevBundle("1.21.1-R0.1-SNAPSHOT") } diff --git a/src/main/java/de/t14d3/zones/Zones.java b/src/main/java/de/t14d3/zones/Zones.java index e1574c4..319a70d 100644 --- a/src/main/java/de/t14d3/zones/Zones.java +++ b/src/main/java/de/t14d3/zones/Zones.java @@ -1,5 +1,7 @@ package de.t14d3.zones; +import com.sk89q.worldedit.WorldEdit; +import de.t14d3.zones.integrations.WorldEditSession; import de.t14d3.zones.listeners.CommandListener; import de.t14d3.zones.listeners.PlayerInteractListener; import de.t14d3.zones.listeners.PlayerQuitListener; @@ -93,6 +95,10 @@ public void onEnable() { getLogger().info("Zones have been saved."); }, 20L, getConfig().getInt("zone-saving.period", 60) * 20L); } + if (getServer().getPluginManager().getPlugin("WorldEdit") != null) { + WorldEdit.getInstance().getEventBus().register(new WorldEditSession(this)); + getLogger().info("WorldEdit Integration enabled."); + } getLogger().info("Zones plugin has been enabled! Loaded " + regionManager.loadedRegions.size() + " regions."); } diff --git a/src/main/java/de/t14d3/zones/integrations/WorldEditExtent.java b/src/main/java/de/t14d3/zones/integrations/WorldEditExtent.java new file mode 100644 index 0000000..8aa2075 --- /dev/null +++ b/src/main/java/de/t14d3/zones/integrations/WorldEditExtent.java @@ -0,0 +1,28 @@ +package de.t14d3.zones.integrations; + +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.extent.AbstractDelegateExtent; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.block.BlockStateHolder; + +import java.util.Set; + +public class WorldEditExtent extends AbstractDelegateExtent { + private final Set mask; + + public WorldEditExtent(Set mask, Extent extent) { + super(extent); + this.mask = mask; + } + + @SuppressWarnings("unchecked") + @Override + public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException { + if (!WorldEditSession.WorldEditUtils.maskContains(this.mask, location.x(), location.y(), location.z())) { + return false; + } + return super.setBlock(location, block); + } +} diff --git a/src/main/java/de/t14d3/zones/integrations/WorldEditSession.java b/src/main/java/de/t14d3/zones/integrations/WorldEditSession.java new file mode 100644 index 0000000..ce47673 --- /dev/null +++ b/src/main/java/de/t14d3/zones/integrations/WorldEditSession.java @@ -0,0 +1,70 @@ +package de.t14d3.zones.integrations; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.event.extent.EditSessionEvent; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.util.eventbus.Subscribe; +import de.t14d3.zones.Region; +import de.t14d3.zones.Zones; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.HashSet; +import java.util.Set; + +public class WorldEditSession { + private final Zones plugin; + private final WorldEditUtils utils; + + + public WorldEditSession(Zones plugin) { + this.plugin = plugin; + this.utils = new WorldEditUtils(); + } + + @Subscribe + public void onEditSessionEvent(EditSessionEvent event) { + if (event.getStage() == EditSession.Stage.BEFORE_REORDER) { + Player player = null; + if (event.getActor().isPlayer()) { + player = Bukkit.getPlayer(event.getActor().getName()); + } + Set mask = utils.getMask(player); + event.setExtent(new WorldEditExtent(mask, event.getExtent())); + } + } + + public class WorldEditUtils { + public HashSet getMask(Player player) { + HashSet mask = new HashSet<>(); + for (Region region : plugin.getRegionManager().regions().values()) { + if ((plugin.getPermissionManager().hasPermission(player.getUniqueId(), "PLACE", "true", region) + && plugin.getPermissionManager().hasPermission(player.getUniqueId(), "BREAK", "true", region)) + || region.isAdmin(player.getUniqueId())) { + mask.add(new CuboidRegion( + BukkitAdapter.asBlockVector(region.getMin()), + BukkitAdapter.asBlockVector(region.getMax().clone().subtract(1, 1, 1)) // Don't ask me why, but it works + )); + } + } + return mask; + } + + public static boolean cuboidRegionContains(CuboidRegion region, int x, int y, int z) { + return region.getMinimumPoint().x() <= x && region.getMaximumPoint().x() >= x && + region.getMinimumPoint().y() <= y && region.getMaximumPoint().y() >= y && + region.getMinimumPoint().z() <= z && region.getMaximumPoint().z() >= z; + } + + public static boolean maskContains(Set mask, int x, int y, int z) { + for (CuboidRegion region : mask) { + if (cuboidRegionContains(region, x, y, z)) { + return true; + } + } + return false; + } + } + +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0808ca4..424a647 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,6 +2,7 @@ name: Zones version: '${version}' main: de.t14d3.zones.Zones api-version: '1.21' +softdepend: [ WorldEdit, FastAsyncWorldEdit ] commands: zone: description: Main Command From ece6867a18a941f237022dcf59f590175d5f9def Mon Sep 17 00:00:00 2001 From: T14D3 <73843330+T14D3@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:36:03 +0100 Subject: [PATCH 2/3] Add FastAsyncWorldEdit support --- build.gradle | 3 + src/main/java/de/t14d3/zones/Zones.java | 6 ++ .../zones/integrations/FAWEIntegration.java | 61 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/main/java/de/t14d3/zones/integrations/FAWEIntegration.java diff --git a/build.gradle b/build.gradle index 6364101..6cfeb66 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,9 @@ dependencies { compileOnly 'io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT' compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.3.0' //paperweight.paperDevBundle("1.21.1-R0.1-SNAPSHOT") + implementation(platform("com.intellectualsites.bom:bom-newest:1.52")) + compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core") + compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") } def targetJavaVersion = 21 diff --git a/src/main/java/de/t14d3/zones/Zones.java b/src/main/java/de/t14d3/zones/Zones.java index 319a70d..6db7443 100644 --- a/src/main/java/de/t14d3/zones/Zones.java +++ b/src/main/java/de/t14d3/zones/Zones.java @@ -1,6 +1,8 @@ package de.t14d3.zones; +import com.fastasyncworldedit.core.util.WEManager; import com.sk89q.worldedit.WorldEdit; +import de.t14d3.zones.integrations.FAWEIntegration; import de.t14d3.zones.integrations.WorldEditSession; import de.t14d3.zones.listeners.CommandListener; import de.t14d3.zones.listeners.PlayerInteractListener; @@ -99,6 +101,10 @@ public void onEnable() { WorldEdit.getInstance().getEventBus().register(new WorldEditSession(this)); getLogger().info("WorldEdit Integration enabled."); } + if (getServer().getPluginManager().getPlugin("FastAsyncWorldEdit") != null) { + WEManager.weManager().addManager(new FAWEIntegration(this)); + getLogger().info("FAWE Integration enabled."); + } getLogger().info("Zones plugin has been enabled! Loaded " + regionManager.loadedRegions.size() + " regions."); } diff --git a/src/main/java/de/t14d3/zones/integrations/FAWEIntegration.java b/src/main/java/de/t14d3/zones/integrations/FAWEIntegration.java new file mode 100644 index 0000000..494ddf4 --- /dev/null +++ b/src/main/java/de/t14d3/zones/integrations/FAWEIntegration.java @@ -0,0 +1,61 @@ +package de.t14d3.zones.integrations; + +import com.fastasyncworldedit.bukkit.regions.BukkitMaskManager; +import com.fastasyncworldedit.core.regions.FaweMask; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.regions.CuboidRegion; +import de.t14d3.zones.Region; +import de.t14d3.zones.Zones; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.List; + +public class FAWEIntegration extends BukkitMaskManager { + + private final Zones plugin; + + public FAWEIntegration(final Zones plugin) { + super(plugin.getName()); + this.plugin = plugin; + } + + public boolean isAllowed(Player player, Region region, MaskType type) { + return region != null && + (region.isAdmin(player.getUniqueId()) || + type == MaskType.MEMBER && ( + plugin.getPermissionManager().hasPermission(player.getUniqueId(), "PLACE", "true", region) + || plugin.getPermissionManager().hasPermission(player.getUniqueId(), "BREAK", "true", region))); + } + + @Override + public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, final MaskType type, boolean isWhitelist) { + final Player player = BukkitAdapter.adapt(wePlayer); + final Location location = player.getLocation(); + List regions = plugin.getRegionManager().getRegionsAt(location); + if (!regions.isEmpty()) { + boolean isAllowed = true; + for (Region region : regions) { + if (!isAllowed(player, region, type)) { + isAllowed = false; + break; + } + } + if (isAllowed) { + final Location pos1 = regions.get(0).getMin(); + final Location pos2 = regions.get(0).getMax(); + final Region region = regions.get(0); + return new FaweMask(new CuboidRegion(BukkitAdapter.asBlockVector(pos1), BukkitAdapter.asBlockVector(pos2))) { + @Override + public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) { + return isAllowed(BukkitAdapter.adapt(player), region, type); + } + }; + } + } + + + return null; + } + +} From 1bd6e6979ac6c7a1f7ec967cde9a807c9ab85d8d Mon Sep 17 00:00:00 2001 From: T14D3 <73843330+T14D3@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:37:45 +0100 Subject: [PATCH 3/3] [ci skip] Update TODO.md --- TODO.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index a60a4b8..393002b 100644 --- a/TODO.md +++ b/TODO.md @@ -43,7 +43,9 @@ - [ ] PlaceholderAPI - [ ] Vault (Maybe? Not sure for what) - [ ] WorldGuard (Overlap compatibility checking?) - - [ ] WorldEdit (Creating from selection, visuals) + - [ ] WorldEdit + - [x] Zone-based restrictions + - [ ] Selection integration (Visuals, Creation) - [ ] Other: - [ ] Better error handling - [ ] Storage Methods: