Add non-player members

This commit is contained in:
stonar96 2022-10-08 14:20:29 +02:00
parent c8a6e598f8
commit 2dff68071f
12 changed files with 217 additions and 41 deletions

View File

@ -296,6 +296,7 @@ public class BukkitWorldConfiguration extends YamlWorldConfiguration {
maxClaimVolume = getInt("regions.max-claim-volume", 30000);
claimOnlyInsideExistingRegions = getBoolean("regions.claim-only-inside-existing-regions", false);
setParentOnClaim = getString("regions.set-parent-on-claim", "");
nonplayerBorderBypassOnClaim = getBoolean("regions.nonplayer-border-bypass-on-claim", false);
boundedLocationFlags = getBoolean("regions.location-flags-only-inside-regions", false);
maxRegionCountPerPlayer = getInt("regions.max-region-count-per-player.default", 7);

View File

@ -64,6 +64,8 @@ import com.sk89q.worldguard.bukkit.util.Events;
import com.sk89q.worldguard.commands.GeneralCommands;
import com.sk89q.worldguard.commands.ProtectionCommands;
import com.sk89q.worldguard.commands.ToggleCommands;
import com.sk89q.worldguard.domains.CustomDomain;
import com.sk89q.worldguard.domains.registry.CustomDomainContext;
import com.sk89q.worldguard.domains.registry.SimpleDomainRegistry;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.Flags;
@ -93,8 +95,14 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -132,6 +140,61 @@ public class WorldGuardPlugin extends JavaPlugin {
return inst;
}
@Override
public void onLoad() {
WorldGuard.getInstance().getDomainRegistry().register("nonplayer-protection-domains", n -> new CustomDomain(n) {
private final Set<String> nonplayerProtectionDomains = new HashSet<>();
@Override
public void parseInput(CustomDomainContext context) {
setDirty(true);
nonplayerProtectionDomains.addAll(Arrays.asList(context.getUserInput().split(",")));
}
@Override
public void unmarshal(Object o) {
nonplayerProtectionDomains.clear();
nonplayerProtectionDomains.addAll((Collection<? extends String>) o);
}
@Override
public Object marshal() {
return new ArrayList<>(nonplayerProtectionDomains);
}
@Override
public boolean contains(UUID uniqueId) {
return false;
}
@Override
public boolean contains(String playerName) {
return false;
}
@Override
public boolean containsNonplayer(String nonplayerProtectionDomain) {
return nonplayerProtectionDomains.contains(nonplayerProtectionDomain);
}
@Override
public int size() {
return nonplayerProtectionDomains.size();
}
@Override
public void clear() {
setDirty(true);
nonplayerProtectionDomains.clear();
}
@Override
public String toString() {
return " " + nonplayerProtectionDomains;
}
});
}
/**
* Called on plugin enable.
*/

View File

@ -53,6 +53,9 @@ import com.sk89q.worldguard.commands.task.RegionManagerSaver;
import com.sk89q.worldguard.commands.task.RegionRemover;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.domains.CustomDomain;
import com.sk89q.worldguard.domains.registry.CustomDomainContext;
import com.sk89q.worldguard.domains.registry.InvalidDomainFormat;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.FlagValueCalculator;
@ -83,7 +86,9 @@ import com.sk89q.worldguard.util.Enums;
import com.sk89q.worldguard.util.logging.LoggerToChatHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.logging.Level;
@ -330,6 +335,19 @@ public final class RegionCommands extends RegionCommandsBase {
}
}
if (wcfg.nonplayerBorderBypassOnClaim) {
CustomDomain customDomain = WorldGuard.getInstance().getDomainRegistry().createDomain("nonplayer-protection-domains");
try {
customDomain.parseInput(CustomDomainContext.create().setInput(player.getUniqueId().toString()).build());
} catch (InvalidDomainFormat e) {
throw new CommandException(e.getMessage());
}
region.getOwners().addCustomDomain(customDomain);
region.setFlag(Flags.NONPLAYER_PROTECTION_DOMAINS, new HashSet<>(Arrays.asList(player.getUniqueId().toString())));
}
region.getOwners().addPlayer(player);
manager.addRegion(region);
player.print(TextComponent.of(String.format("A new region has been claimed named '%s'.", id)));

View File

@ -130,6 +130,7 @@ public abstract class WorldConfiguration {
public int maxClaimVolume;
public boolean claimOnlyInsideExistingRegions;
public String setParentOnClaim;
public boolean nonplayerBorderBypassOnClaim;
public int maxRegionCountPerPlayer;
public boolean antiWolfDumbness;
public boolean signChestProtection;

View File

@ -324,6 +324,11 @@ public class DefaultDomain implements Domain, ChangeTracked {
return playerDomain.contains(playerName);
}
@Override
public boolean containsNonplayer(String nonplayerProtectionDomain) {
return customDomains.stream().anyMatch(d -> d.containsNonplayer(nonplayerProtectionDomain));
}
@Override
public int size() {
return groupDomain.size() + playerDomain.size() + customDomains.size();

View File

@ -58,6 +58,14 @@ public interface Domain {
@Deprecated
boolean contains(String playerName);
/**
* Returns true if a domain contains a non-player.
*
* @param nonplayerProtectionDomain the non-player protection domain to check
* @return whether this domain contains {@code nonplayerProtectionDomain}
*/
boolean containsNonplayer(String nonplayerProtectionDomain);
/**
* Get the number of entries.
*

View File

@ -120,6 +120,11 @@ public class GroupDomain implements Domain, ChangeTracked {
return false; // GroupDomains can't contain player names.
}
@Override
public boolean containsNonplayer(String nonplayerProtectionDomain) {
return false; // GroupDomains can't contain non-players.
}
@Override
public int size() {
return groups.size();

View File

@ -184,6 +184,11 @@ public class PlayerDomain implements Domain, ChangeTracked {
return names.contains(playerName.trim().toLowerCase());
}
@Override
public boolean containsNonplayer(String nonplayerProtectionDomain) {
return false; // PlayerDomains can't contain non-players.
}
@Override
public int size() {
return names.size() + uniqueIds.size();

View File

@ -58,6 +58,11 @@ public class UnknownDomain extends CustomDomain {
return false;
}
@Override
public boolean containsNonplayer(String nonplayerProtectionDomain) {
return false;
}
@Override
public int size() {
return 0;

View File

@ -22,13 +22,9 @@ package com.sk89q.worldguard.protection.association;
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;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -64,39 +60,22 @@ public abstract class AbstractRegionOverlapAssociation implements RegionAssociab
this.maxPriorityRegions = bestRegions;
}
private boolean checkNonplayerProtectionDomains(Iterable<? extends ProtectedRegion> source, Collection<?> domains) {
if (source == null || domains == null || domains.isEmpty()) {
return false;
}
for (ProtectedRegion region : source) {
// Potential endless recurrence? No, because there is no region group flag.
Set<String> regionDomains = FlagValueCalculator.getEffectiveFlagOf(region, Flags.NONPLAYER_PROTECTION_DOMAINS, this);
if (regionDomains == null || regionDomains.isEmpty()) {
continue;
}
if (!Collections.disjoint(regionDomains, domains)) {
return true;
}
}
return false;
}
@Override
public Association getAssociation(List<ProtectedRegion> regions) {
checkNotNull(source);
boolean member = false;
for (ProtectedRegion region : regions) {
while (region != null) {
if ((region.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty())) {
ProtectedRegion current = region;
while (current != null) {
if ((current.getId().equals(ProtectedRegion.GLOBAL_REGION) && source.isEmpty())) {
return Association.OWNER;
}
if (source.contains(region)) {
if (source.contains(current)) {
if (useMaxPriorityAssociation) {
int priority = region.getPriority();
int priority = current.getPriority();
if (priority == maxPriority) {
return Association.OWNER;
}
@ -105,23 +84,24 @@ public abstract class AbstractRegionOverlapAssociation implements RegionAssociab
}
}
Set<ProtectedRegion> source;
current = current.getParent();
}
if (useMaxPriorityAssociation) {
source = maxPriorityRegions;
} else {
source = this.source;
}
Set<ProtectedRegion> source;
// 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;
}
if (useMaxPriorityAssociation) {
source = maxPriorityRegions;
} else {
source = this.source;
}
region = region.getParent();
if (source.stream().anyMatch(region::isOwner)) {
return Association.OWNER;
} else if (!member && source.stream().anyMatch(region::isMember)) {
member = true;
}
}
return Association.NON_MEMBER;
return member ? Association.MEMBER : Association.NON_MEMBER;
}
}

View File

@ -26,7 +26,9 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.FlagValueCalculator;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.util.ChangeTracked;
import com.sk89q.worldguard.util.Normal;
@ -35,6 +37,7 @@ import java.awt.geom.Line2D;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;
@ -325,6 +328,36 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
return false;
}
/**
* Checks whether a region is an owner of this region or any of its parents.
*
* @param region region to check
* @return whether an owner
*/
public boolean isOwner(ProtectedRegion region) {
checkNotNull(region);
Set<String> nonplayerProtectionDomains = FlagValueCalculator.getEffectiveFlagOf(region, Flags.NONPLAYER_PROTECTION_DOMAINS, null);
if (nonplayerProtectionDomains == null) {
return false;
}
if (nonplayerProtectionDomains.stream().anyMatch(owners::containsNonplayer)) {
return true;
}
ProtectedRegion curParent = getParent();
while (curParent != null) {
if (nonplayerProtectionDomains.stream().anyMatch(curParent.getOwners()::containsNonplayer)) {
return true;
}
curParent = curParent.getParent();
}
return false;
}
/**
* Checks whether a player is a member OR OWNER of the region
* or any of its parents.
@ -374,6 +407,23 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
return false;
}
/**
* Checks whether a region is a member OR OWNER of this region
* or any of its parents.
*
* @param region region to check
* @return whether an owner or member
*/
public boolean isMember(ProtectedRegion region) {
checkNotNull(region);
if (isOwner(region)) {
return true;
}
return isMemberOnly(region);
}
/**
* Checks whether a player is a member of the region or any of its parents.
*
@ -399,6 +449,36 @@ public abstract class ProtectedRegion implements ChangeTracked, Comparable<Prote
return false;
}
/**
* Checks whether a region is a member of this region or any of its parents.
*
* @param region region to check
* @return whether an member
*/
public boolean isMemberOnly(ProtectedRegion region) {
checkNotNull(region);
Set<String> nonplayerProtectionDomains = FlagValueCalculator.getEffectiveFlagOf(region, Flags.NONPLAYER_PROTECTION_DOMAINS, null);
if (nonplayerProtectionDomains == null) {
return false;
}
if (nonplayerProtectionDomains.stream().anyMatch(members::containsNonplayer)) {
return true;
}
ProtectedRegion curParent = getParent();
while (curParent != null) {
if (nonplayerProtectionDomains.stream().anyMatch(curParent.getMembers()::containsNonplayer)) {
return true;
}
curParent = curParent.getParent();
}
return false;
}
/**
* Get a flag's value.
*

View File

@ -57,6 +57,11 @@ public class CustomUUIDDomain extends CustomDomain {
return false;
}
@Override
public boolean containsNonplayer(String nonplayerProtectionDomain) {
return false;
}
@Override
public void clear() {
test = null;