From 5e702f80a61239551b47af1074855ae076db7de1 Mon Sep 17 00:00:00 2001 From: stonar96 Date: Mon, 9 Aug 2021 05:00:02 +0200 Subject: [PATCH] Add inheritance for all flags (#1787) --- .../commands/region/RegionCommands.java | 7 +++--- .../region/RegionPrintoutBuilder.java | 4 +++- .../commands/task/RegionLister.java | 6 ++++- .../protection/FlagValueCalculator.java | 23 +++++++++++++++---- .../AbstractRegionOverlapAssociation.java | 7 ++++-- .../worldguard/protection/flags/Flags.java | 2 +- 6 files changed, 37 insertions(+), 12 deletions(-) diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommands.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommands.java index 299f74d3..b0ef7fff 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommands.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommands.java @@ -52,6 +52,7 @@ import com.sk89q.worldguard.config.WorldConfiguration; import com.sk89q.worldguard.internal.permission.RegionPermissionModel; import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.FlagValueCalculator; import com.sk89q.worldguard.protection.flags.Flag; import com.sk89q.worldguard.protection.flags.FlagContext; import com.sk89q.worldguard.protection.flags.Flags; @@ -1095,21 +1096,21 @@ public void teleport(CommandContext args, Actor sender) throws CommandException // -s for spawn location if (args.hasFlag('s')) { - teleportLocation = existing.getFlag(Flags.SPAWN_LOC); + teleportLocation = FlagValueCalculator.getEffectiveFlagOf(existing, Flags.SPAWN_LOC, player); if (teleportLocation == null) { throw new CommandException( "The region has no spawn point associated."); } } else { - teleportLocation = existing.getFlag(Flags.TELE_LOC); + teleportLocation = FlagValueCalculator.getEffectiveFlagOf(existing, Flags.TELE_LOC, player); if (teleportLocation == null) { throw new CommandException("The region has no teleport point associated."); } } - String message = existing.getFlag(Flags.TELE_MESSAGE); + String message = FlagValueCalculator.getEffectiveFlagOf(existing, Flags.TELE_MESSAGE, player); // If the flag isn't set, use the default message // If message.isEmpty(), no message is sent by LocalPlayer#teleport(...) diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionPrintoutBuilder.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionPrintoutBuilder.java index 2066d131..4928e1dd 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionPrintoutBuilder.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionPrintoutBuilder.java @@ -36,6 +36,8 @@ import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.domains.DefaultDomain; import com.sk89q.worldguard.internal.permission.RegionPermissionModel; +import com.sk89q.worldguard.protection.FlagValueCalculator; +import com.sk89q.worldguard.protection.association.RegionAssociable; import com.sk89q.worldguard.protection.flags.Flag; import com.sk89q.worldguard.protection.flags.Flags; import com.sk89q.worldguard.protection.flags.RegionGroupFlag; @@ -315,7 +317,7 @@ public void appendBounds() { .clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg select " + region.getId())); } builder.append(bound); - final Location teleFlag = region.getFlag(Flags.TELE_LOC); + final Location teleFlag = FlagValueCalculator.getEffectiveFlagOf(region, Flags.TELE_LOC, perms.getSender() instanceof RegionAssociable ? (RegionAssociable) perms.getSender() : null); if (teleFlag != null && perms != null && perms.mayTeleportTo(region)) { builder.append(TextComponent.space().append(TextComponent.of("[Teleport]", TextColor.GRAY) .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/task/RegionLister.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/task/RegionLister.java index e5eaad74..ed75fc67 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/task/RegionLister.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/task/RegionLister.java @@ -24,6 +24,7 @@ import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.worldguard.util.profile.Profile; import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.formatting.component.PaginationBox; import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TextComponent; @@ -33,6 +34,8 @@ import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.domains.DefaultDomain; import com.sk89q.worldguard.internal.permission.RegionPermissionModel; +import com.sk89q.worldguard.protection.FlagValueCalculator; +import com.sk89q.worldguard.protection.association.RegionAssociable; import com.sk89q.worldguard.protection.flags.Flags; import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.regions.ProtectedRegion; @@ -261,7 +264,8 @@ public Component getComponent(int number) { .clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/rg info -w \"" + world + "\" " + entry.region.getId())))); } - if (perms != null && entry.region.getFlag(Flags.TELE_LOC) != null && perms.mayTeleportTo(entry.region)) { + final Location teleFlag = FlagValueCalculator.getEffectiveFlagOf(entry.region, Flags.TELE_LOC, perms.getSender() instanceof RegionAssociable ? (RegionAssociable) perms.getSender() : null); + if (perms != null && teleFlag != null && perms.mayTeleportTo(entry.region)) { builder.append(TextComponent.space().append(TextComponent.of("[TP]", TextColor.GRAY) .hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to teleport"))) .clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java index a8f4fffd..c6cdc189 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/FlagValueCalculator.java @@ -297,7 +297,12 @@ public V queryMapValue(@Nullable RegionAssociable subject, MapFlag } @Nullable - private V getEffectiveMapValue(ProtectedRegion region, MapFlag mapFlag, K key, RegionAssociable subject) { + public V getEffectiveMapValue(ProtectedRegion region, MapFlag mapFlag, K key, RegionAssociable subject) { + return getEffectiveMapValueOf(region, mapFlag, key, subject); + } + + @Nullable + public static V getEffectiveMapValueOf(ProtectedRegion region, MapFlag mapFlag, K key, RegionAssociable subject) { List seen = new ArrayList<>(); ProtectedRegion current = region; @@ -450,7 +455,11 @@ && getEffectiveFlag(region, Flags.PASSTHROUGH, subject) != State.ALLOW) { * @return the priority */ public int getPriority(final ProtectedRegion region) { - if (region == globalRegion) { + return getPriorityOf(region); + } + + public static int getPriorityOf(final ProtectedRegion region) { + if (region.getId().equals(ProtectedRegion.GLOBAL_REGION)) { return Integer.MIN_VALUE; } else { return region.getPriority(); @@ -466,9 +475,15 @@ public int getPriority(final ProtectedRegion region) { * @param subject an subject object * @return the value */ - @SuppressWarnings("unchecked") + @Nullable public V getEffectiveFlag(final ProtectedRegion region, Flag flag, @Nullable RegionAssociable subject) { - if (region == globalRegion) { + return getEffectiveFlagOf(region, flag, subject); + } + + @SuppressWarnings("unchecked") + @Nullable + public static V getEffectiveFlagOf(final ProtectedRegion region, Flag flag, @Nullable RegionAssociable subject) { + if (region.getId().equals(ProtectedRegion.GLOBAL_REGION)) { if (flag == Flags.PASSTHROUGH) { // Has members/owners -> the global region acts like // a regular region without PASSTHROUGH diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/association/AbstractRegionOverlapAssociation.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/association/AbstractRegionOverlapAssociation.java index 9b0a42e0..0cbd78fe 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/association/AbstractRegionOverlapAssociation.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/association/AbstractRegionOverlapAssociation.java @@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.sk89q.worldguard.domains.Association; +import com.sk89q.worldguard.protection.FlagValueCalculator; import com.sk89q.worldguard.protection.flags.Flags; import com.sk89q.worldguard.protection.regions.ProtectedRegion; @@ -69,7 +70,8 @@ private boolean checkNonplayerProtectionDomains(Iterable regionDomains = region.getFlag(Flags.NONPLAYER_PROTECTION_DOMAINS); + // Potential endless recurrence? No, because there is no region group flag. + Set regionDomains = FlagValueCalculator.getEffectiveFlagOf(region, Flags.NONPLAYER_PROTECTION_DOMAINS, this); if (regionDomains == null || regionDomains.isEmpty()) { continue; @@ -111,7 +113,8 @@ public Association getAssociation(List regions) { source = this.source; } - if (checkNonplayerProtectionDomains(source, region.getFlag(Flags.NONPLAYER_PROTECTION_DOMAINS))) { + // Potential endless recurrence? No, because there is no region group flag. + if (checkNonplayerProtectionDomains(source, FlagValueCalculator.getEffectiveFlagOf(region, Flags.NONPLAYER_PROTECTION_DOMAINS, this))) { return Association.OWNER; } diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/Flags.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/Flags.java index 31292475..c3edeaec 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/Flags.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/Flags.java @@ -46,7 +46,7 @@ public final class Flags { // Overrides membership check public static final StateFlag PASSTHROUGH = register(new StateFlag("passthrough", false)); - public static final SetFlag NONPLAYER_PROTECTION_DOMAINS = register(new SetFlag<>("nonplayer-protection-domains", new StringFlag(null))); + public static final SetFlag NONPLAYER_PROTECTION_DOMAINS = register(new SetFlag<>("nonplayer-protection-domains", null, new StringFlag(null))); // This flag is unlike the others. It forces the checking of region membership public static final StateFlag BUILD = register(new BuildFlag("build", true));