From 24325d91ba6a5b75ef730fc15695664444169eb0 Mon Sep 17 00:00:00 2001 From: Jordan Date: Wed, 28 Jun 2023 09:24:20 +0100 Subject: [PATCH] feat: improve (region) fawe mask handling (#2312) * feat: improve fawe mask handling - Actually cache masks, even if the player has left the region - Fix P2 isValid test for single plots - Fixes #1946 * Fix incorrect delegated method --- .../fastasyncworldedit/bukkit/FaweBukkit.java | 2 +- .../regions/GriefPreventionFeature.java | 3 - .../bukkit/regions/ResidenceFeature.java | 8 +- .../plotsquared/PlotSquaredFeature.java | 75 ++++++++++++------- .../core/regions/FaweMask.java | 20 +++++ .../core/regions/FaweMaskManager.java | 10 ++- .../core/util/WEManager.java | 68 ++++++++--------- 7 files changed, 112 insertions(+), 74 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java index c2c9923e7..46bf125c5 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java @@ -225,7 +225,7 @@ public class FaweBukkit implements IFawe, Listener { final Plugin residencePlugin = Bukkit.getServer().getPluginManager().getPlugin("Residence"); if (residencePlugin != null && residencePlugin.isEnabled()) { try { - managers.add(new ResidenceFeature(residencePlugin, this)); + managers.add(new ResidenceFeature(residencePlugin)); LOGGER.info("Attempting to use plugin 'Residence'"); } catch (Throwable ignored) { } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/GriefPreventionFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/GriefPreventionFeature.java index e7fd9ad3a..9f302d057 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/GriefPreventionFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/GriefPreventionFeature.java @@ -2,10 +2,7 @@ package com.fastasyncworldedit.bukkit.regions; import com.fastasyncworldedit.core.regions.FaweMask; import com.fastasyncworldedit.core.util.TaskManager; -import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.BukkitWorld; -import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/ResidenceFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/ResidenceFeature.java index d72769176..a7c13cef5 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/ResidenceFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/ResidenceFeature.java @@ -3,7 +3,6 @@ package com.fastasyncworldedit.bukkit.regions; import com.bekvon.bukkit.residence.Residence; import com.bekvon.bukkit.residence.protection.ClaimedResidence; import com.bekvon.bukkit.residence.protection.CuboidArea; -import com.fastasyncworldedit.bukkit.FaweBukkit; import com.fastasyncworldedit.core.regions.FaweMask; import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -19,13 +18,8 @@ public class ResidenceFeature extends BukkitMaskManager implements Listener { private static final Logger LOGGER = LogManagerCompat.getLogger(); - private final FaweBukkit plugin; - private final Plugin residence; - - public ResidenceFeature(final Plugin residencePlugin, final FaweBukkit p3) { + public ResidenceFeature(final Plugin residencePlugin) { super(residencePlugin.getName()); - this.residence = residencePlugin; - this.plugin = p3; LOGGER.info("Plugin 'Residence' found. Using it now."); } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java index cd6f5ae22..46ba12f68 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java @@ -67,28 +67,32 @@ public class PlotSquaredFeature extends FaweMaskManager { * @param plot the {@link Plot} * @param type the {@link MaskType} * @return {@code true} if the player is the plot owner, trusted, has the permission fawe.plotsquared.member - * or fawe.plotsquared.admin and the NoWorldeditFlag is not set; otherwise {@code false} + * or fawe.plotsquared.admin and the NoWorldeditFlag is not set; otherwise {@code false} */ - public boolean isAllowed(Player player, Plot plot, MaskType type) { + public boolean isAllowed(Player player, Plot plot, MaskType type, boolean notify) { if (plot == null) { return false; } UUID uid = player.getUniqueId(); if (plot.getFlag(NoWorldeditFlag.class)) { - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.cancel.reason.no.region.plot.noworldeditflag") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.cancel.reason.no.region.plot.noworldeditflag") + )); + } return false; } if (plot.isOwner(uid) || player.hasPermission("fawe.plotsquared.admin")) { return true; } if (type != MaskType.MEMBER) { - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.cancel.reason.no.region.plot.owner.only") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.cancel.reason.no.region.plot.owner.only") + )); + } return false; } if (plot.getTrusted().contains(uid) || plot.getTrusted().contains(DBFunc.EVERYONE)) { @@ -96,26 +100,32 @@ public class PlotSquaredFeature extends FaweMaskManager { } if (plot.getMembers().contains(uid) || plot.getMembers().contains(DBFunc.EVERYONE)) { if (!player.hasPermission("fawe.plotsquared.member")) { - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.error.no-perm", "fawe.plotsquared.member") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.error.no-perm", "fawe.plotsquared.member") + )); + } return false; } if (!plot.getOwners().isEmpty() && plot.getOwners().stream().anyMatch(this::playerOnline)) { return true; } else { - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.cancel.reason.no.region.plot.owner.offline") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.cancel.reason.no.region.plot.owner.offline") + )); + } return false; } } - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.cancel.reason.no.region.not.added") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.cancel.reason.no.region.not.added") + )); + } return false; } @@ -128,14 +138,19 @@ public class PlotSquaredFeature extends FaweMaskManager { } @Override - public FaweMask getMask(Player player, MaskType type, boolean isWhitelist) { + public FaweMask getMask(final Player player, final MaskType type, final boolean isWhitelist) { + return getMask(player, type, isWhitelist, true); + } + + @Override + public FaweMask getMask(Player player, MaskType type, boolean isWhitelist, boolean notify) { final PlotPlayer pp = PlotPlayer.from(BukkitAdapter.adapt(player)); if (pp == null) { return null; } final Set regions; Plot plot = pp.getCurrentPlot(); - if (isAllowed(player, plot, type)) { + if (isAllowed(player, plot, type, notify)) { regions = plot.getRegions(); } else { plot = null; @@ -184,19 +199,23 @@ public class PlotSquaredFeature extends FaweMaskManager { private final Plot plot; private final WeakReference> connectedPlots; + private final boolean singlePlot; private PlotSquaredMask(Region region, Plot plot) { super(region); this.plot = plot; - connectedPlots = new WeakReference<>(plot.getConnectedPlots()); + Set connected = plot.getConnectedPlots(); + connectedPlots = new WeakReference<>(connected); + singlePlot = connected.size() == 1; } @Override - public boolean isValid(Player player, MaskType type) { - if (!connectedPlots.refersTo(plot.getConnectedPlots()) || (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot))) { + public boolean isValid(Player player, MaskType type, boolean notify) { + if ((!connectedPlots.refersTo(plot.getConnectedPlots()) && !singlePlot) || (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone( + plot))) { return false; } - return isAllowed(player, plot, type); + return isAllowed(player, plot, type, notify); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMask.java index 907769f51..4ea8c2c06 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMask.java @@ -17,10 +17,30 @@ public class FaweMask implements IDelegateRegion { return region; } + /** + * Test if the mask is still valid + * + * @param player player to test + * @param type type of mask + * @return if still valid + */ public boolean isValid(Player player, FaweMaskManager.MaskType type) { return false; } + /** + * Test if the mask is still valid + * + * @param player player to test + * @param type type of mask + * @param notify if the player should be notified + * @return if still valid + * @since TODO + */ + public boolean isValid(Player player, FaweMaskManager.MaskType type, boolean notify) { + return isValid(player, type); + } + @Override public Region clone() { throw new UnsupportedOperationException("Clone not supported"); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMaskManager.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMaskManager.java index 60c6e6be9..c52cc17e7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMaskManager.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMaskManager.java @@ -1,7 +1,6 @@ package com.fastasyncworldedit.core.regions; import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.regions.filter.RegionFilter; import com.sk89q.worldedit.entity.Player; import java.util.Locale; @@ -28,6 +27,15 @@ public abstract class FaweMaskManager { */ public abstract FaweMask getMask(final Player player, MaskType type, boolean isWhitelist); + /** + * Get a {@link FaweMask} for the given player and {@link MaskType}. If isWhitelist is false, will return a "blacklist" mask. + * + * @since TODO + */ + public FaweMask getMask(final Player player, MaskType type, boolean isWhitelist, boolean notify) { + return getMask(player, type, isWhitelist); + } + public boolean isExclusive() { return Settings.settings().REGION_RESTRICTIONS_OPTIONS.EXCLUSIVE_MANAGERS.contains(this.key); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/WEManager.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/WEManager.java index 439b486e3..17b7882f2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/WEManager.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/WEManager.java @@ -108,27 +108,22 @@ public class WEManager { } player.setMeta("lastMaskWorld", world); Set masks = player.getMeta("lastMask"); - Set backupRegions = new HashSet<>(); Set regions = new HashSet<>(); - if (masks == null || !isWhitelist) { masks = new HashSet<>(); } else { synchronized (masks) { boolean removed = false; + boolean inMask = false; if (!masks.isEmpty()) { Iterator iterator = masks.iterator(); while (iterator.hasNext()) { FaweMask mask = iterator.next(); - if (mask.isValid(player, type)) { + if (mask.isValid(player, type, false)) { Region region = mask.getRegion(); - if (region.contains(loc.toBlockPoint())) { - regions.add(region); - } else { - removed = true; - backupRegions.add(region); - } + inMask |= region.contains(loc.toBlockPoint()); + regions.add(region); } else { if (Settings.settings().ENABLED_COMPONENTS.DEBUG) { player.printDebug(Caption.of("fawe.error.region-mask-invalid", mask.getClass().getSimpleName())); @@ -138,39 +133,44 @@ public class WEManager { } } } - if (!removed) { + if (!removed && inMask) { return regions.toArray(new Region[0]); } - masks.clear(); } } - for (FaweMaskManager manager : managers) { - if (player.hasPermission("fawe." + manager.getKey())) { - try { - if (manager.isExclusive() && !masks.isEmpty()) { - continue; - } - final FaweMask mask = manager.getMask(player, FaweMaskManager.MaskType.getDefaultMaskType(), isWhitelist); - if (mask != null) { - regions.add(mask.getRegion()); - masks.add(mask); - if (manager.isExclusive()) { - break; + synchronized (masks) { + for (FaweMaskManager manager : managers) { + if (player.hasPermission("fawe." + manager.getKey())) { + try { + if (manager.isExclusive() && !masks.isEmpty()) { + continue; } + final FaweMask mask = manager.getMask( + player, + FaweMaskManager.MaskType.getDefaultMaskType(), + isWhitelist, + masks.isEmpty() + ); + if (mask != null) { + regions.add(mask.getRegion()); + masks.add(mask); + if (manager.isExclusive()) { + break; + } + } + } catch (Throwable e) { + e.printStackTrace(); } - } catch (Throwable e) { - e.printStackTrace(); + } else { + player.printError(TextComponent.of("Missing permission " + "fawe." + manager.getKey())); } - } else { - player.printError(TextComponent.of("Missing permission " + "fawe." + manager.getKey())); } - } - if (isWhitelist) { - regions.addAll(backupRegions); - if (!masks.isEmpty()) { - player.setMeta("lastMask", masks); - } else { - player.deleteMeta("lastMask"); + if (isWhitelist) { + if (!masks.isEmpty()) { + player.setMeta("lastMask", masks); + } else { + player.deleteMeta("lastMask"); + } } } return regions.toArray(new Region[0]);