From 40317394991d09dd10e7e2d8a4c6701f6c5d54b3 Mon Sep 17 00:00:00 2001
From: JOO200
Date: Wed, 29 Dec 2021 21:20:54 +0100
Subject: [PATCH 01/11] Add Api Domains to add custom domains
---
.../worldguard/bukkit/WorldGuardPlugin.java | 2 +
.../java/com/sk89q/worldguard/WorldGuard.java | 13 ++
.../sk89q/worldguard/domains/ApiDomain.java | 69 ++++++++
.../worldguard/domains/DefaultDomain.java | 42 ++++-
.../registry/DomainConflictException.java | 26 +++
.../domains/registry/DomainRegistry.java | 91 +++++++++++
.../registry/SimpleDomainRegistry.java | 150 ++++++++++++++++++
.../domains/registry/UnknownDomain.java | 67 ++++++++
.../managers/storage/file/YamlRegionFile.java | 16 ++
9 files changed, 472 insertions(+), 4 deletions(-)
create mode 100644 worldguard-core/src/main/java/com/sk89q/worldguard/domains/ApiDomain.java
create mode 100644 worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainConflictException.java
create mode 100644 worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
create mode 100644 worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
create mode 100644 worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
diff --git a/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java
index e0f83634a..e95d1aec1 100644
--- a/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java
+++ b/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java
@@ -64,6 +64,7 @@
import com.sk89q.worldguard.commands.GeneralCommands;
import com.sk89q.worldguard.commands.ProtectionCommands;
import com.sk89q.worldguard.commands.ToggleCommands;
+import com.sk89q.worldguard.domains.registry.SimpleDomainRegistry;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
@@ -211,6 +212,7 @@ public void onEnable() {
});
((SimpleFlagRegistry) WorldGuard.getInstance().getFlagRegistry()).setInitialized(true);
+ ((SimpleDomainRegistry) WorldGuard.getInstance().getDomainRegistry()).setInitialized(true);
// Enable metrics
final Metrics metrics = new Metrics(this, BSTATS_PLUGIN_ID); // bStats plugin id
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/WorldGuard.java b/worldguard-core/src/main/java/com/sk89q/worldguard/WorldGuard.java
index 637eee7bd..cc287c6c3 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/WorldGuard.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/WorldGuard.java
@@ -24,6 +24,8 @@
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.sk89q.minecraft.util.commands.CommandException;
+import com.sk89q.worldguard.domains.registry.DomainRegistry;
+import com.sk89q.worldguard.domains.registry.SimpleDomainRegistry;
import com.sk89q.worldguard.util.profile.cache.HashMapCache;
import com.sk89q.worldguard.util.profile.cache.ProfileCache;
import com.sk89q.worldguard.util.profile.cache.SQLiteCache;
@@ -55,6 +57,7 @@ public final class WorldGuard {
private WorldGuardPlatform platform;
private final SimpleFlagRegistry flagRegistry = new SimpleFlagRegistry();
+ private final SimpleDomainRegistry domainRegistry = new SimpleDomainRegistry();
private final Supervisor supervisor = new SimpleSupervisor();
private ProfileCache profileCache;
private ProfileService profileService;
@@ -116,6 +119,16 @@ public FlagRegistry getFlagRegistry() {
return this.flagRegistry;
}
+
+ /**
+ * Get the domain registry.
+ *
+ * @return the domain registry
+ */
+ public DomainRegistry getDomainRegistry() {
+ return this.domainRegistry;
+ }
+
/**
* Get the supervisor.
*
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/ApiDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/ApiDomain.java
new file mode 100644
index 000000000..49e7ddddf
--- /dev/null
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/ApiDomain.java
@@ -0,0 +1,69 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldguard.domains;
+
+import com.sk89q.worldguard.LocalPlayer;
+
+import java.util.regex.Pattern;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public abstract class ApiDomain implements Domain {
+ private static final Pattern VALID_NAME = Pattern.compile("^[:A-Za-z0-9\\-]{1,40}$");
+
+ private String name;
+
+ public ApiDomain(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the name of the domain resolver.
+ *
+ * @return The name of the domain
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Convert the current Domain to a storable foramt
+ *
+ * @return The marshalled type
+ */
+ public abstract Object marshal();
+
+ /**
+ * Test whether a flag name is valid.
+ *
+ * @param name The flag name
+ * @return Whether the name is valid
+ */
+ public static boolean isValidName(String name) {
+ checkNotNull(name, "name");
+ return VALID_NAME.matcher(name).matches();
+ }
+
+
+ @Override
+ public boolean contains(LocalPlayer player) {
+ return contains(player.getUniqueId());
+ }
+}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
index 3030a9c10..601b1fbae 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
@@ -22,8 +22,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import com.sk89q.worldguard.util.profile.Profile;
-import com.sk89q.worldguard.util.profile.cache.ProfileCache;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
@@ -31,9 +29,14 @@
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.util.ChangeTracked;
+import com.sk89q.worldguard.util.profile.Profile;
+import com.sk89q.worldguard.util.profile.cache.ProfileCache;
import javax.annotation.Nullable;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -50,6 +53,8 @@ public class DefaultDomain implements Domain, ChangeTracked {
private PlayerDomain playerDomain = new PlayerDomain();
private GroupDomain groupDomain = new GroupDomain();
+ private Set apiDomains = new HashSet<>();
+
/**
* Create a new domain.
*/
@@ -104,6 +109,35 @@ public void setGroupDomain(GroupDomain groupDomain) {
this.groupDomain = new GroupDomain(groupDomain);
}
+ /**
+ * Add new api domains
+ *
+ * @param apiDomain a domain
+ */
+ public void addApiDomain(ApiDomain apiDomain) {
+ checkNotNull(apiDomain);
+ this.apiDomains.add(apiDomain);
+ }
+
+ /**
+ * Set the api domains to a specified value
+ *
+ * @param apiDomains the domains
+ */
+ public void setApiDomains(Collection apiDomains) {
+ checkNotNull(apiDomains);
+ this.apiDomains = new HashSet<>(apiDomains);
+ }
+
+ /**
+ * Get all api domains
+ *
+ * @return a unmodifiable copy of the domains
+ */
+ public Set getApiDomains() {
+ return Collections.unmodifiableSet(this.apiDomains);
+ }
+
/**
* Add the given player to the domain, identified by the player's name.
*
@@ -242,12 +276,12 @@ public Set getGroups() {
@Override
public boolean contains(LocalPlayer player) {
- return playerDomain.contains(player) || groupDomain.contains(player);
+ return playerDomain.contains(player) || groupDomain.contains(player) || apiDomains.stream().anyMatch(d -> d.contains(player));
}
@Override
public boolean contains(UUID uniqueId) {
- return playerDomain.contains(uniqueId);
+ return playerDomain.contains(uniqueId) || apiDomains.stream().anyMatch(d -> d.contains(uniqueId));
}
@Override
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainConflictException.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainConflictException.java
new file mode 100644
index 000000000..4ab7e933b
--- /dev/null
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainConflictException.java
@@ -0,0 +1,26 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldguard.domains.registry;
+
+public class DomainConflictException extends RuntimeException {
+ public DomainConflictException(String message) {
+ super(message);
+ }
+}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
new file mode 100644
index 000000000..bad155147
--- /dev/null
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
@@ -0,0 +1,91 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldguard.domains.registry;
+
+import com.sk89q.worldguard.domains.ApiDomain;
+
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Map;
+
+public interface DomainRegistry extends Iterable> {
+ abstract static class Factory {
+ public abstract T create(String name, Object values);
+ }
+
+ /**
+ * Register a new Domain
+ *
+ * There may be an appropiate time to register domains. if domains are
+ * registered outside this time, then an exception may be thrown.
+ *
+ * @param domain The domain
+ * @throws DomainConflictException Thrown when already an existing domain exists with the same name
+ * @throws IllegalStateException If it is not the right time to register new domains
+ */
+ void register(String name, Factory> domain) throws DomainConflictException;
+
+ /**
+ * Register a collection of domains.
+ *
+ * There may be an appropriate time to register domains. If domains are
+ * registered outside this time, then an exception may be thrown.
+ *
+ * If there is a domain conflict, then an error will be logged but
+ * no exception will be thrown.
+ *
+ * @param flags a collection of flags
+ * @throws IllegalStateException If it is not the right time to register new flags
+ */
+ void registerAll(Map> domains);
+
+ /**
+ * Get the domain by its name.
+ *
+ * @param name The name
+ * @return The domain, if it has been registered
+ */
+ @Nullable
+ Factory> get(String name);
+
+ /**
+ * Get all domains
+ *
+ * @return All domains
+ */
+ List> getAll();
+
+ /**
+ * Unmarshal a raw map of values into a list of domains with their
+ * unmarshalled values.
+ *
+ * @param rawValues The raw values map
+ * @param createUnknown Whether "just in time" domains should be created for unknown domains
+ * @return The unmarshalled domain list
+ */
+ List unmarshal(Map rawValues, boolean createUnknown);
+
+ /**
+ * Get the number of registered domains.
+ *
+ * @return The number of registered domains
+ */
+ int size();
+}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
new file mode 100644
index 000000000..11a8ebaf5
--- /dev/null
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
@@ -0,0 +1,150 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldguard.domains.registry;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Maps;
+import com.sk89q.worldguard.domains.ApiDomain;
+
+import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class SimpleDomainRegistry implements DomainRegistry {
+ private static final Logger log = Logger.getLogger(SimpleDomainRegistry.class.getCanonicalName());
+
+ private final Object lock = new Object();
+ private final ConcurrentMap> domains = Maps.newConcurrentMap();
+ private boolean initialized = false;
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ public void setInitialized(boolean initialized) {
+ this.initialized = initialized;
+ }
+
+ @Override
+ public void register(String name, Factory> domain) throws DomainConflictException {
+ synchronized (lock) {
+ if (initialized) {
+ throw new IllegalStateException("New flags cannot be registered at this time");
+ }
+
+ forceRegister(name, domain);
+ }
+ }
+
+ @Override
+ public void registerAll(Map> domains) {
+ synchronized (lock) {
+ for (Map.Entry> entry : domains.entrySet()) {
+ try {
+ register(entry.getKey(), entry.getValue());
+ } catch (DomainConflictException e) {
+ log.log(Level.WARNING, e.getMessage());
+ }
+ }
+ }
+ }
+
+ private > T forceRegister(String name, T domain) throws DomainConflictException {
+ checkNotNull(domain, "domain");
+ checkNotNull(name, "name");
+
+ synchronized (lock) {
+ if (domains.containsKey(name)) {
+ throw new DomainConflictException("A domain already exists by the name " + name);
+ }
+
+ domains.put(name, domain);
+ }
+
+ return domain;
+ }
+
+ @Nullable
+ @Override
+ public Factory> get(String name) {
+ checkNotNull(name, "name");
+ return domains.get(name.toLowerCase());
+ }
+
+ @Override
+ public List> getAll() {
+ return ImmutableList.copyOf(domains.values());
+ }
+
+ private ApiDomain getOrCreate(String name, Object value, boolean createUnknown) {
+ Factory extends ApiDomain> domain = get(name);
+
+ if (domain != null) {
+ return domain.create(name, value);
+ }
+
+ synchronized (lock) {
+ domain = get(name); // Load again because the previous load was not synchronized
+ if (domain != null) {
+ return domain.create(name, value);
+ }
+ if (createUnknown) {
+ Factory unknownFactory = forceRegister(name, UnknownDomain.FACTORY);
+ return unknownFactory.create(name, value);
+ }
+ }
+ return null;
+ }
+
+ public List unmarshal(Map rawValues, boolean createUnknown) {
+ checkNotNull(rawValues, "rawValues");
+
+ List domainList = new ArrayList<>();
+
+ for (Map.Entry entry : rawValues.entrySet()) {
+ try {
+ ApiDomain domain = getOrCreate(entry.getKey(), entry.getValue(), createUnknown);
+ domainList.add(domain);
+ } catch (Throwable e) {
+ log.log(Level.WARNING, "Failed to unmarshal domain for " + entry.getKey(), e);
+ }
+ }
+ return domainList;
+ }
+
+ @Override
+ public int size() {
+ return domains.size();
+ }
+
+ @Override
+ public Iterator> iterator() {
+ return Iterators.unmodifiableIterator(domains.values().iterator());
+ }
+}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
new file mode 100644
index 000000000..551f5c657
--- /dev/null
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
@@ -0,0 +1,67 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldguard.domains.registry;
+
+import com.sk89q.worldguard.domains.ApiDomain;
+
+import javax.annotation.Nullable;
+import java.util.UUID;
+
+public class UnknownDomain extends ApiDomain {
+ public static DomainRegistry.Factory FACTORY = new DomainRegistry.Factory() {
+ @Override
+ public UnknownDomain create(String name, Object values) {
+ return new UnknownDomain(name, values);
+ }
+ };
+
+ Object o;
+
+ public UnknownDomain(String name, Object values) {
+ super(name);
+ this.o = values;
+ }
+
+
+ @Override
+ public Object marshal() {
+ return o;
+ }
+
+ @Override
+ public boolean contains(UUID uniqueId) {
+ return false;
+ }
+
+ @Override
+ public boolean contains(String playerName) {
+ return false;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public void clear() {
+ o = null;
+ }
+}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java
index 9aebc5ac7..1d9187412 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java
@@ -27,6 +27,8 @@
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
+import com.sk89q.worldguard.WorldGuard;
+import com.sk89q.worldguard.domains.ApiDomain;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.flags.FlagUtil;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
@@ -284,6 +286,12 @@ private DefaultDomain parseDomain(YAMLNode node) {
}
}
+ YAMLNode apiDomains = node.getNode("api");
+ if (apiDomains != null) {
+ List parsedDomains = WorldGuard.getInstance().getDomainRegistry().unmarshal(apiDomains.getMap(), true);
+ domain.setApiDomains(parsedDomains);
+ }
+
return domain;
}
@@ -304,6 +312,14 @@ private Map getDomainData(DefaultDomain domain) {
setDomainData(domainData, "unique-ids", domain.getUniqueIds());
setDomainData(domainData, "groups", domain.getGroups());
+ if (!domain.getApiDomains().isEmpty()) {
+ Map values = new HashMap<>();
+ for (ApiDomain apiDomain : domain.getApiDomains()) {
+ values.put(apiDomain.getName(), apiDomain.marshal());
+ }
+ domainData.put("api", values);
+ }
+
return domainData;
}
From 3b7c6fb9e1031424d08b2395b9a48ae94b2bc20a Mon Sep 17 00:00:00 2001
From: JOO200
Date: Thu, 30 Dec 2021 20:38:36 +0100
Subject: [PATCH 02/11] Improved api usage for CustomDomains
---
.../domains/registry/DomainFactory.java | 28 +++++++++++++++++++
.../domains/registry/DomainRegistry.java | 15 ++++------
.../registry/SimpleDomainRegistry.java | 20 ++++++-------
.../domains/registry/UnknownDomain.java | 7 +----
4 files changed, 45 insertions(+), 25 deletions(-)
create mode 100644 worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainFactory.java
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainFactory.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainFactory.java
new file mode 100644
index 000000000..7fff6f661
--- /dev/null
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainFactory.java
@@ -0,0 +1,28 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.sk89q.worldguard.domains.registry;
+
+import com.sk89q.worldguard.domains.ApiDomain;
+
+@FunctionalInterface
+public interface DomainFactory {
+ T create(String name, Object values);
+}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
index bad155147..ead7a7801 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
@@ -25,10 +25,7 @@
import java.util.List;
import java.util.Map;
-public interface DomainRegistry extends Iterable> {
- abstract static class Factory {
- public abstract T create(String name, Object values);
- }
+public interface DomainRegistry extends Iterable> {
/**
* Register a new Domain
@@ -40,7 +37,7 @@ abstract static class Factory {
* @throws DomainConflictException Thrown when already an existing domain exists with the same name
* @throws IllegalStateException If it is not the right time to register new domains
*/
- void register(String name, Factory> domain) throws DomainConflictException;
+ void register(String name, DomainFactory> domain) throws DomainConflictException;
/**
* Register a collection of domains.
@@ -51,10 +48,10 @@ abstract static class Factory {
* If there is a domain conflict, then an error will be logged but
* no exception will be thrown.
*
- * @param flags a collection of flags
+ * @param domains a collection of domain factories
* @throws IllegalStateException If it is not the right time to register new flags
*/
- void registerAll(Map> domains);
+ void registerAll(Map> domains);
/**
* Get the domain by its name.
@@ -63,14 +60,14 @@ abstract static class Factory {
* @return The domain, if it has been registered
*/
@Nullable
- Factory> get(String name);
+ DomainFactory> get(String name);
/**
* Get all domains
*
* @return All domains
*/
- List> getAll();
+ List> getAll();
/**
* Unmarshal a raw map of values into a list of domains with their
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
index 11a8ebaf5..9e6f56ce8 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
@@ -40,7 +40,7 @@ public class SimpleDomainRegistry implements DomainRegistry {
private static final Logger log = Logger.getLogger(SimpleDomainRegistry.class.getCanonicalName());
private final Object lock = new Object();
- private final ConcurrentMap> domains = Maps.newConcurrentMap();
+ private final ConcurrentMap> domains = Maps.newConcurrentMap();
private boolean initialized = false;
public boolean isInitialized() {
@@ -52,7 +52,7 @@ public void setInitialized(boolean initialized) {
}
@Override
- public void register(String name, Factory> domain) throws DomainConflictException {
+ public void register(String name, DomainFactory> domain) throws DomainConflictException {
synchronized (lock) {
if (initialized) {
throw new IllegalStateException("New flags cannot be registered at this time");
@@ -63,9 +63,9 @@ public void register(String name, Factory> domain) throws DomainConflictExcept
}
@Override
- public void registerAll(Map> domains) {
+ public void registerAll(Map> domains) {
synchronized (lock) {
- for (Map.Entry> entry : domains.entrySet()) {
+ for (Map.Entry> entry : domains.entrySet()) {
try {
register(entry.getKey(), entry.getValue());
} catch (DomainConflictException e) {
@@ -75,7 +75,7 @@ public void registerAll(Map> domains) {
}
}
- private > T forceRegister(String name, T domain) throws DomainConflictException {
+ private > T forceRegister(String name, T domain) throws DomainConflictException {
checkNotNull(domain, "domain");
checkNotNull(name, "name");
@@ -92,18 +92,18 @@ private > T forceRegister(String name, T domain) throws Dom
@Nullable
@Override
- public Factory> get(String name) {
+ public DomainFactory> get(String name) {
checkNotNull(name, "name");
return domains.get(name.toLowerCase());
}
@Override
- public List> getAll() {
+ public List> getAll() {
return ImmutableList.copyOf(domains.values());
}
private ApiDomain getOrCreate(String name, Object value, boolean createUnknown) {
- Factory extends ApiDomain> domain = get(name);
+ DomainFactory extends ApiDomain> domain = get(name);
if (domain != null) {
return domain.create(name, value);
@@ -115,7 +115,7 @@ private ApiDomain getOrCreate(String name, Object value, boolean createUnknown)
return domain.create(name, value);
}
if (createUnknown) {
- Factory unknownFactory = forceRegister(name, UnknownDomain.FACTORY);
+ DomainFactory unknownFactory = forceRegister(name, UnknownDomain.FACTORY);
return unknownFactory.create(name, value);
}
}
@@ -144,7 +144,7 @@ public int size() {
}
@Override
- public Iterator> iterator() {
+ public Iterator> iterator() {
return Iterators.unmodifiableIterator(domains.values().iterator());
}
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
index 551f5c657..fd2d431a4 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
@@ -25,12 +25,7 @@
import java.util.UUID;
public class UnknownDomain extends ApiDomain {
- public static DomainRegistry.Factory FACTORY = new DomainRegistry.Factory() {
- @Override
- public UnknownDomain create(String name, Object values) {
- return new UnknownDomain(name, values);
- }
- };
+ public static DomainFactory FACTORY = UnknownDomain::new;
Object o;
From 65a0cfad438c714101c321e67629008abf3f807f Mon Sep 17 00:00:00 2001
From: JOO200
Date: Sat, 1 Jan 2022 16:19:50 +0100
Subject: [PATCH 03/11] Renamed ApiDomain to CustomDomain, added commands to
modify CustomDomains
---
.../commands/CommandInputContext.java | 112 ++++++++++++
.../commands/region/MemberCommands.java | 162 +++++++++++++++++-
.../commands/region/RegionCommandsBase.java | 15 +-
.../{ApiDomain.java => CustomDomain.java} | 27 ++-
.../worldguard/domains/DefaultDomain.java | 103 ++++++++---
.../domains/registry/CustomDomainContext.java | 93 ++++++++++
.../domains/registry/DomainFactory.java | 6 +-
.../domains/registry/DomainRegistry.java | 8 +-
.../domains/registry/InvalidDomainFormat.java | 28 +++
.../registry/SimpleDomainRegistry.java | 39 +++--
.../domains/registry/UnknownDomain.java | 38 +++-
.../permission/RegionPermissionModel.java | 20 +++
.../protection/flags/FlagContext.java | 88 +---------
.../managers/storage/file/YamlRegionFile.java | 12 +-
.../protection/util/DomainInputResolver.java | 2 +-
15 files changed, 603 insertions(+), 150 deletions(-)
create mode 100644 worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java
rename worldguard-core/src/main/java/com/sk89q/worldguard/domains/{ApiDomain.java => CustomDomain.java} (68%)
create mode 100644 worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/CustomDomainContext.java
create mode 100644 worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/InvalidDomainFormat.java
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java
new file mode 100644
index 000000000..5aab831c4
--- /dev/null
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java
@@ -0,0 +1,112 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldguard.commands;
+
+import com.google.common.collect.Maps;
+import com.sk89q.worldedit.extension.platform.Actor;
+import com.sk89q.worldguard.LocalPlayer;
+import com.sk89q.worldguard.protection.flags.FlagContext;
+import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
+
+import javax.annotation.Nullable;
+import java.util.Map;
+
+public class CommandInputContext {
+ protected final Actor sender;
+ protected final String input;
+
+ protected Map context;
+
+ protected CommandInputContext(Actor sender, String input, Map values) {
+ this.sender = sender;
+ this.input = input;
+ this.context = values;
+ }
+
+ public void put(String name, Object value) {
+ context.put(name, value);
+ }
+
+ public Actor getSender() {
+ return sender;
+ }
+
+ public String getUserInput() {
+ return input;
+ }
+
+ /**
+ * Gets the CommandSender as a player.
+ *
+ * @return Player
+ * @throws InvalidFlagFormat if the sender is not a player
+ */
+ public LocalPlayer getPlayerSender() throws InvalidFlagFormat {
+ if (sender.isPlayer() && sender instanceof LocalPlayer) {
+ return (LocalPlayer) sender;
+ } else {
+ throw new InvalidFlagFormat("Not a player");
+ }
+ }
+
+ public Integer getUserInputAsInt() throws InvalidFlagFormat {
+ try {
+ return Integer.parseInt(input);
+ } catch (NumberFormatException e) {
+ throw new InvalidFlagFormat("Not a number: " + input);
+ }
+ }
+
+ public Double getUserInputAsDouble() throws InvalidFlagFormat {
+ try {
+ return Double.parseDouble(input);
+ } catch (NumberFormatException e) {
+ throw new InvalidFlagFormat("Not a number: " + input);
+ }
+ }
+
+ /**
+ * Get an object from the context by key name.
+ * May return null if the object does not exist in the context.
+ *
+ * @param name key name of the object
+ * @return the object matching the key, or null
+ */
+ @Nullable
+ public Object get(String name) {
+ return get(name, null);
+ }
+
+ /**
+ * Get an object from the context by key name.
+ * Will only return null if
+ * a) you provide null as the default
+ * b) the key has explicity been set to null
+ *
+ * @param name key name of the object
+ * @return the object matching the key
+ */
+ @Nullable
+ public Object get(String name, Object defaultValue) {
+ Object obj;
+ return (((obj = context.get(name)) != null) || context.containsKey(name)
+ ? obj : defaultValue);
+ }
+}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
index e41eb1b93..292683481 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
@@ -25,16 +25,30 @@
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
import com.sk89q.worldedit.extension.platform.Actor;
-import com.sk89q.worldedit.util.auth.AuthorizationException;
+import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
+import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
+import com.sk89q.worldedit.util.formatting.text.Component;
+import com.sk89q.worldedit.util.formatting.text.TextComponent;
+import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
+import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
+import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
+import com.sk89q.worldguard.domains.CustomDomain;
import com.sk89q.worldguard.domains.DefaultDomain;
+import com.sk89q.worldguard.domains.registry.DomainFactory;
+import com.sk89q.worldguard.domains.registry.DomainRegistry;
+import com.sk89q.worldguard.domains.registry.InvalidDomainFormat;
+import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.util.DomainInputResolver;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
import java.util.concurrent.Callable;
public class MemberCommands extends RegionCommandsBase {
@@ -229,4 +243,150 @@ public void removeOwner(CommandContext args, Actor sender) throws CommandExcepti
.onFailure("Failed to remove owners", worldGuard.getExceptionConverter())
.buildAndExec(worldGuard.getExecutorService());
}
+
+
+ /**
+ * Modify a custom domain for owner.
+ *
+ * @param args the arguments
+ * @param sender the sender
+ * @throws CommandException any error
+ */
+ @Command(aliases = {"ownerdomain"},
+ usage = " [-w world] [value]",
+ flags = "w:",
+ desc = "Set flags",
+ min = 2)
+ public void ownerDomain(CommandContext args, Actor sender) throws CommandException {
+ domain(args, sender, true);
+ }
+
+ /**
+ * Modify a custom domain for member.
+ *
+ * @param args the arguments
+ * @param sender the sender
+ * @throws CommandException any error
+ */
+ @Command(aliases = {"memberdomain"},
+ usage = " [-w world] [value]",
+ flags = "w:",
+ desc = "Set flags",
+ min = 2)
+ public void onMemberDomain(CommandContext args, Actor sender) throws CommandException {
+ domain(args, sender, false);
+ }
+
+ private void domain(CommandContext args, Actor sender, boolean isOwner) throws CommandException {
+ warnAboutSaveFailures(sender);
+
+ World world = checkWorld(args, sender, 'w'); // Get the world
+ String domainName = args.getString(1);
+ String value = args.argsLength() >= 3 ? args.getJoinedStrings(2) : null;
+ DomainRegistry domainRegistry = WorldGuard.getInstance().getDomainRegistry();
+ RegionPermissionModel permModel = getPermissionModel(sender);
+
+ // Lookup the existing region
+ RegionManager manager = checkRegionManager(world);
+ ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), true);
+
+ // Check permissions
+ if (!permModel.mayModifyCustomDomain(existing, isOwner, domainName)) {
+ throw new CommandPermissionsException();
+ }
+ String regionId = existing.getId();
+
+ DomainFactory> domainFactory = domainRegistry.get(domainName);
+
+ // We didn't find the domain, so let's print a list of domains that the user
+ // can use, and do nothing afterwards
+ if (domainFactory == null) {
+ AsyncCommandBuilder.wrap(new DomainListBuilder(domainRegistry, permModel, existing, world,
+ regionId, sender, domainName, isOwner), sender)
+ .registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), "Domain list for invalid domain command.")
+ .onSuccess((Component) null, sender::print)
+ .onFailure((Component) null, WorldGuard.getInstance().getExceptionConverter())
+ .buildAndExec(WorldGuard.getInstance().getExecutorService());
+ return;
+ }
+
+ DefaultDomain usedDomain = isOwner ? existing.getOwners() : existing.getMembers();
+
+ // Set the flag value if a value was set
+ if (value != null) {
+ // Set the flag if [value] was given even if [-g group] was given as well
+ try {
+ CustomDomain customDomain = domainFactory.create(domainName);
+ setDomain(existing, usedDomain, customDomain, sender, value);
+ } catch (InvalidDomainFormat e) {
+ throw new CommandException(e.getMessage());
+ }
+ // No value? Clear the flag, if -g isn't specified
+ } else {
+ usedDomain.removeCustomDomain(domainName);
+ }
+
+ RegionPrintoutBuilder printout = new RegionPrintoutBuilder(world.getName(), existing, null, sender);
+ printout.append(SubtleFormat.wrap("(Current domains: "));
+ printout.appendDomain();
+ printout.append(SubtleFormat.wrap(")"));
+ printout.send(sender);
+ checkSpawnOverlap(sender, world, existing);
+
+ }
+
+ private static class DomainListBuilder implements Callable {
+ private final DomainRegistry domainRegistry;
+ private final RegionPermissionModel permModel;
+ private final ProtectedRegion existing;
+ private final World world;
+ private final String regionId;
+ private final Actor sender;
+ private final boolean isOwner;
+ private final String domainName;
+
+ DomainListBuilder(DomainRegistry domainRegistry, RegionPermissionModel permModel, ProtectedRegion existing,
+ World world, String regionId, Actor sender, String domainName, boolean isOwner) {
+ this.domainRegistry = domainRegistry;
+ this.permModel = permModel;
+ this.existing = existing;
+ this.world = world;
+ this.regionId = regionId;
+ this.sender = sender;
+ this.domainName = domainName;
+ this.isOwner = isOwner;
+ }
+
+ @Override
+ public Component call() {
+ ArrayList domainList = new ArrayList<>();
+
+ // Need to build a list
+ for (Map.Entry> domainEntry : domainRegistry.getAll().entrySet()) {
+ if (!permModel.mayModifyCustomDomain(existing, isOwner, domainEntry.getKey())) {
+ continue;
+ }
+ domainList.add(domainEntry.getKey());
+ }
+ Collections.sort(domainList);
+
+ final TextComponent.Builder builder = TextComponent.builder("Available domains: ");
+
+ final HoverEvent clickToSet = HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to set"));
+ for (int i = 0; i < domainList.size(); i++) {
+ String flag = domainList.get(i);
+
+ builder.append(TextComponent.of(flag, i % 2 == 0 ? TextColor.GRAY : TextColor.WHITE)
+ .hoverEvent(clickToSet).clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
+ "/rg " + (isOwner ? "ownerdomains" : "memberdomains") +" -w \"" + world.getName() + "\" " + regionId + " " + flag + " ")));
+ if (i < domainList.size() + 1) {
+ builder.append(TextComponent.of(", "));
+ }
+ }
+
+ return ErrorFormat.wrap("Unknown domain specified: " + domainName)
+ .append(TextComponent.newline())
+ .append(builder.build());
+ }
+ }
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommandsBase.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommandsBase.java
index 7d2ca5a82..fa74e839b 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommandsBase.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommandsBase.java
@@ -32,18 +32,19 @@
import com.sk89q.worldedit.regions.Polygonal2DRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector;
-import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
-import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
-import com.sk89q.worldedit.util.formatting.text.format.TextDecoration;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
+import com.sk89q.worldguard.domains.CustomDomain;
+import com.sk89q.worldguard.domains.DefaultDomain;
+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.flags.Flag;
@@ -426,4 +427,12 @@ protected static V setFlag(ProtectedRegion region, Flag flag, Actor sende
return val;
}
+ /**
+ * Utility method to set a custom domain
+ */
+ protected static void setDomain(ProtectedRegion region, DefaultDomain target, CustomDomain domain, Actor sender, String value) throws InvalidDomainFormat {
+ domain.parseInput(CustomDomainContext.create().setSender(sender).setInput(value).setObject("region", region).build());
+ target.addCustomDomain(domain);
+ }
+
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/ApiDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
similarity index 68%
rename from worldguard-core/src/main/java/com/sk89q/worldguard/domains/ApiDomain.java
rename to worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
index 49e7ddddf..b48678083 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/ApiDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
@@ -20,17 +20,20 @@
package com.sk89q.worldguard.domains;
import com.sk89q.worldguard.LocalPlayer;
+import com.sk89q.worldguard.domains.registry.CustomDomainContext;
+import com.sk89q.worldguard.domains.registry.InvalidDomainFormat;
+import com.sk89q.worldguard.util.ChangeTracked;
import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.checkNotNull;
-public abstract class ApiDomain implements Domain {
- private static final Pattern VALID_NAME = Pattern.compile("^[:A-Za-z0-9\\-]{1,40}$");
+public abstract class CustomDomain implements Domain, ChangeTracked {
+ private static final Pattern VALID_NAME = Pattern.compile("^[A-Za-z0-9\\-]{1,40}$");
- private String name;
+ private final String name;
- public ApiDomain(String name) {
+ public CustomDomain(String name) {
this.name = name;
}
@@ -43,6 +46,22 @@ public String getName() {
return name;
}
+ /**
+ * Parse a given input to fill the context of the CustomDomain.
+ *
+ * @param context the {@link CustomDomainContext}
+ * @throws InvalidDomainFormat Raised if the input is invalid
+ */
+ public abstract void parseInput(CustomDomainContext context) throws InvalidDomainFormat;
+
+ /**
+ * Convert a raw type that was loaded (from a YAML file, for example)
+ * into the custom domain.
+ *
+ * @param o The object
+ */
+ public abstract void unmarshal(Object o);
+
/**
* Convert the current Domain to a storable foramt
*
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
index 601b1fbae..ae44a94df 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
@@ -53,7 +53,7 @@ public class DefaultDomain implements Domain, ChangeTracked {
private PlayerDomain playerDomain = new PlayerDomain();
private GroupDomain groupDomain = new GroupDomain();
- private Set apiDomains = new HashSet<>();
+ private Set customDomains = new HashSet<>();
/**
* Create a new domain.
@@ -110,23 +110,44 @@ public void setGroupDomain(GroupDomain groupDomain) {
}
/**
- * Add new api domains
+ * Add new custom domains
*
- * @param apiDomain a domain
+ * @param customDomain a domain
*/
- public void addApiDomain(ApiDomain apiDomain) {
- checkNotNull(apiDomain);
- this.apiDomains.add(apiDomain);
+ public void addCustomDomain(CustomDomain customDomain) {
+ checkNotNull(customDomain);
+ removeCustomDomain(customDomain.getName());
+ this.customDomains.add(customDomain);
+ }
+
+ /**
+ * Remove a custom domain matched by the name
+ *
+ * @param name the name
+ */
+ public void removeCustomDomain(String name) {
+ checkNotNull(name);
+ this.customDomains.removeIf(d -> d.getName().equalsIgnoreCase(name));
+ }
+
+ /**
+ * Remove a custom domain
+ *
+ * @param customDomain a domain
+ */
+ public void removeCustomDomain(CustomDomain customDomain) {
+ checkNotNull(customDomain);
+ this.customDomains.remove(customDomain);
}
/**
* Set the api domains to a specified value
*
- * @param apiDomains the domains
+ * @param customDomains the domains
*/
- public void setApiDomains(Collection apiDomains) {
- checkNotNull(apiDomains);
- this.apiDomains = new HashSet<>(apiDomains);
+ public void setCustomDomains(Collection customDomains) {
+ checkNotNull(customDomains);
+ this.customDomains = new HashSet<>(customDomains);
}
/**
@@ -134,8 +155,8 @@ public void setApiDomains(Collection apiDomains) {
*
* @return a unmodifiable copy of the domains
*/
- public Set getApiDomains() {
- return Collections.unmodifiableSet(this.apiDomains);
+ public Set getCustomDomains() {
+ return Collections.unmodifiableSet(this.customDomains);
}
/**
@@ -209,6 +230,9 @@ public void addAll(DefaultDomain other) {
for (String group : other.getGroups()) {
addGroup(group);
}
+ for (CustomDomain domain : other.getCustomDomains()) {
+ addCustomDomain(domain);
+ }
}
/**
@@ -227,6 +251,9 @@ public void removeAll(DefaultDomain other) {
for (String group : other.getGroups()) {
removeGroup(group);
}
+ for (CustomDomain domain : other.getCustomDomains()) {
+ removeCustomDomain(domain);
+ }
}
/**
@@ -276,12 +303,12 @@ public Set getGroups() {
@Override
public boolean contains(LocalPlayer player) {
- return playerDomain.contains(player) || groupDomain.contains(player) || apiDomains.stream().anyMatch(d -> d.contains(player));
+ return playerDomain.contains(player) || groupDomain.contains(player) || customDomains.stream().anyMatch(d -> d.contains(player));
}
@Override
public boolean contains(UUID uniqueId) {
- return playerDomain.contains(uniqueId) || apiDomains.stream().anyMatch(d -> d.contains(uniqueId));
+ return playerDomain.contains(uniqueId) || customDomains.stream().anyMatch(d -> d.contains(uniqueId));
}
@Override
@@ -309,7 +336,6 @@ public String toPlayersString() {
}
public String toPlayersString(@Nullable ProfileCache cache) {
- StringBuilder str = new StringBuilder();
List output = new ArrayList<>();
for (String name : playerDomain.getPlayers()) {
@@ -333,13 +359,7 @@ public String toPlayersString(@Nullable ProfileCache cache) {
}
output.sort(String.CASE_INSENSITIVE_ORDER);
- for (Iterator it = output.iterator(); it.hasNext();) {
- str.append(it.next());
- if (it.hasNext()) {
- str.append(", ");
- }
- }
- return str.toString();
+ return String.join(", ", output);
}
public String toGroupsString() {
@@ -354,6 +374,15 @@ public String toGroupsString() {
return str.toString();
}
+ public String toCustomDomainsString() {
+ List output = new ArrayList<>();
+ for (CustomDomain customDomain : customDomains) {
+ output.add(customDomain.getName() + ":" + customDomain.toString());
+ }
+ output.sort(String.CASE_INSENSITIVE_ORDER);
+ return String.join(", ", output);
+ }
+
public String toUserFriendlyString() {
StringBuilder str = new StringBuilder();
@@ -386,6 +415,12 @@ public String toUserFriendlyString(ProfileCache cache) {
str.append(toGroupsString());
}
+ if (!customDomains.isEmpty()) {
+ if (str.length() > 0) {
+ str.append("; ");
+ }
+ str.append(toCustomDomainsString());
+ }
return str.toString();
}
@@ -401,6 +436,12 @@ public Component toUserFriendlyComponent(@Nullable ProfileCache cache) {
}
builder.append(toGroupsComponent());
}
+ if (!customDomains.isEmpty()) {
+ if (playerDomain.size() > 0 || groupDomain.size() > 0) {
+ builder.append(TextComponent.of("; "));
+ }
+ builder.append(toCustomDomainsString());
+ }
return builder.build();
}
@@ -476,21 +517,37 @@ private Component toPlayersComponent(ProfileCache cache) {
return builder.build();
}
+ private Component toCustomDomainsComponent(ProfileCache cache) {
+ final TextComponent.Builder builder = TextComponent.builder("");
+ for (Iterator it = customDomains.iterator(); it.hasNext(); ) {
+ CustomDomain domain = it.next();
+ builder.append(TextComponent.of(domain.getName() + ":", TextColor.GRAY))
+ .append(TextComponent.of(domain.toString(), TextColor.GOLD));
+ if (it.hasNext()) {
+ builder.append(TextComponent.of(", "));
+ }
+ }
+ return builder.build().hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("CustomDomain")));
+ }
+
+
@Override
public boolean isDirty() {
- return playerDomain.isDirty() || groupDomain.isDirty();
+ return playerDomain.isDirty() || groupDomain.isDirty() || customDomains.stream().anyMatch(ChangeTracked::isDirty);
}
@Override
public void setDirty(boolean dirty) {
playerDomain.setDirty(dirty);
groupDomain.setDirty(dirty);
+ customDomains.forEach(d -> d.setDirty(dirty));
}
@Override
public String toString() {
return "{players=" + playerDomain +
", groups=" + groupDomain +
+ ", custom=" + customDomains +
'}';
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/CustomDomainContext.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/CustomDomainContext.java
new file mode 100644
index 000000000..e534bc483
--- /dev/null
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/CustomDomainContext.java
@@ -0,0 +1,93 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldguard.domains.registry;
+
+import com.google.common.collect.Maps;
+import com.sk89q.worldedit.extension.platform.Actor;
+import com.sk89q.worldguard.commands.CommandInputContext;
+
+import javax.annotation.Nullable;
+import java.util.Map;
+
+public final class CustomDomainContext extends CommandInputContext {
+
+ private CustomDomainContext(Actor sender, String input, Map values) {
+ super(sender, input, values);
+ }
+
+
+ public static CustomDomainContext.CustomDomainContextBuilder create() {
+ return new CustomDomainContext.CustomDomainContextBuilder();
+ }
+
+ /**
+ * Create a copy of this FlagContext, with optional substitutions for values
+ *
+ * If any supplied variable is null, it will be ignored.
+ * If a map is supplied, it will override this FlagContext's values of the same key,
+ * but unprovided keys will not be overriden and will be returned as shallow copies.
+ *
+ * @param commandSender CommandSender for the new FlagContext to run under
+ * @param s String of the user input for the new FlagContext
+ * @param values map of values to override from the current FlagContext
+ * @return a copy of this FlagContext
+ */
+ public CustomDomainContext copyWith(@Nullable Actor commandSender, @Nullable String s, @Nullable Map values) {
+ Map map = Maps.newHashMap();
+ map.putAll(context);
+ if (values != null) {
+ map.putAll(values);
+ }
+ return new CustomDomainContext(commandSender == null ? this.sender : commandSender, s == null ? this.input : s, map);
+ }
+
+ public static class CustomDomainContextBuilder {
+ private Actor sender;
+ private String input;
+ private Map map = Maps.newHashMap();
+
+ public CustomDomainContextBuilder setSender(Actor sender) {
+ this.sender = sender;
+ return this;
+ }
+
+ public CustomDomainContextBuilder setInput(String input) {
+ this.input = input;
+ return this;
+ }
+
+ public CustomDomainContextBuilder setObject(String key, Object value) {
+ this.map.put(key, value);
+ return this;
+ }
+
+ public boolean tryAddToMap(String key, Object value) {
+ if (map.containsKey(key)) return false;
+ this.map.put(key, value);
+ return true;
+ }
+
+ public CustomDomainContext build() {
+ return new CustomDomainContext(sender, input, map);
+ }
+ }
+
+}
+
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainFactory.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainFactory.java
index 7fff6f661..5d901bd3e 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainFactory.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainFactory.java
@@ -20,9 +20,9 @@
package com.sk89q.worldguard.domains.registry;
-import com.sk89q.worldguard.domains.ApiDomain;
+import com.sk89q.worldguard.domains.CustomDomain;
@FunctionalInterface
-public interface DomainFactory {
- T create(String name, Object values);
+public interface DomainFactory {
+ T create(String name);
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
index ead7a7801..e05ad1780 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
@@ -19,7 +19,7 @@
package com.sk89q.worldguard.domains.registry;
-import com.sk89q.worldguard.domains.ApiDomain;
+import com.sk89q.worldguard.domains.CustomDomain;
import javax.annotation.Nullable;
import java.util.List;
@@ -63,11 +63,11 @@ public interface DomainRegistry extends Iterable> {
DomainFactory> get(String name);
/**
- * Get all domains
+ * Get all domains keyed by the registered name
*
* @return All domains
*/
- List> getAll();
+ Map> getAll();
/**
* Unmarshal a raw map of values into a list of domains with their
@@ -77,7 +77,7 @@ public interface DomainRegistry extends Iterable> {
* @param createUnknown Whether "just in time" domains should be created for unknown domains
* @return The unmarshalled domain list
*/
- List unmarshal(Map rawValues, boolean createUnknown);
+ List unmarshal(Map rawValues, boolean createUnknown);
/**
* Get the number of registered domains.
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/InvalidDomainFormat.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/InvalidDomainFormat.java
new file mode 100644
index 000000000..83fc3fc91
--- /dev/null
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/InvalidDomainFormat.java
@@ -0,0 +1,28 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldguard.domains.registry;
+
+public class InvalidDomainFormat extends Exception {
+ private static final long serialVersionUID = 8101615074524004172L;
+
+ public InvalidDomainFormat(String msg) {
+ super(msg);
+ }
+}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
index 9e6f56ce8..27f14b3ca 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
@@ -19,14 +19,13 @@
package com.sk89q.worldguard.domains.registry;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterators;
import com.google.common.collect.Maps;
-import com.sk89q.worldguard.domains.ApiDomain;
+import com.sk89q.worldguard.domains.CustomDomain;
import javax.annotation.Nullable;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -98,38 +97,46 @@ public DomainFactory> get(String name) {
}
@Override
- public List> getAll() {
- return ImmutableList.copyOf(domains.values());
+ public Map> getAll() {
+ return ImmutableMap.copyOf(domains);
}
- private ApiDomain getOrCreate(String name, Object value, boolean createUnknown) {
- DomainFactory extends ApiDomain> domain = get(name);
+ private CustomDomain getOrCreate(String name, Object value, boolean createUnknown) {
+ DomainFactory extends CustomDomain> domainFactory = get(name);
- if (domain != null) {
- return domain.create(name, value);
+ if (domainFactory != null) {
+ CustomDomain customDomain = domainFactory.create(name);
+ if (customDomain != null) customDomain.unmarshal(value);
+ return customDomain;
}
synchronized (lock) {
- domain = get(name); // Load again because the previous load was not synchronized
- if (domain != null) {
- return domain.create(name, value);
+ domainFactory = get(name); // Load again because the previous load was not synchronized
+ if (domainFactory != null) {
+ CustomDomain customDomain = domainFactory.create(name);
+ if (customDomain != null) customDomain.unmarshal(value);
+ return customDomain;
}
if (createUnknown) {
DomainFactory unknownFactory = forceRegister(name, UnknownDomain.FACTORY);
- return unknownFactory.create(name, value);
+ if (unknownFactory != null) {
+ CustomDomain customDomain = unknownFactory.create(name);
+ if (customDomain != null) customDomain.unmarshal(value);
+ return customDomain;
+ }
}
}
return null;
}
- public List unmarshal(Map rawValues, boolean createUnknown) {
+ public List unmarshal(Map rawValues, boolean createUnknown) {
checkNotNull(rawValues, "rawValues");
- List domainList = new ArrayList<>();
+ List domainList = new ArrayList<>();
for (Map.Entry entry : rawValues.entrySet()) {
try {
- ApiDomain domain = getOrCreate(entry.getKey(), entry.getValue(), createUnknown);
+ CustomDomain domain = getOrCreate(entry.getKey(), entry.getValue(), createUnknown);
domainList.add(domain);
} catch (Throwable e) {
log.log(Level.WARNING, "Failed to unmarshal domain for " + entry.getKey(), e);
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
index fd2d431a4..1b509bc4a 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
@@ -19,21 +19,29 @@
package com.sk89q.worldguard.domains.registry;
-import com.sk89q.worldguard.domains.ApiDomain;
+import com.sk89q.worldguard.domains.CustomDomain;
-import javax.annotation.Nullable;
import java.util.UUID;
-public class UnknownDomain extends ApiDomain {
+public class UnknownDomain extends CustomDomain {
public static DomainFactory FACTORY = UnknownDomain::new;
- Object o;
+ private boolean isDirty = false;
+ private Object o;
- public UnknownDomain(String name, Object values) {
+ public UnknownDomain(String name) {
super(name);
- this.o = values;
}
+ @Override
+ public void parseInput(CustomDomainContext c) throws InvalidDomainFormat {
+ throw new InvalidDomainFormat("The plugin that registered this flag is not currently installed");
+ }
+
+ @Override
+ public void unmarshal(Object o) {
+ this.o = o;
+ }
@Override
public Object marshal() {
@@ -57,6 +65,24 @@ public int size() {
@Override
public void clear() {
+ isDirty = true;
o = null;
}
+
+ @Override
+ public void setDirty(boolean dirty) {
+ isDirty = dirty;
+ }
+
+ @Override
+ public boolean isDirty() {
+ return isDirty;
+ }
+
+ @Override
+ public String toString() {
+ return "UnknownDomain{" +
+ "o=" + o +
+ '}';
+ }
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/internal/permission/RegionPermissionModel.java b/worldguard-core/src/main/java/com/sk89q/worldguard/internal/permission/RegionPermissionModel.java
index 287ed972d..966801375 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/internal/permission/RegionPermissionModel.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/internal/permission/RegionPermissionModel.java
@@ -27,6 +27,7 @@
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
@@ -176,6 +177,24 @@ public boolean mayRemoveMembers(ProtectedRegion region) {
public boolean mayRemoveOwners(ProtectedRegion region) {
return hasPatternPermission("removeowner", region);
}
+
+ /**
+ * Checks to see if the given sender has permission to modify a custom region
+ *
+ * @param region the region
+ * @param isOwnerLevel whether the domain level is owner (else member)
+ * @param domainName the name of the domain
+ * @return whether the actor has the permission
+ */
+ public boolean mayModifyCustomDomain(ProtectedRegion region, boolean isOwnerLevel, @Nonnull String domainName) {
+
+ String sanitizedValue = domainName.trim().toLowerCase().replaceAll("[^a-z0-9]", "");
+ if (sanitizedValue.length() > 20) {
+ sanitizedValue = sanitizedValue.substring(0, 20);
+ }
+
+ return hasPatternPermission("flag.flags." + sanitizedValue + "." + (isOwnerLevel ? "owner" : "member"), region);
+ }
/**
* Checks to see if the given sender has permission to modify the given region
@@ -183,6 +202,7 @@ public boolean mayRemoveOwners(ProtectedRegion region) {
*
* @param perm the name of the node
* @param region the region
+ * @return whether the actor has the permission
*/
private boolean hasPatternPermission(String perm, ProtectedRegion region) {
if (!(getSender() instanceof Player)) {
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/FlagContext.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/FlagContext.java
index a394a18fb..d5d8cda65 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/FlagContext.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/FlagContext.java
@@ -21,100 +21,22 @@
import com.google.common.collect.Maps;
import com.sk89q.worldedit.extension.platform.Actor;
-import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
-
-import java.util.Map;
+import com.sk89q.worldguard.commands.CommandInputContext;
import javax.annotation.Nullable;
+import java.util.Map;
-public final class FlagContext {
-
- private final Actor sender;
- private final String input;
-
- private Map context;
+public final class FlagContext extends CommandInputContext {
private FlagContext(Actor sender, String input, Map values) {
- this.sender = sender;
- this.input = input;
- this.context = values;
+ super(sender, input, values);
}
- public static FlagContextBuilder create() {
+ public static FlagContext.FlagContextBuilder create() {
return new FlagContextBuilder();
}
- public void put(String name, Object value) {
- context.put(name, value);
- }
-
- public Actor getSender() {
- return sender;
- }
-
- public String getUserInput() {
- return input;
- }
-
- /**
- * Gets the CommandSender as a player.
- *
- * @return Player
- * @throws InvalidFlagFormat if the sender is not a player
- */
- public LocalPlayer getPlayerSender() throws InvalidFlagFormat {
- if (sender.isPlayer() && sender instanceof LocalPlayer) {
- return (LocalPlayer) sender;
- } else {
- throw new InvalidFlagFormat("Not a player");
- }
- }
-
- public Integer getUserInputAsInt() throws InvalidFlagFormat {
- try {
- return Integer.parseInt(input);
- } catch (NumberFormatException e) {
- throw new InvalidFlagFormat("Not a number: " + input);
- }
- }
-
- public Double getUserInputAsDouble() throws InvalidFlagFormat {
- try {
- return Double.parseDouble(input);
- } catch (NumberFormatException e) {
- throw new InvalidFlagFormat("Not a number: " + input);
- }
- }
-
- /**
- * Get an object from the context by key name.
- * May return null if the object does not exist in the context.
- *
- * @param name key name of the object
- * @return the object matching the key, or null
- */
- @Nullable
- public Object get(String name) {
- return get(name, null);
- }
-
- /**
- * Get an object from the context by key name.
- * Will only return null if
- * a) you provide null as the default
- * b) the key has explicity been set to null
- *
- * @param name key name of the object
- * @return the object matching the key
- */
- @Nullable
- public Object get(String name, Object defaultValue) {
- Object obj;
- return (((obj = context.get(name)) != null) || context.containsKey(name)
- ? obj : defaultValue);
- }
-
/**
* Create a copy of this FlagContext, with optional substitutions for values
*
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java
index 1d9187412..f45ac1e0a 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java
@@ -28,7 +28,7 @@
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldguard.WorldGuard;
-import com.sk89q.worldguard.domains.ApiDomain;
+import com.sk89q.worldguard.domains.CustomDomain;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.flags.FlagUtil;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
@@ -288,8 +288,8 @@ private DefaultDomain parseDomain(YAMLNode node) {
YAMLNode apiDomains = node.getNode("api");
if (apiDomains != null) {
- List parsedDomains = WorldGuard.getInstance().getDomainRegistry().unmarshal(apiDomains.getMap(), true);
- domain.setApiDomains(parsedDomains);
+ List parsedDomains = WorldGuard.getInstance().getDomainRegistry().unmarshal(apiDomains.getMap(), true);
+ domain.setCustomDomains(parsedDomains);
}
return domain;
@@ -312,10 +312,10 @@ private Map getDomainData(DefaultDomain domain) {
setDomainData(domainData, "unique-ids", domain.getUniqueIds());
setDomainData(domainData, "groups", domain.getGroups());
- if (!domain.getApiDomains().isEmpty()) {
+ if (!domain.getCustomDomains().isEmpty()) {
Map values = new HashMap<>();
- for (ApiDomain apiDomain : domain.getApiDomains()) {
- values.put(apiDomain.getName(), apiDomain.marshal());
+ for (CustomDomain customDomain : domain.getCustomDomains()) {
+ values.put(customDomain.getName(), customDomain.marshal());
}
domainData.put("api", values);
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
index 4c8a00ff8..e30856c33 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
@@ -102,7 +102,7 @@ public DefaultDomain call() throws UnresolvedNamesException {
UUID uuid = parseUUID(s);
if (uuid != null) {
// Try to add any UUIDs given
- domain.addPlayer(UUID.fromString(UUIDs.addDashes(s.replaceAll("^uuid:", ""))));
+ domain.addPlayer(uuid);
} else {
switch (locatorPolicy) {
case NAME_ONLY:
From b0669cc756b034dbf48f4c5290f8388baed56665 Mon Sep 17 00:00:00 2001
From: JOO200
Date: Sat, 1 Jan 2022 17:23:38 +0100
Subject: [PATCH 04/11] Fixed unformatted command output, check for valid
domain name
---
.../java/com/sk89q/worldguard/domains/CustomDomain.java | 8 ++++++++
.../java/com/sk89q/worldguard/domains/DefaultDomain.java | 9 +++++----
.../domains/registry/SimpleDomainRegistry.java | 4 ++++
.../protection/managers/storage/file/YamlRegionFile.java | 4 ++--
4 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
index b48678083..213d6d718 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
@@ -34,6 +34,9 @@ public abstract class CustomDomain implements Domain, ChangeTracked {
private final String name;
public CustomDomain(String name) {
+ if (name == null ||!isValidName(name)) {
+ throw new IllegalArgumentException("Invalid Domain name used.");
+ }
this.name = name;
}
@@ -85,4 +88,9 @@ public static boolean isValidName(String name) {
public boolean contains(LocalPlayer player) {
return contains(player.getUniqueId());
}
+
+ @Override
+ public int size() {
+ return 1;
+ }
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
index ae44a94df..0b7d0dc83 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
@@ -69,6 +69,7 @@ public DefaultDomain() {
public DefaultDomain(DefaultDomain existing) {
setPlayerDomain(existing.getPlayerDomain());
setGroupDomain(existing.getGroupDomain());
+ setCustomDomains(existing.getCustomDomains());
}
/**
@@ -318,7 +319,7 @@ public boolean contains(String playerName) {
@Override
public int size() {
- return groupDomain.size() + playerDomain.size();
+ return groupDomain.size() + playerDomain.size() + customDomains.size();
}
@Override
@@ -440,7 +441,7 @@ public Component toUserFriendlyComponent(@Nullable ProfileCache cache) {
if (playerDomain.size() > 0 || groupDomain.size() > 0) {
builder.append(TextComponent.of("; "));
}
- builder.append(toCustomDomainsString());
+ builder.append(toCustomDomainsComponent());
}
return builder.build();
}
@@ -517,11 +518,11 @@ private Component toPlayersComponent(ProfileCache cache) {
return builder.build();
}
- private Component toCustomDomainsComponent(ProfileCache cache) {
+ private Component toCustomDomainsComponent() {
final TextComponent.Builder builder = TextComponent.builder("");
for (Iterator it = customDomains.iterator(); it.hasNext(); ) {
CustomDomain domain = it.next();
- builder.append(TextComponent.of(domain.getName() + ":", TextColor.GRAY))
+ builder.append(TextComponent.of(domain.getName() + ":", TextColor.LIGHT_PURPLE))
.append(TextComponent.of(domain.toString(), TextColor.GOLD));
if (it.hasNext()) {
builder.append(TextComponent.of(", "));
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
index 27f14b3ca..7b0b0a8b4 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
@@ -78,6 +78,10 @@ private > T forceRegister(String name, T domain) thro
checkNotNull(domain, "domain");
checkNotNull(name, "name");
+ if (!CustomDomain.isValidName(name)) {
+ throw new IllegalArgumentException("Invalid Domain name used.");
+ }
+
synchronized (lock) {
if (domains.containsKey(name)) {
throw new DomainConflictException("A domain already exists by the name " + name);
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java
index f45ac1e0a..531b499f6 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/managers/storage/file/YamlRegionFile.java
@@ -286,7 +286,7 @@ private DefaultDomain parseDomain(YAMLNode node) {
}
}
- YAMLNode apiDomains = node.getNode("api");
+ YAMLNode apiDomains = node.getNode("custom");
if (apiDomains != null) {
List parsedDomains = WorldGuard.getInstance().getDomainRegistry().unmarshal(apiDomains.getMap(), true);
domain.setCustomDomains(parsedDomains);
@@ -317,7 +317,7 @@ private Map getDomainData(DefaultDomain domain) {
for (CustomDomain customDomain : domain.getCustomDomains()) {
values.put(customDomain.getName(), customDomain.marshal());
}
- domainData.put("api", values);
+ domainData.put("custom", values);
}
return domainData;
From 8736185c92353643911f88e22bbcf06f4cf1b533 Mon Sep 17 00:00:00 2001
From: JOO200
Date: Sat, 1 Jan 2022 17:42:23 +0100
Subject: [PATCH 05/11] Fix for weird format
---
.../com/sk89q/worldguard/commands/region/MemberCommands.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
index 292683481..33e3f8224 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
@@ -327,7 +327,8 @@ private void domain(CommandContext args, Actor sender, boolean isOwner) throws C
}
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(world.getName(), existing, null, sender);
- printout.append(SubtleFormat.wrap("(Current domains: "));
+ printout.append(SubtleFormat.wrap("(Current domains:"));
+ printout.newline();
printout.appendDomain();
printout.append(SubtleFormat.wrap(")"));
printout.send(sender);
From 4f1be027c5e766514c3524f1fa0b66ee4366a35f Mon Sep 17 00:00:00 2001
From: JOO200
Date: Thu, 13 Jan 2022 21:08:39 +0100
Subject: [PATCH 06/11] Fixed dirty flags for CustomDomain, added UnitTest
---
.../commands/CommandInputContext.java | 2 -
.../worldguard/domains/CustomDomain.java | 11 ++++
.../worldguard/domains/DefaultDomain.java | 15 ++++-
.../domains/registry/UnknownDomain.java | 2 +-
.../worldguard/domains/CustomUUIDDomain.java | 64 +++++++++++++++++++
.../worldguard/domains/DefaultDomainTest.java | 6 ++
6 files changed, 94 insertions(+), 6 deletions(-)
create mode 100644 worldguard-core/src/test/java/com/sk89q/worldguard/domains/CustomUUIDDomain.java
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java
index 5aab831c4..737d062d3 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java
@@ -19,10 +19,8 @@
package com.sk89q.worldguard.commands;
-import com.google.common.collect.Maps;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.LocalPlayer;
-import com.sk89q.worldguard.protection.flags.FlagContext;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import javax.annotation.Nullable;
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
index 213d6d718..3383a0388 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
@@ -32,6 +32,7 @@ public abstract class CustomDomain implements Domain, ChangeTracked {
private static final Pattern VALID_NAME = Pattern.compile("^[A-Za-z0-9\\-]{1,40}$");
private final String name;
+ private boolean dirty;
public CustomDomain(String name) {
if (name == null ||!isValidName(name)) {
@@ -93,4 +94,14 @@ public boolean contains(LocalPlayer player) {
public int size() {
return 1;
}
+
+ @Override
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ @Override
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
index 0b7d0dc83..3128076fc 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
@@ -54,6 +54,7 @@ public class DefaultDomain implements Domain, ChangeTracked {
private GroupDomain groupDomain = new GroupDomain();
private Set customDomains = new HashSet<>();
+ private boolean customDomainsChanged = false;
/**
* Create a new domain.
@@ -119,6 +120,7 @@ public void addCustomDomain(CustomDomain customDomain) {
checkNotNull(customDomain);
removeCustomDomain(customDomain.getName());
this.customDomains.add(customDomain);
+ customDomainsChanged = true;
}
/**
@@ -128,7 +130,9 @@ public void addCustomDomain(CustomDomain customDomain) {
*/
public void removeCustomDomain(String name) {
checkNotNull(name);
- this.customDomains.removeIf(d -> d.getName().equalsIgnoreCase(name));
+ if (this.customDomains.removeIf(d -> d.getName().equalsIgnoreCase(name))) {
+ customDomainsChanged = true;
+ }
}
/**
@@ -138,7 +142,9 @@ public void removeCustomDomain(String name) {
*/
public void removeCustomDomain(CustomDomain customDomain) {
checkNotNull(customDomain);
- this.customDomains.remove(customDomain);
+ if (this.customDomains.remove(customDomain)) {
+ customDomainsChanged = true;
+ }
}
/**
@@ -149,6 +155,7 @@ public void removeCustomDomain(CustomDomain customDomain) {
public void setCustomDomains(Collection customDomains) {
checkNotNull(customDomains);
this.customDomains = new HashSet<>(customDomains);
+ customDomainsChanged = true;
}
/**
@@ -534,13 +541,15 @@ private Component toCustomDomainsComponent() {
@Override
public boolean isDirty() {
- return playerDomain.isDirty() || groupDomain.isDirty() || customDomains.stream().anyMatch(ChangeTracked::isDirty);
+ return playerDomain.isDirty() || groupDomain.isDirty() ||
+ customDomainsChanged || customDomains.stream().anyMatch(ChangeTracked::isDirty);
}
@Override
public void setDirty(boolean dirty) {
playerDomain.setDirty(dirty);
groupDomain.setDirty(dirty);
+ customDomainsChanged = true;
customDomains.forEach(d -> d.setDirty(dirty));
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
index 1b509bc4a..5aa83f460 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
@@ -34,7 +34,7 @@ public UnknownDomain(String name) {
}
@Override
- public void parseInput(CustomDomainContext c) throws InvalidDomainFormat {
+ public void parseInput(CustomDomainContext context) throws InvalidDomainFormat {
throw new InvalidDomainFormat("The plugin that registered this flag is not currently installed");
}
diff --git a/worldguard-core/src/test/java/com/sk89q/worldguard/domains/CustomUUIDDomain.java b/worldguard-core/src/test/java/com/sk89q/worldguard/domains/CustomUUIDDomain.java
new file mode 100644
index 000000000..1f9dfd7bf
--- /dev/null
+++ b/worldguard-core/src/test/java/com/sk89q/worldguard/domains/CustomUUIDDomain.java
@@ -0,0 +1,64 @@
+/*
+ * WorldGuard, a suite of tools for Minecraft
+ * Copyright (C) sk89q
+ * Copyright (C) WorldGuard team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldguard.domains;
+
+import com.sk89q.worldguard.domains.registry.CustomDomainContext;
+import com.sk89q.worldguard.domains.registry.InvalidDomainFormat;
+
+import java.util.Objects;
+import java.util.UUID;
+
+public class CustomUUIDDomain extends CustomDomain {
+ private UUID test;
+
+ public CustomUUIDDomain(String name, UUID test) {
+ super(name);
+ this.test = test;
+ }
+
+ @Override
+ public void parseInput(CustomDomainContext context) throws InvalidDomainFormat {
+ throw new InvalidDomainFormat("not supported");
+ }
+
+ @Override
+ public void unmarshal(Object o) {
+ }
+
+ @Override
+ public Object marshal() {
+ return null;
+ }
+
+ @Override
+ public boolean contains(UUID uniqueId) {
+ return Objects.equals(test, uniqueId);
+ }
+
+ @Override
+ public boolean contains(String playerName) {
+ return false;
+ }
+
+ @Override
+ public void clear() {
+ test = null;
+ }
+}
diff --git a/worldguard-core/src/test/java/com/sk89q/worldguard/domains/DefaultDomainTest.java b/worldguard-core/src/test/java/com/sk89q/worldguard/domains/DefaultDomainTest.java
index 86586657f..fc112219d 100644
--- a/worldguard-core/src/test/java/com/sk89q/worldguard/domains/DefaultDomainTest.java
+++ b/worldguard-core/src/test/java/com/sk89q/worldguard/domains/DefaultDomainTest.java
@@ -112,5 +112,11 @@ public void testContains() throws Exception {
assertFalse(domain.contains(player1));
assertTrue(domain.contains(player2));
assertTrue(domain.contains(player3));
+
+ domain = new DefaultDomain();
+ domain.addCustomDomain(new CustomUUIDDomain("test", player2.getUniqueId()));
+ assertTrue(domain.contains(player2));
+ assertFalse(domain.contains(player2.getName()));
+ assertFalse(domain.contains(player3));
}
}
\ No newline at end of file
From b3ae14bfbaf43ba1c97816afd9c61e02d1377e84 Mon Sep 17 00:00:00 2001
From: JOO200
Date: Sat, 29 Jan 2022 19:42:13 +0100
Subject: [PATCH 07/11] Removed commands for custom domains.
Adding/Removing custom domains are now in /rg addmember/delmember/addowner/delowner
---
.../commands/region/MemberCommands.java | 108 ++----------------
.../commands/region/RegionCommands.java | 4 +-
.../commands/region/RegionCommandsBase.java | 9 --
.../worldguard/commands/task/RegionAdder.java | 18 ++-
.../worldguard/domains/CustomDomain.java | 3 +-
.../worldguard/domains/DefaultDomain.java | 4 +-
.../protection/util/DomainInputResolver.java | 52 ++++++++-
.../util/WorldGuardExceptionConverter.java | 6 +
8 files changed, 89 insertions(+), 115 deletions(-)
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
index 33e3f8224..960782d8b 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
@@ -81,6 +81,8 @@ public void addMember(CommandContext args, Actor sender) throws CommandException
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
+ resolver.setActor(sender);
+ resolver.setRegion(region);
final String description = String.format("Adding members to the region '%s' on '%s'", region.getId(), world.getName());
@@ -115,7 +117,8 @@ public void addOwner(CommandContext args, Actor sender) throws CommandException
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
-
+ resolver.setActor(sender);
+ resolver.setRegion(region);
final String description = String.format("Adding owners to the region '%s' on '%s'", region.getId(), world.getName());
AsyncCommandBuilder.wrap(checkedAddOwners(sender, manager, region, world, resolver), sender)
@@ -188,6 +191,8 @@ public void removeMember(CommandContext args, Actor sender) throws CommandExcept
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_AND_NAME);
+ resolver.setActor(sender);
+ resolver.setRegion(region);
callable = resolver;
}
@@ -231,6 +236,8 @@ public void removeOwner(CommandContext args, Actor sender) throws CommandExcepti
DomainInputResolver resolver = new DomainInputResolver(
WorldGuard.getInstance().getProfileService(), args.getParsedPaddedSlice(1, 0));
resolver.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_AND_NAME);
+ resolver.setActor(sender);
+ resolver.setRegion(region);
callable = resolver;
}
@@ -244,98 +251,7 @@ public void removeOwner(CommandContext args, Actor sender) throws CommandExcepti
.buildAndExec(worldGuard.getExecutorService());
}
-
- /**
- * Modify a custom domain for owner.
- *
- * @param args the arguments
- * @param sender the sender
- * @throws CommandException any error
- */
- @Command(aliases = {"ownerdomain"},
- usage = " [-w world] [value]",
- flags = "w:",
- desc = "Set flags",
- min = 2)
- public void ownerDomain(CommandContext args, Actor sender) throws CommandException {
- domain(args, sender, true);
- }
-
- /**
- * Modify a custom domain for member.
- *
- * @param args the arguments
- * @param sender the sender
- * @throws CommandException any error
- */
- @Command(aliases = {"memberdomain"},
- usage = " [-w world] [value]",
- flags = "w:",
- desc = "Set flags",
- min = 2)
- public void onMemberDomain(CommandContext args, Actor sender) throws CommandException {
- domain(args, sender, false);
- }
-
- private void domain(CommandContext args, Actor sender, boolean isOwner) throws CommandException {
- warnAboutSaveFailures(sender);
-
- World world = checkWorld(args, sender, 'w'); // Get the world
- String domainName = args.getString(1);
- String value = args.argsLength() >= 3 ? args.getJoinedStrings(2) : null;
- DomainRegistry domainRegistry = WorldGuard.getInstance().getDomainRegistry();
- RegionPermissionModel permModel = getPermissionModel(sender);
-
- // Lookup the existing region
- RegionManager manager = checkRegionManager(world);
- ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), true);
-
- // Check permissions
- if (!permModel.mayModifyCustomDomain(existing, isOwner, domainName)) {
- throw new CommandPermissionsException();
- }
- String regionId = existing.getId();
-
- DomainFactory> domainFactory = domainRegistry.get(domainName);
-
- // We didn't find the domain, so let's print a list of domains that the user
- // can use, and do nothing afterwards
- if (domainFactory == null) {
- AsyncCommandBuilder.wrap(new DomainListBuilder(domainRegistry, permModel, existing, world,
- regionId, sender, domainName, isOwner), sender)
- .registerWithSupervisor(WorldGuard.getInstance().getSupervisor(), "Domain list for invalid domain command.")
- .onSuccess((Component) null, sender::print)
- .onFailure((Component) null, WorldGuard.getInstance().getExceptionConverter())
- .buildAndExec(WorldGuard.getInstance().getExecutorService());
- return;
- }
-
- DefaultDomain usedDomain = isOwner ? existing.getOwners() : existing.getMembers();
-
- // Set the flag value if a value was set
- if (value != null) {
- // Set the flag if [value] was given even if [-g group] was given as well
- try {
- CustomDomain customDomain = domainFactory.create(domainName);
- setDomain(existing, usedDomain, customDomain, sender, value);
- } catch (InvalidDomainFormat e) {
- throw new CommandException(e.getMessage());
- }
- // No value? Clear the flag, if -g isn't specified
- } else {
- usedDomain.removeCustomDomain(domainName);
- }
-
- RegionPrintoutBuilder printout = new RegionPrintoutBuilder(world.getName(), existing, null, sender);
- printout.append(SubtleFormat.wrap("(Current domains:"));
- printout.newline();
- printout.appendDomain();
- printout.append(SubtleFormat.wrap(")"));
- printout.send(sender);
- checkSpawnOverlap(sender, world, existing);
-
- }
-
+ // TODO: Implement a list for available domains. Maybe /rg domains? or /rg addmembers/addowners/delmembers/delowners?
private static class DomainListBuilder implements Callable {
private final DomainRegistry domainRegistry;
private final RegionPermissionModel permModel;
@@ -375,11 +291,11 @@ public Component call() {
final HoverEvent clickToSet = HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to set"));
for (int i = 0; i < domainList.size(); i++) {
- String flag = domainList.get(i);
+ String domainName = domainList.get(i);
- builder.append(TextComponent.of(flag, i % 2 == 0 ? TextColor.GRAY : TextColor.WHITE)
+ builder.append(TextComponent.of(domainName, i % 2 == 0 ? TextColor.GRAY : TextColor.WHITE)
.hoverEvent(clickToSet).clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND,
- "/rg " + (isOwner ? "ownerdomains" : "memberdomains") +" -w \"" + world.getName() + "\" " + regionId + " " + flag + " ")));
+ "/rg " + (isOwner ? "addowner" : "addmember") +" -w \"" + world.getName() + "\" " + regionId + " " + domainName + ":")));
if (i < domainList.size() + 1) {
builder.append(TextComponent.of(", "));
}
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 9299ad02b..104184955 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
@@ -160,7 +160,7 @@ public void define(CommandContext args, Actor sender) throws CommandException {
region = checkRegionFromSelection(sender, id);
}
- RegionAdder task = new RegionAdder(manager, region);
+ RegionAdder task = new RegionAdder(manager, region, sender);
task.addOwnersFromCommand(args, 2);
final String description = String.format("Adding region '%s'", region.getId());
@@ -214,7 +214,7 @@ public void redefine(CommandContext args, Actor sender) throws CommandException
region.copyFrom(existing);
- RegionAdder task = new RegionAdder(manager, region);
+ RegionAdder task = new RegionAdder(manager, region, sender);
final String description = String.format("Updating region '%s'", region.getId());
AsyncCommandBuilder.wrap(task, sender)
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommandsBase.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommandsBase.java
index fa74e839b..8d728a44e 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommandsBase.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/RegionCommandsBase.java
@@ -426,13 +426,4 @@ protected static V setFlag(ProtectedRegion region, Flag flag, Actor sende
region.setFlag(flag, val);
return val;
}
-
- /**
- * Utility method to set a custom domain
- */
- protected static void setDomain(ProtectedRegion region, DefaultDomain target, CustomDomain domain, Actor sender, String value) throws InvalidDomainFormat {
- domain.parseInput(CustomDomainContext.create().setSender(sender).setInput(value).setObject("region", region).build());
- target.addCustomDomain(domain);
- }
-
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/task/RegionAdder.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/task/RegionAdder.java
index 932b85827..dc7a957da 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/task/RegionAdder.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/task/RegionAdder.java
@@ -20,6 +20,7 @@
package com.sk89q.worldguard.commands.task;
import com.sk89q.minecraft.util.commands.CommandContext;
+import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.managers.RegionManager;
@@ -39,6 +40,7 @@ public class RegionAdder implements Callable {
private final RegionManager manager;
private final ProtectedRegion region;
+ private final Actor actor;
@Nullable
private String[] ownersInput;
private UserLocatorPolicy locatorPolicy = UserLocatorPolicy.UUID_ONLY;
@@ -46,15 +48,26 @@ public class RegionAdder implements Callable {
/**
* Create a new instance.
*
- * @param manager the manage
+ * @param manager the manager
* @param region the region
*/
public RegionAdder(RegionManager manager, ProtectedRegion region) {
+ this(manager, region, null);
+ }
+
+ /**
+ * Create a new instance.
+ * @param manager the manager
+ * @param region the region
+ * @param actor the actor
+ */
+ public RegionAdder(RegionManager manager, ProtectedRegion region, Actor actor) {
checkNotNull(manager);
checkNotNull(region);
this.manager = manager;
this.region = region;
+ this.actor = actor;
}
/**
@@ -75,6 +88,9 @@ public ProtectedRegion call() throws Exception {
if (ownersInput != null) {
DomainInputResolver resolver = new DomainInputResolver(WorldGuard.getInstance().getProfileService(), ownersInput);
resolver.setLocatorPolicy(locatorPolicy);
+ resolver.setActor(actor);
+ resolver.setRegion(region);
+
DefaultDomain domain = resolver.call();
region.getOwners().addAll(domain);
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
index 3383a0388..991bef226 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/CustomDomain.java
@@ -81,7 +81,8 @@ public String getName() {
*/
public static boolean isValidName(String name) {
checkNotNull(name, "name");
- return VALID_NAME.matcher(name).matches();
+ // g is already reserved by the group domain
+ return VALID_NAME.matcher(name).matches() && !name.equalsIgnoreCase("g");
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
index 3128076fc..d14604920 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
@@ -260,7 +260,7 @@ public void removeAll(DefaultDomain other) {
removeGroup(group);
}
for (CustomDomain domain : other.getCustomDomains()) {
- removeCustomDomain(domain);
+ removeCustomDomain(domain.getName());
}
}
@@ -549,7 +549,7 @@ public boolean isDirty() {
public void setDirty(boolean dirty) {
playerDomain.setDirty(dirty);
groupDomain.setDirty(dirty);
- customDomainsChanged = true;
+ customDomainsChanged = dirty;
customDomains.forEach(d -> d.setDirty(dirty));
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
index e30856c33..ed9ce6826 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
@@ -21,6 +21,13 @@
import com.google.common.base.Function;
import com.google.common.base.Joiner;
+import com.sk89q.worldedit.extension.platform.Actor;
+import com.sk89q.worldguard.WorldGuard;
+import com.sk89q.worldguard.domains.CustomDomain;
+import com.sk89q.worldguard.domains.registry.CustomDomainContext;
+import com.sk89q.worldguard.domains.registry.DomainFactory;
+import com.sk89q.worldguard.domains.registry.InvalidDomainFormat;
+import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.util.profile.Profile;
import com.sk89q.worldguard.util.profile.resolver.ProfileService;
import com.sk89q.worldguard.util.profile.util.UUIDs;
@@ -43,6 +50,7 @@
public class DomainInputResolver implements Callable {
private static final Pattern GROUP_PATTERN = Pattern.compile("(?i)^[G]:(.+)$");
+ private static final Pattern CUSTOM_PATTERN = Pattern.compile("(?i)^([A-Za-z0-9\\-]{1,40}):(.*)$");
/**
* The policy for locating users.
@@ -56,6 +64,8 @@ public enum UserLocatorPolicy {
private final ProfileService profileService;
private final String[] input;
private UserLocatorPolicy locatorPolicy = UserLocatorPolicy.UUID_ONLY;
+ private ProtectedRegion region;
+ private Actor actor;
/**
* Create a new instance.
@@ -89,15 +99,49 @@ public void setLocatorPolicy(UserLocatorPolicy locatorPolicy) {
this.locatorPolicy = locatorPolicy;
}
+ /**
+ * Set the region for the Resolver
+ * @param region the region
+ */
+ public void setRegion(ProtectedRegion region) {
+ this.region = region;
+ }
+
+ /**
+ * Get the current region from the Resolver
+ * @return the region
+ */
+ public @Nullable ProtectedRegion getRegion() {
+ return region;
+ }
+
+ /**
+ * Set the actor of the Resolver
+ * @param actor the actor
+ */
+ public void setActor(Actor actor) {
+ this.actor = actor;
+ }
+
@Override
- public DefaultDomain call() throws UnresolvedNamesException {
+ public DefaultDomain call() throws UnresolvedNamesException, InvalidDomainFormat {
DefaultDomain domain = new DefaultDomain();
List namesToQuery = new ArrayList<>();
for (String s : input) {
- Matcher m = GROUP_PATTERN.matcher(s);
- if (m.matches()) {
- domain.addGroup(m.group(1));
+ Matcher groupMatcher = GROUP_PATTERN.matcher(s);
+ Matcher customMatcher = CUSTOM_PATTERN.matcher(s);
+ if (groupMatcher.matches()) {
+ domain.addGroup(groupMatcher.group(1));
+ } else if (customMatcher.matches()) {
+ String domainName = customMatcher.group(1);
+ DomainFactory> domainFactory = WorldGuard.getInstance().getDomainRegistry().get(domainName);
+ if (domainFactory == null) {
+ throw new InvalidDomainFormat("No domain named '" + domainName + "' found.");
+ }
+ CustomDomain customDomain = domainFactory.create(domainName);
+ customDomain.parseInput(CustomDomainContext.create()
+ .setSender(actor).setInput(customMatcher.group(2)).setObject("region", region).build());
} else {
UUID uuid = parseUUID(s);
if (uuid != null) {
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/util/WorldGuardExceptionConverter.java b/worldguard-core/src/main/java/com/sk89q/worldguard/util/WorldGuardExceptionConverter.java
index 89492df2d..f508951cd 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/util/WorldGuardExceptionConverter.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/util/WorldGuardExceptionConverter.java
@@ -26,6 +26,7 @@
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.util.formatting.component.InvalidComponentException;
import com.sk89q.worldguard.WorldGuard;
+import com.sk89q.worldguard.domains.registry.InvalidDomainFormat;
import com.sk89q.worldguard.protection.managers.storage.StorageException;
import com.sk89q.worldguard.protection.util.UnresolvedNamesException;
@@ -91,6 +92,11 @@ public void convert(UnresolvedNamesException e) throws CommandException {
throw newCommandException(e.getMessage(), e);
}
+ @ExceptionMatch
+ public void convert(InvalidDomainFormat e) throws CommandException {
+ throw newCommandException(e.getMessage(), e);
+ }
+
@ExceptionMatch
public void convert(AuthorizationException e) throws CommandException {
throw newCommandException("You don't have permission to do that.", e);
From 44f7380d7783e237f10a4a727cfb41e8a79bc9a9 Mon Sep 17 00:00:00 2001
From: JOO200
Date: Sat, 29 Jan 2022 19:55:18 +0100
Subject: [PATCH 08/11] Cleanup DomainRegistry
---
.../commands/region/MemberCommands.java | 3 ---
.../domains/registry/DomainRegistry.java | 6 +++++
.../registry/SimpleDomainRegistry.java | 24 ++++++++++++-------
.../protection/util/DomainInputResolver.java | 5 ++--
4 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
index 960782d8b..1ddc48030 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/region/MemberCommands.java
@@ -26,7 +26,6 @@
import com.sk89q.worldedit.command.util.AsyncCommandBuilder;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
-import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
@@ -35,11 +34,9 @@
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
-import com.sk89q.worldguard.domains.CustomDomain;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.domains.registry.DomainFactory;
import com.sk89q.worldguard.domains.registry.DomainRegistry;
-import com.sk89q.worldguard.domains.registry.InvalidDomainFormat;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
index e05ad1780..8a7294b95 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
@@ -62,6 +62,12 @@ public interface DomainRegistry extends Iterable> {
@Nullable
DomainFactory> get(String name);
+ /**
+ * Try to get a domain by its name
+ */
+ @Nullable
+ CustomDomain createDomain(String name);
+
/**
* Get all domains keyed by the registered name
*
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
index 7b0b0a8b4..95f8837f7 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/SimpleDomainRegistry.java
@@ -100,31 +100,37 @@ public DomainFactory> get(String name) {
return domains.get(name.toLowerCase());
}
+ @Nullable
+ @Override
+ public CustomDomain createDomain(String name) {
+ DomainFactory> factory = get(name);
+ if (factory == null) return null;
+ return factory.create(name);
+ }
+
@Override
public Map> getAll() {
return ImmutableMap.copyOf(domains);
}
private CustomDomain getOrCreate(String name, Object value, boolean createUnknown) {
- DomainFactory extends CustomDomain> domainFactory = get(name);
+ CustomDomain customDomain = createDomain(name);
- if (domainFactory != null) {
- CustomDomain customDomain = domainFactory.create(name);
- if (customDomain != null) customDomain.unmarshal(value);
+ if (customDomain != null) {
+ customDomain.unmarshal(value);
return customDomain;
}
synchronized (lock) {
- domainFactory = get(name); // Load again because the previous load was not synchronized
- if (domainFactory != null) {
- CustomDomain customDomain = domainFactory.create(name);
- if (customDomain != null) customDomain.unmarshal(value);
+ customDomain = createDomain(name); // Load again because the previous load was not synchronized
+ if (customDomain != null) {
+ customDomain.unmarshal(value);
return customDomain;
}
if (createUnknown) {
DomainFactory unknownFactory = forceRegister(name, UnknownDomain.FACTORY);
if (unknownFactory != null) {
- CustomDomain customDomain = unknownFactory.create(name);
+ customDomain = unknownFactory.create(name);
if (customDomain != null) customDomain.unmarshal(value);
return customDomain;
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
index ed9ce6826..855e37ed6 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
@@ -135,11 +135,10 @@ public DefaultDomain call() throws UnresolvedNamesException, InvalidDomainFormat
domain.addGroup(groupMatcher.group(1));
} else if (customMatcher.matches()) {
String domainName = customMatcher.group(1);
- DomainFactory> domainFactory = WorldGuard.getInstance().getDomainRegistry().get(domainName);
- if (domainFactory == null) {
+ CustomDomain customDomain = WorldGuard.getInstance().getDomainRegistry().createDomain(domainName);
+ if (customDomain == null) {
throw new InvalidDomainFormat("No domain named '" + domainName + "' found.");
}
- CustomDomain customDomain = domainFactory.create(domainName);
customDomain.parseInput(CustomDomainContext.create()
.setSender(actor).setInput(customMatcher.group(2)).setObject("region", region).build());
} else {
From be23d4b031e4ba670bc6737d3a5813f0f8fa9426 Mon Sep 17 00:00:00 2001
From: Joo200
Date: Sun, 18 Sep 2022 18:31:03 +0200
Subject: [PATCH 09/11] Tidy up PR and fixed wrong javadoc
---
.../commands/CommandInputContext.java | 16 +++++++------
.../domains/registry/CustomDomainContext.java | 23 +++++++++++--------
.../domains/registry/DomainRegistry.java | 2 +-
.../domains/registry/UnknownDomain.java | 2 +-
.../permission/RegionPermissionModel.java | 2 +-
.../protection/flags/FlagContext.java | 11 ++++++---
6 files changed, 34 insertions(+), 22 deletions(-)
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java
index 737d062d3..12e86a27b 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/commands/CommandInputContext.java
@@ -26,7 +26,7 @@
import javax.annotation.Nullable;
import java.util.Map;
-public class CommandInputContext {
+public abstract class CommandInputContext {
protected final Actor sender;
protected final String input;
@@ -56,30 +56,32 @@ public String getUserInput() {
* @return Player
* @throws InvalidFlagFormat if the sender is not a player
*/
- public LocalPlayer getPlayerSender() throws InvalidFlagFormat {
+ public LocalPlayer getPlayerSender() throws T {
if (sender.isPlayer() && sender instanceof LocalPlayer) {
return (LocalPlayer) sender;
} else {
- throw new InvalidFlagFormat("Not a player");
+ throw createException("Not a player");
}
}
- public Integer getUserInputAsInt() throws InvalidFlagFormat {
+ public Integer getUserInputAsInt() throws T {
try {
return Integer.parseInt(input);
} catch (NumberFormatException e) {
- throw new InvalidFlagFormat("Not a number: " + input);
+ throw createException("Not a number: " + input);
}
}
- public Double getUserInputAsDouble() throws InvalidFlagFormat {
+ public Double getUserInputAsDouble() throws T {
try {
return Double.parseDouble(input);
} catch (NumberFormatException e) {
- throw new InvalidFlagFormat("Not a number: " + input);
+ throw createException("Not a number: " + input);
}
}
+ protected abstract T createException(String str);
+
/**
* Get an object from the context by key name.
* May return null if the object does not exist in the context.
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/CustomDomainContext.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/CustomDomainContext.java
index e534bc483..9948e908a 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/CustomDomainContext.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/CustomDomainContext.java
@@ -26,7 +26,7 @@
import javax.annotation.Nullable;
import java.util.Map;
-public final class CustomDomainContext extends CommandInputContext {
+public final class CustomDomainContext extends CommandInputContext {
private CustomDomainContext(Actor sender, String input, Map values) {
super(sender, input, values);
@@ -38,16 +38,16 @@ public static CustomDomainContext.CustomDomainContextBuilder create() {
}
/**
- * Create a copy of this FlagContext, with optional substitutions for values
+ * Create a copy of this CustomDomainContext, with optional substitutions for values
*
- * If any supplied variable is null, it will be ignored.
- * If a map is supplied, it will override this FlagContext's values of the same key,
- * but unprovided keys will not be overriden and will be returned as shallow copies.
+ * If any supplied variable is null, it will be ignored.
+ * If a map is supplied, it will override this CustomDomainContext's values of the same key,
+ * but unprovided keys will not be overriden and will be returned as shallow copies.
*
- * @param commandSender CommandSender for the new FlagContext to run under
- * @param s String of the user input for the new FlagContext
- * @param values map of values to override from the current FlagContext
- * @return a copy of this FlagContext
+ * @param commandSender CommandSender for the new CustomDomainContext to run under
+ * @param s String of the user input for the new CustomDomainContext
+ * @param values map of values to override from the current CustomDomainContext
+ * @return a copy of this CustomDomainContext
*/
public CustomDomainContext copyWith(@Nullable Actor commandSender, @Nullable String s, @Nullable Map values) {
Map map = Maps.newHashMap();
@@ -58,6 +58,11 @@ public CustomDomainContext copyWith(@Nullable Actor commandSender, @Nullable Str
return new CustomDomainContext(commandSender == null ? this.sender : commandSender, s == null ? this.input : s, map);
}
+ @Override
+ protected InvalidDomainFormat createException(String str) {
+ return new InvalidDomainFormat(str);
+ }
+
public static class CustomDomainContextBuilder {
private Actor sender;
private String input;
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
index 8a7294b95..5fd8ac46b 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/DomainRegistry.java
@@ -49,7 +49,7 @@ public interface DomainRegistry extends Iterable> {
* no exception will be thrown.
*
* @param domains a collection of domain factories
- * @throws IllegalStateException If it is not the right time to register new flags
+ * @throws IllegalStateException If it is not the right time to register new domains
*/
void registerAll(Map> domains);
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
index 5aa83f460..2d093ca0d 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
@@ -35,7 +35,7 @@ public UnknownDomain(String name) {
@Override
public void parseInput(CustomDomainContext context) throws InvalidDomainFormat {
- throw new InvalidDomainFormat("The plugin that registered this flag is not currently installed");
+ throw new InvalidDomainFormat("The plugin that registered this domain is not currently installed");
}
@Override
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/internal/permission/RegionPermissionModel.java b/worldguard-core/src/main/java/com/sk89q/worldguard/internal/permission/RegionPermissionModel.java
index 966801375..5806dc7c0 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/internal/permission/RegionPermissionModel.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/internal/permission/RegionPermissionModel.java
@@ -179,7 +179,7 @@ public boolean mayRemoveOwners(ProtectedRegion region) {
}
/**
- * Checks to see if the given sender has permission to modify a custom region
+ * Checks to see if the given sender has permission to set or modify a custom domain
*
* @param region the region
* @param isOwnerLevel whether the domain level is owner (else member)
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/FlagContext.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/FlagContext.java
index d5d8cda65..3283de3a5 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/FlagContext.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/flags/FlagContext.java
@@ -27,7 +27,7 @@
import javax.annotation.Nullable;
import java.util.Map;
-public final class FlagContext extends CommandInputContext {
+public final class FlagContext extends CommandInputContext {
private FlagContext(Actor sender, String input, Map values) {
super(sender, input, values);
@@ -40,9 +40,9 @@ public static FlagContext.FlagContextBuilder create() {
/**
* Create a copy of this FlagContext, with optional substitutions for values
*
- * If any supplied variable is null, it will be ignored.
+ * If any supplied variable is null, it will be ignored.
* If a map is supplied, it will override this FlagContext's values of the same key,
- * but unprovided keys will not be overriden and will be returned as shallow copies.
+ * but unprovided keys will not be overriden and will be returned as shallow copies.
*
* @param commandSender CommandSender for the new FlagContext to run under
* @param s String of the user input for the new FlagContext
@@ -58,6 +58,11 @@ public FlagContext copyWith(@Nullable Actor commandSender, @Nullable String s, @
return new FlagContext(commandSender == null ? this.sender : commandSender, s == null ? this.input : s, map);
}
+ @Override
+ protected InvalidFlagFormat createException(String str) {
+ return new InvalidFlagFormat(str);
+ }
+
public static class FlagContextBuilder {
private Actor sender;
private String input;
From c8a6e598f80d31afb748acb6abc4b9c0a8d1f86f Mon Sep 17 00:00:00 2001
From: Joo200
Date: Sun, 25 Sep 2022 12:08:54 +0200
Subject: [PATCH 10/11] Add custom domain to domain when using command
---
.../sk89q/worldguard/protection/util/DomainInputResolver.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
index 855e37ed6..0d345feff 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/util/DomainInputResolver.java
@@ -141,6 +141,7 @@ public DefaultDomain call() throws UnresolvedNamesException, InvalidDomainFormat
}
customDomain.parseInput(CustomDomainContext.create()
.setSender(actor).setInput(customMatcher.group(2)).setObject("region", region).build());
+ domain.addCustomDomain(customDomain);
} else {
UUID uuid = parseUUID(s);
if (uuid != null) {
From 2dff68071f3a7f7b15a83f7a6fe3f3c59204acd7 Mon Sep 17 00:00:00 2001
From: stonar96
Date: Sat, 8 Oct 2022 14:20:29 +0200
Subject: [PATCH 11/11] Add non-player members
---
.../bukkit/BukkitWorldConfiguration.java | 1 +
.../worldguard/bukkit/WorldGuardPlugin.java | 63 +++++++++++++++
.../commands/region/RegionCommands.java | 18 +++++
.../worldguard/config/WorldConfiguration.java | 1 +
.../worldguard/domains/DefaultDomain.java | 5 ++
.../com/sk89q/worldguard/domains/Domain.java | 8 ++
.../sk89q/worldguard/domains/GroupDomain.java | 5 ++
.../worldguard/domains/PlayerDomain.java | 5 ++
.../domains/registry/UnknownDomain.java | 5 ++
.../AbstractRegionOverlapAssociation.java | 62 +++++---------
.../protection/regions/ProtectedRegion.java | 80 +++++++++++++++++++
.../worldguard/domains/CustomUUIDDomain.java | 5 ++
12 files changed, 217 insertions(+), 41 deletions(-)
diff --git a/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/BukkitWorldConfiguration.java b/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/BukkitWorldConfiguration.java
index 936f9803f..eed50d6bb 100644
--- a/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/BukkitWorldConfiguration.java
+++ b/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/BukkitWorldConfiguration.java
@@ -296,6 +296,7 @@ public void loadConfiguration() {
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);
diff --git a/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java b/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java
index e95d1aec1..21567dd0d 100644
--- a/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java
+++ b/worldguard-bukkit/src/main/java/com/sk89q/worldguard/bukkit/WorldGuardPlugin.java
@@ -64,6 +64,8 @@
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.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 static WorldGuardPlugin inst() {
return inst;
}
+ @Override
+ public void onLoad() {
+ WorldGuard.getInstance().getDomainRegistry().register("nonplayer-protection-domains", n -> new CustomDomain(n) {
+ private final Set 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.
*/
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 104184955..21bef1408 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
@@ -53,6 +53,9 @@
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.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 void claim(CommandContext args, Actor sender) throws CommandException {
}
}
+ 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)));
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/config/WorldConfiguration.java b/worldguard-core/src/main/java/com/sk89q/worldguard/config/WorldConfiguration.java
index 33a92339c..dfdcf8e5a 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/config/WorldConfiguration.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/config/WorldConfiguration.java
@@ -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;
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
index d14604920..37cf55ec1 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java
@@ -324,6 +324,11 @@ public boolean contains(String playerName) {
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();
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/Domain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/Domain.java
index 8c3235aba..24ce6e3fc 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/Domain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/Domain.java
@@ -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.
*
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/GroupDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/GroupDomain.java
index 83d6d9c3f..277ef863a 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/GroupDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/GroupDomain.java
@@ -120,6 +120,11 @@ public boolean contains(String playerName) {
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();
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/PlayerDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/PlayerDomain.java
index 084946219..cba554b15 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/PlayerDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/PlayerDomain.java
@@ -184,6 +184,11 @@ public boolean contains(String playerName) {
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();
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
index 2d093ca0d..d6b82e515 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/domains/registry/UnknownDomain.java
@@ -58,6 +58,11 @@ public boolean contains(String playerName) {
return false;
}
+ @Override
+ public boolean containsNonplayer(String nonplayerProtectionDomain) {
+ return false;
+ }
+
@Override
public int size() {
return 0;
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 0cbd78fe0..c4b1823a0 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,13 +22,9 @@
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 @@ protected void calcMaxPriority() {
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 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 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 Association getAssociation(List regions) {
}
}
- Set source;
+ current = current.getParent();
+ }
- if (useMaxPriorityAssociation) {
- source = maxPriorityRegions;
- } else {
- source = this.source;
- }
+ Set 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;
}
}
diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedRegion.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedRegion.java
index 76a527ccc..3cf2200fd 100644
--- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedRegion.java
+++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedRegion.java
@@ -26,7 +26,9 @@
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.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 boolean isOwner(String playerName) {
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 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 boolean isMember(String playerName) {
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 boolean isMemberOnly(LocalPlayer player) {
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 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.
*
diff --git a/worldguard-core/src/test/java/com/sk89q/worldguard/domains/CustomUUIDDomain.java b/worldguard-core/src/test/java/com/sk89q/worldguard/domains/CustomUUIDDomain.java
index 1f9dfd7bf..525a5c0c6 100644
--- a/worldguard-core/src/test/java/com/sk89q/worldguard/domains/CustomUUIDDomain.java
+++ b/worldguard-core/src/test/java/com/sk89q/worldguard/domains/CustomUUIDDomain.java
@@ -57,6 +57,11 @@ public boolean contains(String playerName) {
return false;
}
+ @Override
+ public boolean containsNonplayer(String nonplayerProtectionDomain) {
+ return false;
+ }
+
@Override
public void clear() {
test = null;