diff --git a/api/src/main/java/me/lucko/luckperms/api/Node.java b/api/src/main/java/me/lucko/luckperms/api/Node.java
index 5da591ec..67d27210 100644
--- a/api/src/main/java/me/lucko/luckperms/api/Node.java
+++ b/api/src/main/java/me/lucko/luckperms/api/Node.java
@@ -28,6 +28,13 @@ package me.lucko.luckperms.api;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.context.ContextSet;
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+import me.lucko.luckperms.api.nodetype.types.InheritanceType;
+import me.lucko.luckperms.api.nodetype.types.MetaType;
+import me.lucko.luckperms.api.nodetype.types.PrefixType;
+import me.lucko.luckperms.api.nodetype.types.SuffixType;
+import me.lucko.luckperms.api.nodetype.types.WeightType;
import java.util.Date;
import java.util.List;
@@ -64,7 +71,7 @@ import javax.annotation.concurrent.Immutable;
*
*
* {@link #getPermission() permission} - the actual permission string
- * {@link #getValuePrimitive() value} - the value of the node (false for negated)
+ * {@link #getValue() value} - the value of the node (false for negated)
* {@link #isOverride() override} - if the node is marked as having special priority over other nodes
* {@link #getServer() server} - the specific server where this node should apply
* {@link #getWorld() world} - the specific world where this node should apply
@@ -72,14 +79,22 @@ import javax.annotation.concurrent.Immutable;
* {@link #getExpiry() expiry} - the time when this node should expire
*
*
- * Nodes can also fall into the following sub categories.
+ * The 'permission' property of a {@link Node} is also used in some cases to represent state
+ * beyond a granted permission. This state is encapsulated by extra {@link NodeType} data which
+ * can be obtained from this instance using {@link #getTypeData(NodeTypeKey)}.
+ *
+ * Type data is mapped by {@link NodeTypeKey}s, which are usually stored as static members of the
+ * corresponding {@link NodeType} class under the KEY
field.
+ *
+ * The current types are:
*
*
* normal - just a regular permission
- * {@link #isGroupNode() group node} - a "group node" marks that the holder should inherit data from another group
- * {@link #isPrefix() prefix} - represents an assigned prefix
- * {@link #isSuffix() suffix} - represents an assigned suffix
- * {@link #isMeta() meta} - represents an assigned meta option
+ * {@link InheritanceType} - an "inheritance node" marks that the holder should inherit data from another group
+ * {@link PrefixType} - represents an assigned prefix
+ * {@link SuffixType} - represents an assigned suffix
+ * {@link MetaType} - represents an assigned meta option
+ * {@link WeightType} - marks the weight of the object holding this node
*
*
* The core node state must be immutable in all implementations.
@@ -108,19 +123,7 @@ public interface Node {
*
* @return the nodes value
*/
- @Nonnull
- default Boolean getValue() {
- return getValuePrimitive();
- }
-
- /**
- * Gets the value of the node.
- *
- * A negated setting would result in a value of false
.
- *
- * @return the nodes value
- */
- boolean getValuePrimitive();
+ boolean getValue();
/**
* Gets the value of this node as a {@link Tristate}.
@@ -129,18 +132,18 @@ public interface Node {
*/
@Nonnull
default Tristate getTristate() {
- return Tristate.fromBoolean(getValuePrimitive());
+ return Tristate.fromBoolean(getValue());
}
/**
* Gets if the node is negated.
*
- * This is the inverse of the {@link #getValuePrimitive() value}.
+ * This is the inverse of the {@link #getValue() value}.
*
* @return true if the node is negated
*/
default boolean isNegated() {
- return !getValuePrimitive();
+ return !getValue();
}
/**
@@ -209,7 +212,8 @@ public interface Node {
boolean shouldApplyWithContext(@Nonnull ContextSet contextSet);
/**
- * Resolves any shorthand parts of this node and returns the full list.
+ * Resolves any shorthand parts of this node and returns the full list of
+ * resolved nodes.
*
* The list will not contain the exact permission itself.
*
@@ -219,7 +223,7 @@ public interface Node {
List resolveShorthand();
/**
- * Gets if this node is temporary (will automatically expire).
+ * Gets if this node is assigned temporarily.
*
* @return true if this node will expire in the future
*/
@@ -291,30 +295,6 @@ public interface Node {
@Nonnull
ContextSet getFullContexts();
- /**
- * Returns if the node is a "standard" permission node.
- *
- * @return true if this is a regular permission node
- * @since 4.2
- */
- boolean isRegularPermissionNode();
-
- /**
- * Returns if this is a group node.
- *
- * @return true if this is a group node
- */
- boolean isGroupNode();
-
- /**
- * Gets the name of the group, if this is a group node.
- *
- * @return the name of the group
- * @throws IllegalStateException if this is not a group node. See {@link #isGroupNode()}
- */
- @Nonnull
- String getGroupName() throws IllegalStateException;
-
/**
* Gets if this node is a wildcard permission.
*
@@ -325,58 +305,135 @@ public interface Node {
/**
* Gets the level of this wildcard.
*
+ * The node luckperms.*
has a wildcard level of 1.
+ * The node luckperms.user.permission.*
has a wildcard level of 3.
+ *
+ * Nodes with a higher wildcard level are more specific and have priority over
+ * less specific nodes (nodes with a lower wildcard level).
+ *
* @return the wildcard level
* @throws IllegalStateException if this is not a wildcard
*/
int getWildcardLevel() throws IllegalStateException;
/**
- * Gets if this node is a meta node.
+ * Gets if this node has any extra {@link NodeType} data attached to it.
*
- * @return true if this node is a meta node
+ * @return if this node has any type data
+ * @since 4.2
*/
- boolean isMeta();
+ boolean hasTypeData();
/**
- * Gets the meta value from this node.
+ * Gets the type data corresponding to the given key
, if present.
*
- * @return the meta value
- * @throws IllegalStateException if this node is not a meta node
+ * @param key the key
+ * @param the {@link NodeType} type
+ * @return the data, if present
+ * @since 4.2
+ */
+ Optional getTypeData(NodeTypeKey key);
+
+ /**
+ * Gets the type data corresponding to the given key
, throwing an exception
+ * if no data is present.
+ *
+ * @param key the key
+ * @param the {@link NodeType} type
+ * @return the data
+ * @throws IllegalStateException if data isn't present
+ * @since 4.2
+ */
+ default T typeData(NodeTypeKey key) throws IllegalStateException {
+ return getTypeData(key)
+ .orElseThrow(() ->
+ new IllegalStateException("Node '" + getPermission() + "' does not have the '" + key.getTypeName() + "' type.")
+ );
+ }
+
+ /**
+ * Gets if this node has {@link InheritanceType} type data.
+ *
+ * @return true if this is a inheritance (group) node.
+ */
+ default boolean isGroupNode() {
+ return getTypeData(InheritanceType.KEY).isPresent();
+ }
+
+ /**
+ * Gets the name of the inherited group if this node has {@link InheritanceType} type data,
+ * throwing an exception if the data is not present.
+ *
+ * @return the name of the group
+ * @throws IllegalStateException if this node doesn't have {@link InheritanceType} data
*/
@Nonnull
- Map.Entry getMeta() throws IllegalStateException;
+ default String getGroupName() throws IllegalStateException {
+ return typeData(InheritanceType.KEY).getGroupName();
+ }
/**
- * Gets if this node is a prefix node.
+ * Gets if this node has {@link MetaType} type data.
+ *
+ * @return true if this is a meta node.
+ */
+ default boolean isMeta() {
+ return getTypeData(MetaType.KEY).isPresent();
+ }
+
+ /**
+ * Gets the meta entry if this node has {@link MetaType} type data,
+ * throwing an exception if the data is not present.
+ *
+ * @return the meta entry
+ * @throws IllegalStateException if this node doesn't have {@link MetaType} data
+ */
+ @Nonnull
+ default Map.Entry getMeta() throws IllegalStateException {
+ return typeData(MetaType.KEY);
+ }
+
+ /**
+ * Gets if this node has {@link PrefixType} type data.
*
* @return true if this node is a prefix node
*/
- boolean isPrefix();
+ default boolean isPrefix() {
+ return getTypeData(PrefixType.KEY).isPresent();
+ }
/**
- * Gets the prefix value from this node.
+ * Gets the prefix entry if this node has {@link PrefixType} type data,
+ * throwing an exception if the data is not present.
*
- * @return the prefix value
- * @throws IllegalStateException if this node is a not a prefix node
+ * @return the meta entry
+ * @throws IllegalStateException if this node doesn't have {@link PrefixType} data
*/
@Nonnull
- Map.Entry getPrefix() throws IllegalStateException;
+ default Map.Entry getPrefix() throws IllegalStateException {
+ return typeData(PrefixType.KEY).getAsEntry();
+ }
/**
- * Gets if this node is a suffix node.
+ * Gets if this node has {@link SuffixType} type data.
*
* @return true if this node is a suffix node
*/
- boolean isSuffix();
+ default boolean isSuffix() {
+ return getTypeData(SuffixType.KEY).isPresent();
+ }
/**
- * Gets the suffix value from this node.
+ * Gets the suffix entry if this node has {@link SuffixType} type data,
+ * throwing an exception if the data is not present.
*
- * @return the suffix value
- * @throws IllegalStateException if this node is a not a suffix node
+ * @return the meta entry
+ * @throws IllegalStateException if this node doesn't have {@link SuffixType} data
*/
@Nonnull
- Map.Entry getSuffix() throws IllegalStateException;
+ default Map.Entry getSuffix() throws IllegalStateException {
+ return typeData(SuffixType.KEY).getAsEntry();
+ }
/**
* Gets if this Node is equal to another node.
diff --git a/api/src/main/java/me/lucko/luckperms/api/nodetype/NodeType.java b/api/src/main/java/me/lucko/luckperms/api/nodetype/NodeType.java
new file mode 100644
index 00000000..abfb3d13
--- /dev/null
+++ b/api/src/main/java/me/lucko/luckperms/api/nodetype/NodeType.java
@@ -0,0 +1,44 @@
+/*
+ * This file is part of LuckPerms, licensed under the MIT License.
+ *
+ * Copyright (c) lucko (Luck)
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.lucko.luckperms.api.nodetype;
+
+import me.lucko.luckperms.api.Node;
+
+/**
+ * Superinterface for extended {@link Node} types.
+ *
+ * The 'permission' property of a {@link Node} is also used in some cases to represent state
+ * beyond a granted permission. This state is encapsulated by extra {@link NodeType} data which
+ * can be obtained from this instance using {@link Node#getTypeData(NodeTypeKey)}.
+ *
+ * Type data is mapped by {@link NodeTypeKey}s, which are usually stored as static members of the
+ * corresponding {@link NodeType} class under the KEY
field.
+ *
+ * @since 4.2
+ */
+public interface NodeType {
+
+}
diff --git a/api/src/main/java/me/lucko/luckperms/api/nodetype/NodeTypeKey.java b/api/src/main/java/me/lucko/luckperms/api/nodetype/NodeTypeKey.java
new file mode 100644
index 00000000..32f2dedc
--- /dev/null
+++ b/api/src/main/java/me/lucko/luckperms/api/nodetype/NodeTypeKey.java
@@ -0,0 +1,56 @@
+/*
+ * This file is part of LuckPerms, licensed under the MIT License.
+ *
+ * Copyright (c) lucko (Luck)
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.lucko.luckperms.api.nodetype;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Marks an instance used as a key for a {@link NodeType}.
+ *
+ * A single instance of this interface is created and stored statically for
+ * each sub-interface of {@link NodeType}.
+ *
+ * @param the type of the {@link NodeType} being indexed by this key
+ * @since 4.2
+ */
+public interface NodeTypeKey {
+
+ /**
+ * Gets the {@link Class#getSimpleName() class name} of the represented type.
+ *
+ * @return the name of the represented type
+ */
+ @Nonnull
+ default String getTypeName() {
+ ParameterizedType thisType = (ParameterizedType) getClass().getGenericSuperclass();
+ Type nodeType = thisType.getActualTypeArguments()[0];
+ return ((Class) nodeType).getSimpleName();
+ }
+
+}
diff --git a/api/src/main/java/me/lucko/luckperms/api/nodetype/types/InheritanceType.java b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/InheritanceType.java
new file mode 100644
index 00000000..8f5ba38d
--- /dev/null
+++ b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/InheritanceType.java
@@ -0,0 +1,57 @@
+/*
+ * This file is part of LuckPerms, licensed under the MIT License.
+ *
+ * Copyright (c) lucko (Luck)
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.lucko.luckperms.api.nodetype.types;
+
+import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A sub-type of {@link Node} used to mark that the holder of the node should inherit
+ * from another group.
+ *
+ * @since 4.2
+ */
+public interface InheritanceType extends NodeType {
+
+ /**
+ * The key for this type.
+ */
+ NodeTypeKey KEY = new NodeTypeKey(){};
+
+ /**
+ * Gets the name of the group to be inherited.
+ *
+ * This is no guarantee that this group exists.
+ *
+ * @return the name of the group
+ */
+ @Nonnull
+ String getGroupName();
+
+}
diff --git a/api/src/main/java/me/lucko/luckperms/api/nodetype/types/MetaType.java b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/MetaType.java
new file mode 100644
index 00000000..0f9c094c
--- /dev/null
+++ b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/MetaType.java
@@ -0,0 +1,69 @@
+/*
+ * This file is part of LuckPerms, licensed under the MIT License.
+ *
+ * Copyright (c) lucko (Luck)
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.lucko.luckperms.api.nodetype.types;
+
+import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A sub-type of {@link Node} used to store meta assignments.
+ *
+ * @since 4.2
+ */
+public interface MetaType extends NodeType, Map.Entry {
+
+ /**
+ * The key for this type.
+ */
+ NodeTypeKey KEY = new NodeTypeKey(){};
+
+ /**
+ * Gets the meta key.
+ *
+ * @return the meta key
+ */
+ @Nonnull
+ String getKey();
+
+ /**
+ * Gets the meta value.
+ *
+ * @return the meta value
+ */
+ @Nonnull
+ String getValue();
+
+ @Override
+ @Deprecated
+ default String setValue(String value) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/api/src/main/java/me/lucko/luckperms/api/nodetype/types/PrefixType.java b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/PrefixType.java
new file mode 100644
index 00000000..c3a052dc
--- /dev/null
+++ b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/PrefixType.java
@@ -0,0 +1,71 @@
+/*
+ * This file is part of LuckPerms, licensed under the MIT License.
+ *
+ * Copyright (c) lucko (Luck)
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.lucko.luckperms.api.nodetype.types;
+
+import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A sub-type of {@link Node} used to store prefix assignments.
+ *
+ * @since 4.2
+ */
+public interface PrefixType extends NodeType {
+
+ /**
+ * The key for this type.
+ */
+ NodeTypeKey KEY = new NodeTypeKey(){};
+
+ /**
+ * Gets the priority of the prefix assignment.
+ *
+ * @return the priority
+ */
+ int getPriority();
+
+ /**
+ * Gets the actual prefix string.
+ *
+ * @return the prefix
+ */
+ @Nonnull
+ String getPrefix();
+
+ /**
+ * Gets a representation of this instance as a {@link Map.Entry}.
+ *
+ * @return a map entry representation of the priority and prefix string
+ */
+ @Nonnull
+ Map.Entry getAsEntry();
+
+}
diff --git a/api/src/main/java/me/lucko/luckperms/api/nodetype/types/SuffixType.java b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/SuffixType.java
new file mode 100644
index 00000000..3a5b7187
--- /dev/null
+++ b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/SuffixType.java
@@ -0,0 +1,71 @@
+/*
+ * This file is part of LuckPerms, licensed under the MIT License.
+ *
+ * Copyright (c) lucko (Luck)
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.lucko.luckperms.api.nodetype.types;
+
+import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A sub-type of {@link Node} used to store suffix assignments.
+ *
+ * @since 4.2
+ */
+public interface SuffixType extends NodeType {
+
+ /**
+ * The key for this type.
+ */
+ NodeTypeKey KEY = new NodeTypeKey(){};
+
+ /**
+ * Gets the priority of the suffix assignment.
+ *
+ * @return the priority
+ */
+ int getPriority();
+
+ /**
+ * Gets the actual suffix string.
+ *
+ * @return the suffix
+ */
+ @Nonnull
+ String getSuffix();
+
+ /**
+ * Gets a representation of this instance as a {@link Map.Entry}.
+ *
+ * @return a map entry representation of the priority and suffix string
+ */
+ @Nonnull
+ Map.Entry getAsEntry();
+
+}
diff --git a/common/src/main/java/me/lucko/luckperms/common/references/HolderReference.java b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/WeightType.java
similarity index 65%
rename from common/src/main/java/me/lucko/luckperms/common/references/HolderReference.java
rename to api/src/main/java/me/lucko/luckperms/api/nodetype/types/WeightType.java
index 834d01e4..b4f78192 100644
--- a/common/src/main/java/me/lucko/luckperms/common/references/HolderReference.java
+++ b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/WeightType.java
@@ -23,34 +23,29 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.references;
+package me.lucko.luckperms.api.nodetype.types;
-import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-
-import java.util.function.Consumer;
+import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
/**
- * A reference to a specific {@link PermissionHolder}.
+ * A sub-type of {@link Node} used to mark the weight of the node's holder.
*
- * @param the holder type
- * @param the holder identifier type
+ * @since 4.2
*/
-public interface HolderReference extends Identifiable {
+public interface WeightType extends NodeType {
/**
- * Gets the holder type
- *
- * @return the holder type
+ * The key for this type.
*/
- HolderType getType();
+ NodeTypeKey KEY = new NodeTypeKey(){};
/**
- * Applies an action to this reference, if it is present and exists.
+ * Gets the weight value.
*
- * @param plugin the plugin
- * @param consumer the action
+ * @return the weight
*/
- void apply(LuckPermsPlugin plugin, Consumer consumer);
+ int getWeight();
}
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculators/BukkitCalculatorFactory.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculators/BukkitCalculatorFactory.java
index 07755aee..55e3ef2a 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculators/BukkitCalculatorFactory.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/calculators/BukkitCalculatorFactory.java
@@ -36,11 +36,11 @@ import me.lucko.luckperms.common.calculators.AbstractCalculatorFactory;
import me.lucko.luckperms.common.calculators.PermissionCalculator;
import me.lucko.luckperms.common.calculators.PermissionCalculatorMetadata;
import me.lucko.luckperms.common.config.ConfigKeys;
+import me.lucko.luckperms.common.model.HolderType;
import me.lucko.luckperms.common.processors.MapProcessor;
import me.lucko.luckperms.common.processors.PermissionProcessor;
import me.lucko.luckperms.common.processors.RegexProcessor;
import me.lucko.luckperms.common.processors.WildcardProcessor;
-import me.lucko.luckperms.common.references.HolderType;
public class BukkitCalculatorFactory extends AbstractCalculatorFactory {
private final LPBukkitPlugin plugin;
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationBPermissions.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationBPermissions.java
index 7669851a..a0e09b49 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationBPermissions.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationBPermissions.java
@@ -42,7 +42,8 @@ import me.lucko.luckperms.common.logging.ProgressLogger;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
+import me.lucko.luckperms.common.node.model.NodeTypes;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Iterators;
@@ -212,7 +213,7 @@ public class MigrationBPermissions extends SubCommand {
continue;
}
- if (meta.getKey().equalsIgnoreCase(NodeFactory.PREFIX_KEY) || meta.getKey().equalsIgnoreCase(NodeFactory.SUFFIX_KEY)) {
+ if (meta.getKey().equalsIgnoreCase(NodeTypes.PREFIX_KEY) || meta.getKey().equalsIgnoreCase(NodeTypes.SUFFIX_KEY)) {
ChatMetaType type = ChatMetaType.valueOf(meta.getKey().toUpperCase());
holder.setPermission(NodeFactory.buildChatMetaNode(type, c.getPriority(), meta.getValue()).setWorld(world.getName()).build());
continue;
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationGroupManager.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationGroupManager.java
index cb584a3c..67ef7276 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationGroupManager.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationGroupManager.java
@@ -37,9 +37,10 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.logging.ProgressLogger;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.model.UserIdentifier;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
+import me.lucko.luckperms.common.node.model.NodeTypes;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.UserIdentifier;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Iterators;
import me.lucko.luckperms.common.utils.Predicates;
@@ -149,7 +150,7 @@ public class MigrationGroupManager extends SubCommand {
if (key.isEmpty() || value.isEmpty()) continue;
if (key.equals("build")) continue;
- if (key.equals(NodeFactory.PREFIX_KEY) || key.equals(NodeFactory.SUFFIX_KEY)) {
+ if (key.equals(NodeTypes.PREFIX_KEY) || key.equals(NodeTypes.SUFFIX_KEY)) {
ChatMetaType type = ChatMetaType.valueOf(key.toUpperCase());
groups.get(groupName).add(NodeFactory.buildChatMetaNode(type, 50, value).setWorld(worldMappingFunc.apply(world)).build());
} else {
@@ -201,7 +202,7 @@ public class MigrationGroupManager extends SubCommand {
if (key.isEmpty() || value.isEmpty()) continue;
if (key.equals("build")) continue;
- if (key.equals(NodeFactory.PREFIX_KEY) || key.equals(NodeFactory.SUFFIX_KEY)) {
+ if (key.equals(NodeTypes.PREFIX_KEY) || key.equals(NodeTypes.SUFFIX_KEY)) {
ChatMetaType type = ChatMetaType.valueOf(key.toUpperCase());
users.get(id).add(NodeFactory.buildChatMetaNode(type, 100, value).setWorld(worldMappingFunc.apply(world)).build());
} else {
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsBukkit.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsBukkit.java
index ef888f6b..306639cc 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsBukkit.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsBukkit.java
@@ -38,7 +38,7 @@ import me.lucko.luckperms.common.logging.ProgressLogger;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Iterators;
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsEx.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsEx.java
index 63d0e4f2..af9d26f8 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsEx.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsEx.java
@@ -39,7 +39,8 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
+import me.lucko.luckperms.common.node.model.NodeTypes;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Iterators;
@@ -288,9 +289,9 @@ public class MigrationPermissionsEx extends SubCommand {
}
String key = opt.getKey().toLowerCase();
- boolean ignore = key.equals(NodeFactory.PREFIX_KEY) ||
- key.equals(NodeFactory.SUFFIX_KEY) ||
- key.equals(NodeFactory.WEIGHT_KEY) ||
+ boolean ignore = key.equals(NodeTypes.PREFIX_KEY) ||
+ key.equals(NodeTypes.SUFFIX_KEY) ||
+ key.equals(NodeTypes.WEIGHT_KEY) ||
key.equals("rank") ||
key.equals("rank-ladder") ||
key.equals("name") ||
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPowerfulPerms.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPowerfulPerms.java
index 4b9c66ff..c4103d5f 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPowerfulPerms.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPowerfulPerms.java
@@ -44,7 +44,7 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.logging.ProgressLogger;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.storage.StorageType;
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationZPermissions.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationZPermissions.java
index e4e4723b..13e886c7 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationZPermissions.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationZPermissions.java
@@ -39,7 +39,8 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
+import me.lucko.luckperms.common.node.model.NodeTypes;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Iterators;
@@ -218,7 +219,7 @@ public class MigrationZPermissions extends SubCommand {
String valueString = value.toString();
if (valueString.isEmpty()) continue;
- if (key.equals(NodeFactory.PREFIX_KEY) || key.equals(NodeFactory.SUFFIX_KEY)) {
+ if (key.equals(NodeTypes.PREFIX_KEY) || key.equals(NodeTypes.SUFFIX_KEY)) {
ChatMetaType type = ChatMetaType.valueOf(key.toUpperCase());
holder.setPermission(NodeFactory.buildChatMetaNode(type, weight, valueString).build());
} else {
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissionAttachment.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissionAttachment.java
index 11dcd3d8..e31cf888 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissionAttachment.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissionAttachment.java
@@ -31,8 +31,8 @@ import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.bukkit.model.dummy.DummyPlugin;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.ImmutableTransientNode;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
+import me.lucko.luckperms.common.node.model.ImmutableTransientNode;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionRemovedExecutor;
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java
index 7e5e4eda..eef205c7 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultChatHook.java
@@ -39,7 +39,8 @@ import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
+import me.lucko.luckperms.common.node.model.NodeTypes;
import net.milkbowl.vault.chat.Chat;
@@ -318,7 +319,7 @@ public class VaultChatHook extends AbstractVaultChat {
}
Node.Builder metaNode;
- if (key.equalsIgnoreCase(NodeFactory.PREFIX_KEY) || key.equalsIgnoreCase(NodeFactory.SUFFIX_KEY)) {
+ if (key.equalsIgnoreCase(NodeTypes.PREFIX_KEY) || key.equalsIgnoreCase(NodeTypes.SUFFIX_KEY)) {
metaNode = NodeFactory.buildChatMetaNode(ChatMetaType.valueOf(key.toUpperCase()), 100, value.toString());
} else {
metaNode = NodeFactory.buildMetaNode(key, value.toString());
diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java
index b560701e..23ab529a 100644
--- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java
+++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java
@@ -39,7 +39,7 @@ import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.verbose.CheckOrigin;
import net.milkbowl.vault.permission.Permission;
@@ -210,7 +210,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
ContextSet contexts = contextForLookup(user, world).getContexts();
- String[] ret = user.getEnduringNodes().values().stream()
+ String[] ret = user.enduringData().immutable().values().stream()
.filter(Node::isGroupNode)
.filter(n -> n.shouldApplyWithContext(contexts))
.map(n -> {
diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/migration/MigrationBungeePerms.java b/bungee/src/main/java/me/lucko/luckperms/bungee/migration/MigrationBungeePerms.java
index 26774be2..91a4e404 100644
--- a/bungee/src/main/java/me/lucko/luckperms/bungee/migration/MigrationBungeePerms.java
+++ b/bungee/src/main/java/me/lucko/luckperms/bungee/migration/MigrationBungeePerms.java
@@ -34,7 +34,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.logging.ProgressLogger;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Iterators;
diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/manager/ApiGroupManager.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/manager/ApiGroupManager.java
index 168d7746..8282bf70 100644
--- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/manager/ApiGroupManager.java
+++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/manager/ApiGroupManager.java
@@ -31,7 +31,7 @@ import me.lucko.luckperms.common.api.ApiUtils;
import me.lucko.luckperms.common.api.delegates.model.ApiGroup;
import me.lucko.luckperms.common.managers.group.GroupManager;
import me.lucko.luckperms.common.model.Group;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/manager/ApiUserManager.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/manager/ApiUserManager.java
index c1526a60..0224baa5 100644
--- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/manager/ApiUserManager.java
+++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/manager/ApiUserManager.java
@@ -29,8 +29,8 @@ import me.lucko.luckperms.common.api.ApiUtils;
import me.lucko.luckperms.common.api.delegates.model.ApiUser;
import me.lucko.luckperms.common.managers.user.UserManager;
import me.lucko.luckperms.common.model.User;
+import me.lucko.luckperms.common.model.UserIdentifier;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.UserIdentifier;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import java.util.Objects;
diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/misc/ApiNodeFactory.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/misc/ApiNodeFactory.java
index bc457ea9..266804df 100644
--- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/misc/ApiNodeFactory.java
+++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/misc/ApiNodeFactory.java
@@ -29,7 +29,7 @@ import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.api.delegates.model.ApiGroup;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import java.util.Objects;
diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java
index 589f7723..137f6c4f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java
+++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java
@@ -36,6 +36,7 @@ import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.NodeEqualityPredicate;
+import me.lucko.luckperms.api.StandardNodeEquality;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.caching.CachedData;
import me.lucko.luckperms.api.context.ContextSet;
@@ -44,14 +45,18 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.MetaType;
+import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.utils.MetaType;
+import me.lucko.luckperms.common.node.utils.NodeTools;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
+import java.util.TreeSet;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
@@ -99,13 +104,13 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.PermissionHol
@Nonnull
@Override
public ImmutableSetMultimap getNodes() {
- return this.handle.getEnduringNodes();
+ return this.handle.enduringData().immutable();
}
@Nonnull
@Override
public ImmutableSetMultimap getTransientNodes() {
- return this.handle.getTransientNodes();
+ return this.handle.transientData().immutable();
}
@Nonnull
@@ -123,33 +128,55 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.PermissionHol
@Nonnull
@Override
public Set getEnduringPermissions() {
- return ImmutableSet.copyOf(this.handle.getEnduringNodes().values());
+ return ImmutableSet.copyOf(this.handle.enduringData().immutable().values());
}
@Nonnull
@Override
public Set getTransientPermissions() {
- return ImmutableSet.copyOf(this.handle.getTransientNodes().values());
+ return ImmutableSet.copyOf(this.handle.transientData().immutable().values());
}
@Nonnull
@Override
public SortedSet getAllNodes(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
- return ImmutableSortedSet.copyOfSorted(this.handle.resolveInheritancesAlmostEqual(contexts));
+
+ List nodes = new LinkedList<>();
+ this.handle.accumulateInheritancesTo(nodes, contexts);
+ NodeTools.removeEqual(nodes.iterator(), StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
+
+ SortedSet ret = new TreeSet<>(NodeWithContextComparator.reverse());
+ ret.addAll(nodes);
+
+ return ImmutableSortedSet.copyOfSorted(ret);
}
@Nonnull
@Override
public SortedSet getAllNodes() {
- return ImmutableSortedSet.copyOfSorted(this.handle.resolveInheritancesAlmostEqual());
+ List nodes = new LinkedList<>();
+ this.handle.accumulateInheritancesTo(nodes);
+ NodeTools.removeEqual(nodes.iterator(), StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
+
+ SortedSet ret = new TreeSet<>(NodeWithContextComparator.reverse());
+ ret.addAll(nodes);
+
+ return ImmutableSortedSet.copyOfSorted(ret);
}
@Nonnull
@Override
public Set getAllNodesFiltered(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
- return ImmutableSet.copyOf(this.handle.getAllNodes(contexts));
+
+ List entries = this.handle.getAllEntries(contexts);
+
+ NodeTools.removeSamePermission(entries.iterator());
+ SortedSet ret = new TreeSet<>(NodeWithContextComparator.reverse());
+ ret.addAll(entries);
+
+ return ImmutableSet.copyOf(ret);
}
@Nonnull
@@ -187,21 +214,21 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.PermissionHol
@Override
public Tristate hasPermission(@Nonnull Node node) {
Objects.requireNonNull(node, "node");
- return this.handle.hasPermission(NodeMapType.ENDURING, node);
+ return this.handle.hasPermission(NodeMapType.ENDURING, node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
}
@Nonnull
@Override
public Tristate hasTransientPermission(@Nonnull Node node) {
Objects.requireNonNull(node, "node");
- return this.handle.hasPermission(NodeMapType.TRANSIENT, node);
+ return this.handle.hasPermission(NodeMapType.TRANSIENT, node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
}
@Nonnull
@Override
public Tristate inheritsPermission(@Nonnull Node node) {
Objects.requireNonNull(node, "node");
- return this.handle.inheritsPermission(node);
+ return this.handle.inheritsPermission(node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
}
@Override
diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiStorage.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiStorage.java
index 1a41f992..08da96c8 100644
--- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiStorage.java
+++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiStorage.java
@@ -33,7 +33,7 @@ import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.event.cause.CreationCause;
import me.lucko.luckperms.api.event.cause.DeletionCause;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.Storage;
diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java
index 504d84a0..9300dbdd 100644
--- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java
+++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java
@@ -28,9 +28,11 @@ package me.lucko.luckperms.common.api.delegates.model;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.DataMutateResult;
+import me.lucko.luckperms.api.StandardNodeEquality;
import me.lucko.luckperms.api.caching.UserData;
+import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import java.util.Objects;
import java.util.UUID;
@@ -80,7 +82,7 @@ public final class ApiUser extends ApiPermissionHolder implements me.lucko.luckp
return DataMutateResult.ALREADY_HAS;
}
- if (!this.handle.hasPermission(NodeFactory.buildGroupNode(group.toLowerCase()).build()).asBoolean()) {
+ if (!this.handle.hasPermission(NodeMapType.ENDURING, NodeFactory.buildGroupNode(group.toLowerCase()).build(), StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE).asBoolean()) {
return DataMutateResult.FAIL;
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/assignments/AssignmentExpression.java b/common/src/main/java/me/lucko/luckperms/common/assignments/AssignmentExpression.java
index 9719efff..f81844a8 100644
--- a/common/src/main/java/me/lucko/luckperms/common/assignments/AssignmentExpression.java
+++ b/common/src/main/java/me/lucko/luckperms/common/assignments/AssignmentExpression.java
@@ -30,8 +30,9 @@ import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.StandardNodeEquality;
import me.lucko.luckperms.api.Tristate;
+import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.LegacyNodeFactory;
+import me.lucko.luckperms.common.node.factory.LegacyNodeFactory;
import me.lucko.luckperms.common.utils.Scripting;
import java.util.List;
@@ -61,7 +62,7 @@ public class AssignmentExpression {
throw new NullPointerException("script engine");
}
- Predicate checker = node -> holder.hasPermission(node, StandardNodeEquality.IGNORE_VALUE_OR_IF_TEMPORARY) == tristate;
+ Predicate checker = node -> holder.hasPermission(NodeMapType.ENDURING, node, StandardNodeEquality.IGNORE_VALUE_OR_IF_TEMPORARY) == tristate;
String exp = this.expression.stream().map(t -> t.forExpression(checker)).collect(Collectors.joining())
.replace("&", "&&").replace("|", "||");
diff --git a/common/src/main/java/me/lucko/luckperms/common/assignments/AssignmentRule.java b/common/src/main/java/me/lucko/luckperms/common/assignments/AssignmentRule.java
index 36d9a1e6..c19a2331 100644
--- a/common/src/main/java/me/lucko/luckperms/common/assignments/AssignmentRule.java
+++ b/common/src/main/java/me/lucko/luckperms/common/assignments/AssignmentRule.java
@@ -28,7 +28,7 @@ package me.lucko.luckperms.common.assignments;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.LegacyNodeFactory;
+import me.lucko.luckperms.common.node.factory.LegacyNodeFactory;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import java.util.List;
diff --git a/common/src/main/java/me/lucko/luckperms/common/backup/Exporter.java b/common/src/main/java/me/lucko/luckperms/common/backup/Exporter.java
index 9036ad68..c8380b55 100644
--- a/common/src/main/java/me/lucko/luckperms/common/backup/Exporter.java
+++ b/common/src/main/java/me/lucko/luckperms/common/backup/Exporter.java
@@ -29,11 +29,11 @@ import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.logging.ProgressLogger;
import me.lucko.luckperms.common.model.Group;
+import me.lucko.luckperms.common.model.HolderType;
import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.HolderType;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.storage.Storage;
@@ -127,7 +127,7 @@ public class Exporter implements Runnable {
}
write(writer, "# Export group: " + group.getName());
- for (Node node : group.getEnduringNodes().values()) {
+ for (Node node : group.enduringData().immutable().values()) {
write(writer, "/lp " + NodeFactory.nodeAsCommand(node, group.getName(), HolderType.GROUP, true));
}
write(writer, "");
@@ -217,7 +217,7 @@ public class Exporter implements Runnable {
output.add("# Export user: " + user.getUuid().toString() + " - " + user.getName().orElse("unknown username"));
boolean inDefault = false;
- for (Node node : user.getEnduringNodes().values()) {
+ for (Node node : user.enduringData().immutable().values()) {
if (node.isGroupNode() && node.getGroupName().equalsIgnoreCase(NodeFactory.DEFAULT_GROUP_NAME)) {
inDefault = true;
continue;
@@ -242,7 +242,7 @@ public class Exporter implements Runnable {
}
// all of the threads have been scheduled now and are running. we just need to wait for them all to complete
- CompletableFuture overallFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
+ CompletableFuture overallFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
while (true) {
try {
diff --git a/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java b/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java
index 4b181719..3d07cc12 100644
--- a/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java
+++ b/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java
@@ -142,7 +142,7 @@ public class Importer implements Runnable {
}
// all of the threads have been scheduled now and are running. we just need to wait for them all to complete
- CompletableFuture overallFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
+ CompletableFuture overallFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
this.notify.forEach(s -> Message.IMPORT_INFO.send(s, "All commands have been processed and scheduled - now waiting for the execution to complete."));
diff --git a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/BulkUpdate.java b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/BulkUpdate.java
index 394132ea..d545a2f3 100644
--- a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/BulkUpdate.java
+++ b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/BulkUpdate.java
@@ -27,7 +27,7 @@ package me.lucko.luckperms.common.bulkupdate;
import me.lucko.luckperms.common.bulkupdate.action.Action;
import me.lucko.luckperms.common.bulkupdate.constraint.Constraint;
-import me.lucko.luckperms.common.node.NodeModel;
+import me.lucko.luckperms.common.node.model.NodeDataContainer;
import java.util.List;
import java.util.Objects;
@@ -59,7 +59,7 @@ public final class BulkUpdate {
* @param node the node to check
* @return true if satisfied
*/
- public boolean satisfiesConstraints(NodeModel node) {
+ public boolean satisfiesConstraints(NodeDataContainer node) {
for (Constraint constraint : this.constraints) {
if (!constraint.isSatisfiedBy(node)) {
return false;
@@ -74,7 +74,7 @@ public final class BulkUpdate {
* @param from the node to base changes from
* @return the new nodemodel instance, or null if the node should be deleted.
*/
- public NodeModel apply(NodeModel from) {
+ public NodeDataContainer apply(NodeDataContainer from) {
if (!satisfiesConstraints(from)) {
return from; // make no change
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/Action.java b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/Action.java
index eca6182d..038f5bb2 100644
--- a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/Action.java
+++ b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/Action.java
@@ -25,7 +25,7 @@
package me.lucko.luckperms.common.bulkupdate.action;
-import me.lucko.luckperms.common.node.NodeModel;
+import me.lucko.luckperms.common.node.model.NodeDataContainer;
/**
* Represents an action to be applied to a given node.
@@ -45,7 +45,7 @@ public interface Action {
* @param from the node to base changes from
* @return the new nodemodel instance, or null if the node should be deleted.
*/
- NodeModel apply(NodeModel from);
+ NodeDataContainer apply(NodeDataContainer from);
/**
* Gets this action in SQL form.
diff --git a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/DeleteAction.java b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/DeleteAction.java
index 350854d0..97c1a415 100644
--- a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/DeleteAction.java
+++ b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/DeleteAction.java
@@ -25,7 +25,7 @@
package me.lucko.luckperms.common.bulkupdate.action;
-import me.lucko.luckperms.common.node.NodeModel;
+import me.lucko.luckperms.common.node.model.NodeDataContainer;
public class DeleteAction implements Action {
@@ -42,7 +42,7 @@ public class DeleteAction implements Action {
}
@Override
- public NodeModel apply(NodeModel from) {
+ public NodeDataContainer apply(NodeDataContainer from) {
return null; // this action just deletes nodes, so return null
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/UpdateAction.java b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/UpdateAction.java
index b4f73484..0db5718e 100644
--- a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/UpdateAction.java
+++ b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/action/UpdateAction.java
@@ -27,7 +27,7 @@ package me.lucko.luckperms.common.bulkupdate.action;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.bulkupdate.constraint.QueryField;
-import me.lucko.luckperms.common.node.NodeModel;
+import me.lucko.luckperms.common.node.model.NodeDataContainer;
public class UpdateAction implements Action {
@@ -52,7 +52,7 @@ public class UpdateAction implements Action {
}
@Override
- public NodeModel apply(NodeModel from) {
+ public NodeDataContainer apply(NodeDataContainer from) {
switch (this.field) {
case PERMISSION:
return from.setPermission(this.value);
diff --git a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/constraint/Constraint.java b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/constraint/Constraint.java
index 8427f6b6..bcf96050 100644
--- a/common/src/main/java/me/lucko/luckperms/common/bulkupdate/constraint/Constraint.java
+++ b/common/src/main/java/me/lucko/luckperms/common/bulkupdate/constraint/Constraint.java
@@ -27,7 +27,7 @@ package me.lucko.luckperms.common.bulkupdate.constraint;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.bulkupdate.comparisons.Comparison;
-import me.lucko.luckperms.common.node.NodeModel;
+import me.lucko.luckperms.common.node.model.NodeDataContainer;
/**
* Represents a query constraint
@@ -59,7 +59,7 @@ public class Constraint {
* @param node the node
* @return true if satisfied
*/
- public boolean isSatisfiedBy(NodeModel node) {
+ public boolean isSatisfiedBy(NodeDataContainer node) {
switch (this.field) {
case PERMISSION:
return this.comparison.matches(node.getPermission(), this.value);
diff --git a/common/src/main/java/me/lucko/luckperms/common/caching/GroupCachedData.java b/common/src/main/java/me/lucko/luckperms/common/caching/GroupCachedData.java
index 27b91aa4..0e0099d6 100644
--- a/common/src/main/java/me/lucko/luckperms/common/caching/GroupCachedData.java
+++ b/common/src/main/java/me/lucko/luckperms/common/caching/GroupCachedData.java
@@ -29,7 +29,7 @@ import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.caching.GroupData;
import me.lucko.luckperms.common.calculators.PermissionCalculatorMetadata;
import me.lucko.luckperms.common.model.Group;
-import me.lucko.luckperms.common.references.HolderType;
+import me.lucko.luckperms.common.model.HolderType;
/**
* Holds an easily accessible cache of a groups's data in a number of contexts
diff --git a/common/src/main/java/me/lucko/luckperms/common/caching/UserCachedData.java b/common/src/main/java/me/lucko/luckperms/common/caching/UserCachedData.java
index a0849b50..52437af3 100644
--- a/common/src/main/java/me/lucko/luckperms/common/caching/UserCachedData.java
+++ b/common/src/main/java/me/lucko/luckperms/common/caching/UserCachedData.java
@@ -28,8 +28,8 @@ package me.lucko.luckperms.common.caching;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.common.calculators.PermissionCalculatorMetadata;
+import me.lucko.luckperms.common.model.HolderType;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.references.HolderType;
/**
* Holds an easily accessible cache of a user's data in a number of contexts
diff --git a/common/src/main/java/me/lucko/luckperms/common/caching/handlers/CachedStateManager.java b/common/src/main/java/me/lucko/luckperms/common/caching/handlers/CachedStateManager.java
deleted file mode 100644
index f0399399..00000000
--- a/common/src/main/java/me/lucko/luckperms/common/caching/handlers/CachedStateManager.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * This file is part of LuckPerms, licensed under the MIT License.
- *
- * Copyright (c) lucko (Luck)
- * Copyright (c) contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package me.lucko.luckperms.common.caching.handlers;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-
-import me.lucko.luckperms.common.references.HolderReference;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Manages the cached state of all permission holders
- */
-public class CachedStateManager {
-
- // Group --> Groups/Users that inherit from that group. (reverse relationship)
- private final Multimap map = HashMultimap.create();
- private final ReentrantLock lock = new ReentrantLock();
-
- /**
- * Gets a set of holder names that inherit permissions (either directly or via other groups)
- * from the given holder name
- *
- * @param holder the holder name to query for
- * @return a set of inherited groups
- */
- public Set getInheritances(HolderReference holder) {
- Set set = new HashSet<>();
- set.add(holder);
-
- this.lock.lock();
- try {
- while (true) {
- Set clone = new HashSet<>(set);
-
- boolean work = false;
-
- for (HolderReference s : clone) {
- if (set.addAll(this.map.get(s))) {
- work = true;
- }
- }
-
- if (!work) {
- break;
- }
- }
- } finally {
- this.lock.unlock();
- }
-
- set.remove(holder);
- return set;
- }
-
- /**
- * Registers a holder and the groups they inherit from within this map.
- *
- * @param holder the holder to add
- * @param inheritedGroups a list of groups the holder inherits from
- */
- public void putAll(HolderReference holder, Set inheritedGroups) {
- this.lock.lock();
- try {
- this.map.entries().removeIf(entry -> entry.getValue().equals(holder));
-
- for (HolderReference child : inheritedGroups) {
- this.map.put(child, holder);
- }
- } finally {
- this.lock.unlock();
- }
- }
-
- /**
- * Clears defined inheritances for the given holder name.
- *
- * @param holder the holder name to clear
- */
- public void clear(HolderReference holder) {
- this.lock.lock();
- try {
- this.map.entries().removeIf(entry -> entry.getValue().equals(holder));
- } finally {
- this.lock.unlock();
- }
- }
-
-}
diff --git a/common/src/main/java/me/lucko/luckperms/common/caching/type/MetaAccumulator.java b/common/src/main/java/me/lucko/luckperms/common/caching/type/MetaAccumulator.java
index 49372d2e..2b3c36a4 100644
--- a/common/src/main/java/me/lucko/luckperms/common/caching/type/MetaAccumulator.java
+++ b/common/src/main/java/me/lucko/luckperms/common/caching/type/MetaAccumulator.java
@@ -30,10 +30,13 @@ import com.google.common.collect.ListMultimap;
import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.LocalizedNode;
+import me.lucko.luckperms.api.nodetype.types.MetaType;
+import me.lucko.luckperms.api.nodetype.types.PrefixType;
+import me.lucko.luckperms.api.nodetype.types.SuffixType;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.metastacking.MetaStack;
import me.lucko.luckperms.common.metastacking.SimpleMetaStack;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.model.NodeTypes;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Comparator;
@@ -73,22 +76,19 @@ public class MetaAccumulator {
}
public void accumulateNode(LocalizedNode n) {
- if (n.isMeta()) {
- Map.Entry entry = n.getMeta();
- this.meta.put(entry.getKey(), entry.getValue());
- }
+ n.getTypeData(MetaType.KEY).ifPresent(metaType ->
+ this.meta.put(metaType.getKey(), metaType.getValue())
+ );
- if (n.isPrefix()) {
- Map.Entry value = n.getPrefix();
- this.prefixes.putIfAbsent(value.getKey(), value.getValue());
+ n.getTypeData(PrefixType.KEY).ifPresent(prefix -> {
+ this.prefixes.putIfAbsent(prefix.getPriority(), prefix.getPrefix());
this.prefixStack.accumulateToAll(n);
- }
+ });
- if (n.isSuffix()) {
- Map.Entry value = n.getSuffix();
- this.suffixes.putIfAbsent(value.getKey(), value.getValue());
+ n.getTypeData(SuffixType.KEY).ifPresent(suffix -> {
+ this.suffixes.putIfAbsent(suffix.getPriority(), suffix.getSuffix());
this.suffixStack.accumulateToAll(n);
- }
+ });
}
public void accumulateMeta(String key, String value) {
@@ -103,8 +103,8 @@ public class MetaAccumulator {
// (it's not going to accumulate more nodes)
// Therefore, it should be ok to set the weight meta key, if not already present.
public ListMultimap getMeta() {
- if (!this.meta.containsKey(NodeFactory.WEIGHT_KEY) && this.weight != 0) {
- this.meta.put(NodeFactory.WEIGHT_KEY, String.valueOf(this.weight));
+ if (!this.meta.containsKey(NodeTypes.WEIGHT_KEY) && this.weight != 0) {
+ this.meta.put(NodeTypes.WEIGHT_KEY, String.valueOf(this.weight));
}
return this.meta;
diff --git a/common/src/main/java/me/lucko/luckperms/common/calculators/PermissionCalculatorMetadata.java b/common/src/main/java/me/lucko/luckperms/common/calculators/PermissionCalculatorMetadata.java
index 51b0a2f1..6d7fdb4c 100644
--- a/common/src/main/java/me/lucko/luckperms/common/calculators/PermissionCalculatorMetadata.java
+++ b/common/src/main/java/me/lucko/luckperms/common/calculators/PermissionCalculatorMetadata.java
@@ -26,7 +26,7 @@
package me.lucko.luckperms.common.calculators;
import me.lucko.luckperms.api.context.ContextSet;
-import me.lucko.luckperms.common.references.HolderType;
+import me.lucko.luckperms.common.model.HolderType;
/**
* Metadata about a given {@link PermissionCalculator}.
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaAddChatMeta.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaAddChatMeta.java
index 34598542..6b33152d 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaAddChatMeta.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaAddChatMeta.java
@@ -42,7 +42,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaAddTempChatMeta.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaAddTempChatMeta.java
index 681c0943..3391da00 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaAddTempChatMeta.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaAddTempChatMeta.java
@@ -45,7 +45,7 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.TemporaryModifier;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.DurationFormatter;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaClear.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaClear.java
index 41546c2a..80834ef0 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaClear.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaClear.java
@@ -39,8 +39,8 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.MetaType;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.model.NodeTypes;
+import me.lucko.luckperms.common.node.utils.MetaType;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
@@ -68,13 +68,13 @@ public class MetaClear extends SharedSubCommand {
if (typeId.equals("chat") || typeId.equals("chatmeta")) {
type = MetaType.CHAT;
}
- if (typeId.equals(NodeFactory.META_KEY)) {
+ if (typeId.equals(NodeTypes.META_KEY)) {
type = MetaType.META;
}
- if (typeId.equals(NodeFactory.PREFIX_KEY) || typeId.equals("prefixes")) {
+ if (typeId.equals(NodeTypes.PREFIX_KEY) || typeId.equals("prefixes")) {
type = MetaType.PREFIX;
}
- if (typeId.equals(NodeFactory.SUFFIX_KEY) || typeId.equals("suffixes")) {
+ if (typeId.equals(NodeTypes.SUFFIX_KEY) || typeId.equals("suffixes")) {
type = MetaType.SUFFIX;
}
@@ -87,7 +87,7 @@ public class MetaClear extends SharedSubCommand {
type = MetaType.ANY;
}
- int before = holder.getEnduringNodes().size();
+ int before = holder.enduringData().immutable().size();
MutableContextSet context = ArgumentParser.parseContext(0, args, plugin);
@@ -102,7 +102,7 @@ public class MetaClear extends SharedSubCommand {
holder.clearMeta(type, context);
}
- int changed = before - holder.getEnduringNodes().size();
+ int changed = before - holder.enduringData().immutable().size();
if (changed == 1) {
Message.META_CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), type.name().toLowerCase(), MessageUtils.contextSetToString(context), changed);
} else {
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaInfo.java
index c6a31ebd..4b299acb 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaInfo.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaInfo.java
@@ -40,8 +40,8 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
-import me.lucko.luckperms.common.node.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaRemoveChatMeta.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaRemoveChatMeta.java
index 2542867a..a7f75926 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaRemoveChatMeta.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaRemoveChatMeta.java
@@ -42,7 +42,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaRemoveTempChatMeta.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaRemoveTempChatMeta.java
index 2a30b201..79cf8a73 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaRemoveTempChatMeta.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaRemoveTempChatMeta.java
@@ -42,7 +42,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaSet.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaSet.java
index 73abc0db..dcad6c3e 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaSet.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaSet.java
@@ -26,6 +26,7 @@
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.StandardNodeEquality;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.command.CommandResult;
@@ -39,8 +40,9 @@ import me.lucko.luckperms.common.command.utils.StorageAssistant;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
+import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
@@ -79,7 +81,7 @@ public class MetaSet extends SharedSubCommand {
Node n = NodeFactory.buildMetaNode(key, value).withExtraContext(context).build();
- if (holder.hasPermission(n).asBoolean()) {
+ if (holder.hasPermission(NodeMapType.ENDURING, n, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE).asBoolean()) {
Message.ALREADY_HAS_META.send(sender, holder.getFriendlyName(), key, value, MessageUtils.contextSetToString(context));
return CommandResult.STATE_ERROR;
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaSetTemp.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaSetTemp.java
index 47a6e2fb..30726b7a 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaSetTemp.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/meta/MetaSetTemp.java
@@ -26,6 +26,7 @@
package me.lucko.luckperms.common.commands.generic.meta;
import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.StandardNodeEquality;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.command.CommandManager;
@@ -41,9 +42,10 @@ import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
+import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.TemporaryModifier;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.DurationFormatter;
@@ -85,7 +87,7 @@ public class MetaSetTemp extends SharedSubCommand {
Node n = NodeFactory.buildMetaNode(key, value).withExtraContext(context).setExpiry(duration).build();
- if (holder.hasPermission(n).asBoolean()) {
+ if (holder.hasPermission(NodeMapType.ENDURING, n, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE).asBoolean()) {
Message.ALREADY_HAS_TEMP_META.send(sender, holder.getFriendlyName(), key, value, MessageUtils.contextSetToString(context));
return CommandResult.STATE_ERROR;
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/other/HolderClear.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/other/HolderClear.java
index 10c790e1..88a221a2 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/other/HolderClear.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/other/HolderClear.java
@@ -57,7 +57,7 @@ public class HolderClear extends SubCommand {
return CommandResult.NO_PERMISSION;
}
- int before = holder.getEnduringNodes().size();
+ int before = holder.enduringData().immutable().size();
MutableContextSet context = ArgumentParser.parseContext(0, args, plugin);
@@ -72,7 +72,7 @@ public class HolderClear extends SubCommand {
holder.clearNodes(context);
}
- int changed = before - holder.getEnduringNodes().size();
+ int changed = before - holder.enduringData().immutable().size();
if (changed == 1) {
Message.CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), MessageUtils.contextSetToString(context), changed);
} else {
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/other/HolderShowTracks.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/other/HolderShowTracks.java
index 218bcbd3..0e8f2994 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/other/HolderShowTracks.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/other/HolderShowTracks.java
@@ -73,9 +73,9 @@ public class HolderShowTracks extends SubCommand
if (holder.getType().isUser()) {
// if the holder is a user, we want to query parent groups for tracks
- Set nodes = holder.getEnduringNodes().values().stream()
+ Set nodes = holder.enduringData().immutable().values().stream()
.filter(Node::isGroupNode)
- .filter(Node::getValuePrimitive)
+ .filter(Node::getValue)
.filter(Node::isPermanent)
.collect(Collectors.toSet());
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentAdd.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentAdd.java
index 2ad96fea..ea04ff4b 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentAdd.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentAdd.java
@@ -41,7 +41,7 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentAddTemp.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentAddTemp.java
index fce90431..b40ba333 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentAddTemp.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentAddTemp.java
@@ -44,7 +44,7 @@ import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.TemporaryModifier;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.DurationFormatter;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentClear.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentClear.java
index 6763c6a5..f5ff4c8a 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentClear.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentClear.java
@@ -57,7 +57,7 @@ public class ParentClear extends SharedSubCommand {
return CommandResult.NO_PERMISSION;
}
- int before = holder.getEnduringNodes().size();
+ int before = holder.enduringData().immutable().size();
MutableContextSet context = ArgumentParser.parseContext(0, args, plugin);
@@ -72,7 +72,7 @@ public class ParentClear extends SharedSubCommand {
holder.clearParents(context, true);
}
- int changed = before - holder.getEnduringNodes().size();
+ int changed = before - holder.enduringData().immutable().size();
if (changed == 1) {
Message.PARENT_CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), MessageUtils.contextSetToString(context), changed);
} else {
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentClearTrack.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentClearTrack.java
index 571c2d86..bead6a41 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentClearTrack.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentClearTrack.java
@@ -78,7 +78,7 @@ public class ParentClearTrack extends SharedSubCommand {
return CommandResult.STATE_ERROR;
}
- int before = holder.getEnduringNodes().size();
+ int before = holder.enduringData().immutable().size();
MutableContextSet context = ArgumentParser.parseContext(1, args, plugin);
@@ -102,7 +102,7 @@ public class ParentClearTrack extends SharedSubCommand {
plugin.getUserManager().giveDefaultIfNeeded(((User) holder), false);
}
- int changed = before - holder.getEnduringNodes().size();
+ int changed = before - holder.enduringData().immutable().size();
if (changed == 1) {
Message.PARENT_CLEAR_TRACK_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), track.getName(), MessageUtils.contextSetToString(context), changed);
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentInfo.java
index 32c46481..11cf6bef 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentInfo.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentInfo.java
@@ -40,8 +40,8 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
-import me.lucko.luckperms.common.node.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.CollationKeyCache;
@@ -77,10 +77,10 @@ public class ParentInfo extends SharedSubCommand {
SortMode sortMode = SortMode.determine(args);
// get the holders nodes
- List nodes = new ArrayList<>(holder.getEnduringData().asSortedSet());
+ List nodes = new ArrayList<>(holder.enduringData().asSortedSet());
// remove irrelevant types (these are displayed in the other info commands)
- nodes.removeIf(node -> !node.isGroupNode() || !node.getValuePrimitive());
+ nodes.removeIf(node -> !node.isGroupNode() || !node.getValue());
// handle empty
if (nodes.isEmpty()) {
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentRemove.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentRemove.java
index 8d024b02..6ffa40a3 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentRemove.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentRemove.java
@@ -42,7 +42,7 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentRemoveTemp.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentRemoveTemp.java
index 27fbe8e1..978ff1b4 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentRemoveTemp.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentRemoveTemp.java
@@ -40,7 +40,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentSet.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentSet.java
index 677f0392..8b24c7a4 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentSet.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentSet.java
@@ -41,7 +41,7 @@ import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentSetTrack.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentSetTrack.java
index 5fc605e4..e5422f24 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentSetTrack.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/ParentSetTrack.java
@@ -41,7 +41,7 @@ import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.Track;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.storage.DataConstraints;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/UserSwitchPrimaryGroup.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/UserSwitchPrimaryGroup.java
index 5ee8b6ba..0b4854a1 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/UserSwitchPrimaryGroup.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/parent/UserSwitchPrimaryGroup.java
@@ -38,7 +38,7 @@ import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheck.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheck.java
index e6c1d994..22e5ad07 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheck.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheck.java
@@ -38,8 +38,9 @@ import me.lucko.luckperms.common.command.utils.MessageUtils;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
+import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
@@ -63,7 +64,7 @@ public class PermissionCheck extends SharedSubCommand {
String node = ArgumentParser.parseString(0, args);
MutableContextSet context = ArgumentParser.parseContext(1, args, plugin);
- Tristate result = holder.hasPermission(NodeFactory.builder(node).withExtraContext(context).build(), StandardNodeEquality.IGNORE_VALUE_OR_IF_TEMPORARY);
+ Tristate result = holder.hasPermission(NodeMapType.ENDURING, NodeFactory.builder(node).withExtraContext(context).build(), StandardNodeEquality.IGNORE_VALUE_OR_IF_TEMPORARY);
String s = MessageUtils.formatTristate(result);
Message.CHECK_PERMISSION.send(sender, holder.getFriendlyName(), node, s, MessageUtils.contextSetToString(context));
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheckInherits.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheckInherits.java
index f557b93c..0119d3ad 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheckInherits.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionCheckInherits.java
@@ -38,8 +38,8 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.InheritanceInfo;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
+import me.lucko.luckperms.common.node.utils.InheritanceInfo;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionClear.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionClear.java
index 6d9c46c3..32d814cf 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionClear.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionClear.java
@@ -57,7 +57,7 @@ public class PermissionClear extends SharedSubCommand {
return CommandResult.NO_PERMISSION;
}
- int before = holder.getEnduringNodes().size();
+ int before = holder.enduringData().immutable().size();
MutableContextSet context = ArgumentParser.parseContext(0, args, plugin);
@@ -72,7 +72,7 @@ public class PermissionClear extends SharedSubCommand {
holder.clearPermissions(context);
}
- int changed = before - holder.getEnduringNodes().size();
+ int changed = before - holder.enduringData().immutable().size();
if (changed == 1) {
Message.PERMISSION_CLEAR_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), MessageUtils.contextSetToString(context), changed);
} else {
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionInfo.java
index 1b56f965..e9410f6f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionInfo.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionInfo.java
@@ -40,8 +40,8 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
-import me.lucko.luckperms.common.node.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.CollationKeyCache;
@@ -77,14 +77,12 @@ public class PermissionInfo extends SharedSubCommand {
SortMode sortMode = SortMode.determine(args);
// get the holders nodes
- List nodes = new ArrayList<>(holder.getEnduringData().asSortedSet());
+ List nodes = new ArrayList<>(holder.enduringData().asSortedSet());
// remove irrelevant types (these are displayed in the other info commands)
- nodes.removeIf(node ->
- // remove if the node is a group node, and if the value isn't false and if the group actually exists
- (node.isGroupNode() && node.getValuePrimitive() && plugin.getGroupManager().isLoaded(node.getGroupName())) ||
- // remove if the node is a meta node
- node.isPrefix() || node.isSuffix() || node.isMeta()
+ nodes.removeIf(node -> (node.isGroupNode() && node.getValue() && plugin.getGroupManager().isLoaded(node.getGroupName())) ||
+ // remove if the node is a meta node
+ node.isPrefix() || node.isSuffix() || node.isMeta()
);
// handle empty
@@ -118,7 +116,7 @@ public class PermissionInfo extends SharedSubCommand {
// send content
for (LocalizedNode node : content) {
- String s = "&3> " + (node.getValuePrimitive() ? "&a" : "&c") + node.getPermission() + (sender.isConsole() ? " &7(" + node.getValuePrimitive() + "&7)" : "") + MessageUtils.getAppendableNodeContextString(node);
+ String s = "&3> " + (node.getValue() ? "&a" : "&c") + node.getPermission() + (sender.isConsole() ? " &7(" + node.getValue() + "&7)" : "") + MessageUtils.getAppendableNodeContextString(node);
if (node.isTemporary()) {
s += "\n&2- expires in " + DurationFormatter.LONG.formatDateDiff(node.getExpiryUnixTime());
}
@@ -142,7 +140,7 @@ public class PermissionInfo extends SharedSubCommand {
private static Consumer> makeFancy(PermissionHolder holder, String label, Node node) {
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextUtils.fromLegacy(TextUtils.joinNewline(
- "Â¥3> " + (node.getValuePrimitive() ? "Â¥a" : "Â¥c") + node.getPermission(),
+ "Â¥3> " + (node.getValue() ? "Â¥a" : "Â¥c") + node.getPermission(),
" ",
"Â¥7Click to remove this node from " + holder.getFriendlyName()
), 'Â¥'));
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSet.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSet.java
index 389935b9..9b1bd193 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSet.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSet.java
@@ -40,7 +40,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSetTemp.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSetTemp.java
index ae90e31e..a9f56202 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSetTemp.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionSetTemp.java
@@ -43,7 +43,7 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.TemporaryModifier;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.DurationFormatter;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnset.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnset.java
index c8eb0e4f..1c0a52d8 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnset.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnset.java
@@ -40,7 +40,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnsetTemp.java b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnsetTemp.java
index c6cbae1e..958b0762 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnsetTemp.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/generic/permission/PermissionUnsetTemp.java
@@ -40,7 +40,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/DeleteGroup.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/DeleteGroup.java
index 204e6583..f57de2f1 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/group/DeleteGroup.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/DeleteGroup.java
@@ -36,7 +36,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupClone.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupClone.java
index 68253ee6..d2922bc9 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupClone.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupClone.java
@@ -36,6 +36,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
+import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.storage.DataConstraints;
@@ -72,7 +73,7 @@ public class GroupClone extends SubCommand {
return CommandResult.NO_PERMISSION;
}
- newGroup.replaceEnduringNodes(group.getEnduringNodes());
+ newGroup.replaceNodes(NodeMapType.ENDURING, group.enduringData().immutable());
Message.CLONE_SUCCESS.send(sender, group.getName(), newGroup.getName());
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupInfo.java
index f5b1d7eb..37e7b2fb 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupInfo.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupInfo.java
@@ -62,12 +62,12 @@ public class GroupInfo extends SubCommand {
group.getWeight().isPresent() ? group.getWeight().getAsInt() : "None"
);
- Set parents = group.getEnduringData().asSet().stream()
+ Set parents = group.enduringData().asSet().stream()
.filter(Node::isGroupNode)
.filter(Node::isPermanent)
.collect(Collectors.toSet());
- Set tempParents = group.getEnduringData().asSet().stream()
+ Set tempParents = group.enduringData().asSet().stream()
.filter(Node::isGroupNode)
.filter(Node::isTemporary)
.collect(Collectors.toSet());
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupListMembers.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupListMembers.java
index 742058e2..1ed46623 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupListMembers.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupListMembers.java
@@ -42,10 +42,10 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
-import me.lucko.luckperms.common.node.HeldPermissionComparator;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.model.HolderType;
+import me.lucko.luckperms.common.node.comparator.HeldPermissionComparator;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.HolderType;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.DurationFormatter;
import me.lucko.luckperms.common.utils.Iterators;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupRename.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupRename.java
index c897671a..67512371 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupRename.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupRename.java
@@ -36,6 +36,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
+import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.storage.DataConstraints;
@@ -78,7 +79,7 @@ public class GroupRename extends SubCommand {
return CommandResult.FAILURE;
}
- newGroup.replaceEnduringNodes(group.getEnduringNodes());
+ newGroup.replaceNodes(NodeMapType.ENDURING, group.enduringData().immutable());
Message.RENAME_SUCCESS.send(sender, group.getName(), newGroup.getName());
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetDisplayName.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetDisplayName.java
index 2671b2e8..04f42fd1 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetDisplayName.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetDisplayName.java
@@ -36,7 +36,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetWeight.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetWeight.java
index 3bad02c4..5203bac3 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetWeight.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetWeight.java
@@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.group;
+import me.lucko.luckperms.api.nodetype.types.WeightType;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.command.CommandResult;
import me.lucko.luckperms.common.command.abstraction.CommandException;
@@ -37,7 +38,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.Group;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
@@ -58,7 +59,7 @@ public class GroupSetWeight extends SubCommand {
int weight = ArgumentParser.parsePriority(0, args);
- group.removeIf(n -> NodeFactory.parseWeightNode(n.getPermission()) != null);
+ group.removeIf(n -> n.getTypeData(WeightType.KEY).isPresent());
group.setPermission(NodeFactory.buildWeightNode(weight).build());
Message.GROUP_SET_WEIGHT.send(sender, weight, group.getFriendlyName());
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/log/LogNotify.java b/common/src/main/java/me/lucko/luckperms/common/commands/log/LogNotify.java
index c81a0a6c..15e2f794 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/log/LogNotify.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/log/LogNotify.java
@@ -34,7 +34,7 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.Predicates;
@@ -60,7 +60,7 @@ public class LogNotify extends SubCommand {
// if they don't have the perm, they're not ignoring
// if set to false, ignore it, return false
- return ret.map(Node::getValuePrimitive).orElse(false);
+ return ret.map(Node::getValue).orElse(false);
}
private static void setIgnoring(LuckPermsPlugin plugin, UUID uuid, boolean state) {
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/migration/MigrationUtils.java b/common/src/main/java/me/lucko/luckperms/common/commands/migration/MigrationUtils.java
index 7b1f90a5..75f3368f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/migration/MigrationUtils.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/migration/MigrationUtils.java
@@ -26,8 +26,9 @@
package me.lucko.luckperms.common.commands.migration;
import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.nodetype.types.WeightType;
import me.lucko.luckperms.common.model.Group;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
public final class MigrationUtils {
@@ -52,7 +53,7 @@ public final class MigrationUtils {
}
public static void setGroupWeight(Group group, int weight) {
- group.removeIf(n -> NodeFactory.parseWeightNode(n.getPermission()) != null);
+ group.removeIf(n -> n.getTypeData(WeightType.KEY).isPresent());
group.setPermission(NodeFactory.buildWeightNode(weight).build());
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/misc/ApplyEditsCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/misc/ApplyEditsCommand.java
index b048e4b1..575f8c8e 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/misc/ApplyEditsCommand.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/misc/ApplyEditsCommand.java
@@ -41,8 +41,9 @@ import me.lucko.luckperms.common.command.utils.StorageAssistant;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
+import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.model.PermissionHolder;
-import me.lucko.luckperms.common.node.NodeModel;
+import me.lucko.luckperms.common.node.model.NodeDataContainer;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.DurationFormatter;
@@ -105,10 +106,10 @@ public class ApplyEditsCommand extends SingleCommand {
return false;
}
- Set nodes = WebEditor.deserializePermissions(data.getAsJsonArray("nodes"));
+ Set nodes = WebEditor.deserializePermissions(data.getAsJsonArray("nodes"));
- Set before = new HashSet<>(holder.getEnduringNodes().values());
- Set after = nodes.stream().map(NodeModel::toNode).collect(Collectors.toSet());
+ Set before = new HashSet<>(holder.enduringData().immutable().values());
+ Set after = nodes.stream().map(NodeDataContainer::toNode).collect(Collectors.toSet());
Map.Entry, Set> diff = diff(before, after);
Set diffAdded = diff.getKey();
@@ -121,16 +122,16 @@ public class ApplyEditsCommand extends SingleCommand {
return false;
}
- holder.setEnduringNodes(after);
+ holder.setNodes(NodeMapType.ENDURING, after);
for (Node n : diffAdded) {
ExtendedLogEntry.build().actor(sender).acted(holder)
- .action("webeditor", "add", n.getPermission(), n.getValuePrimitive(), n.getFullContexts())
+ .action("webeditor", "add", n.getPermission(), n.getValue(), n.getFullContexts())
.build().submit(plugin, sender);
}
for (Node n : diffRemoved) {
ExtendedLogEntry.build().actor(sender).acted(holder)
- .action("webeditor", "remove", n.getPermission(), n.getValuePrimitive(), n.getFullContexts())
+ .action("webeditor", "remove", n.getPermission(), n.getValue(), n.getFullContexts())
.build().submit(plugin, sender);
}
@@ -150,7 +151,7 @@ public class ApplyEditsCommand extends SingleCommand {
}
private static String formatNode(Node n) {
- return n.getPermission() + " &7(" + (n.getValuePrimitive() ? "&a" : "&c") + n.getValuePrimitive() + "&7)" + MessageUtils.getAppendableNodeContextString(n) +
+ return n.getPermission() + " &7(" + (n.getValue() ? "&a" : "&c") + n.getValue() + "&7)" + MessageUtils.getAppendableNodeContextString(n) +
(n.isTemporary() ? " &7(" + DurationFormatter.CONCISE.formatDateDiff(n.getExpiryUnixTime()) + ")" : "");
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/misc/SearchCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/misc/SearchCommand.java
index 0869519c..4002946f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/misc/SearchCommand.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/misc/SearchCommand.java
@@ -41,11 +41,10 @@ import me.lucko.luckperms.common.command.utils.TabCompletions;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
-import me.lucko.luckperms.common.node.HeldPermissionComparator;
-import me.lucko.luckperms.common.node.NodeFactory;
-import me.lucko.luckperms.common.node.NodeHeldPermission;
+import me.lucko.luckperms.common.model.HolderType;
+import me.lucko.luckperms.common.node.comparator.HeldPermissionComparator;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.HolderType;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.utils.DurationFormatter;
import me.lucko.luckperms.common.utils.Iterators;
@@ -147,7 +146,7 @@ public class SearchCommand extends SingleCommand {
private static Consumer> makeFancy(String holderName, HolderType holderType, String label, HeldPermission> perm) {
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextUtils.fromLegacy(TextUtils.joinNewline(
- "&3> " + (perm.asNode().getValuePrimitive() ? "&a" : "&c") + perm.asNode().getPermission(),
+ "&3> " + (perm.asNode().getValue() ? "&a" : "&c") + perm.asNode().getPermission(),
" ",
"&7Click to remove this node from " + holderName
), CommandManager.AMPERSAND_CHAR));
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserClone.java b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserClone.java
index 53b947b8..e9f421c4 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserClone.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserClone.java
@@ -35,6 +35,7 @@ import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
+import me.lucko.luckperms.common.model.NodeMapType;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
@@ -99,7 +100,7 @@ public class UserClone extends SubCommand {
return CommandResult.NO_PERMISSION;
}
- otherUser.replaceEnduringNodes(user.getEnduringNodes());
+ otherUser.replaceNodes(NodeMapType.ENDURING, user.enduringData().immutable());
Message.CLONE_SUCCESS.send(sender, user.getFriendlyName(), otherUser.getFriendlyName());
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java
index a1db7835..ff18522d 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserInfo.java
@@ -72,12 +72,12 @@ public class UserInfo extends SubCommand {
user.getPrimaryGroup().getValue()
);
- Set parents = user.getEnduringData().asSet().stream()
+ Set parents = user.enduringData().asSet().stream()
.filter(Node::isGroupNode)
.filter(Node::isPermanent)
.collect(Collectors.toSet());
- Set tempParents = user.getEnduringData().asSet().stream()
+ Set tempParents = user.enduringData().asSet().stream()
.filter(Node::isGroupNode)
.filter(Node::isTemporary)
.collect(Collectors.toSet());
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserMainCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserMainCommand.java
index 6921d385..e517a205 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/user/UserMainCommand.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/user/UserMainCommand.java
@@ -42,8 +42,8 @@ import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
import me.lucko.luckperms.common.locale.message.Message;
import me.lucko.luckperms.common.model.User;
+import me.lucko.luckperms.common.model.UserIdentifier;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.UserIdentifier;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.storage.DataConstraints;
import me.lucko.luckperms.common.utils.Uuids;
diff --git a/common/src/main/java/me/lucko/luckperms/common/event/EventFactory.java b/common/src/main/java/me/lucko/luckperms/common/event/EventFactory.java
index 539dd95b..7239f548 100644
--- a/common/src/main/java/me/lucko/luckperms/common/event/EventFactory.java
+++ b/common/src/main/java/me/lucko/luckperms/common/event/EventFactory.java
@@ -123,7 +123,7 @@ public final class EventFactory {
}
public void handleGroupDelete(Group group, DeletionCause cause) {
- EventGroupDelete event = new EventGroupDelete(group.getName(), ImmutableSet.copyOf(group.getEnduringNodes().values()), cause);
+ EventGroupDelete event = new EventGroupDelete(group.getName(), ImmutableSet.copyOf(group.enduringData().immutable().values()), cause);
fireEventAsync(event);
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/inheritance/InheritanceComparator.java b/common/src/main/java/me/lucko/luckperms/common/inheritance/InheritanceComparator.java
index 6df485e3..7956bee1 100644
--- a/common/src/main/java/me/lucko/luckperms/common/inheritance/InheritanceComparator.java
+++ b/common/src/main/java/me/lucko/luckperms/common/inheritance/InheritanceComparator.java
@@ -28,7 +28,7 @@ package me.lucko.luckperms.common.inheritance;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import java.util.Comparator;
diff --git a/common/src/main/java/me/lucko/luckperms/common/managers/AbstractManager.java b/common/src/main/java/me/lucko/luckperms/common/managers/AbstractManager.java
index be71a71b..24acef9d 100644
--- a/common/src/main/java/me/lucko/luckperms/common/managers/AbstractManager.java
+++ b/common/src/main/java/me/lucko/luckperms/common/managers/AbstractManager.java
@@ -30,7 +30,7 @@ import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
-import me.lucko.luckperms.common.references.Identifiable;
+import me.lucko.luckperms.common.model.Identifiable;
import java.util.Map;
diff --git a/common/src/main/java/me/lucko/luckperms/common/managers/Manager.java b/common/src/main/java/me/lucko/luckperms/common/managers/Manager.java
index 0a222286..eb6d227b 100644
--- a/common/src/main/java/me/lucko/luckperms/common/managers/Manager.java
+++ b/common/src/main/java/me/lucko/luckperms/common/managers/Manager.java
@@ -25,7 +25,7 @@
package me.lucko.luckperms.common.managers;
-import me.lucko.luckperms.common.references.Identifiable;
+import me.lucko.luckperms.common.model.Identifiable;
import java.util.Map;
import java.util.function.Function;
diff --git a/common/src/main/java/me/lucko/luckperms/common/managers/user/AbstractUserManager.java b/common/src/main/java/me/lucko/luckperms/common/managers/user/AbstractUserManager.java
index 71c08aef..fe16c3c1 100644
--- a/common/src/main/java/me/lucko/luckperms/common/managers/user/AbstractUserManager.java
+++ b/common/src/main/java/me/lucko/luckperms/common/managers/user/AbstractUserManager.java
@@ -30,9 +30,9 @@ import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.managers.AbstractManager;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.model.UserIdentifier;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.UserIdentifier;
import java.util.Optional;
import java.util.UUID;
@@ -83,7 +83,7 @@ public abstract class AbstractUserManager extends AbstractManage
String pg = user.getPrimaryGroup().getValue();
boolean has = false;
- for (Node node : user.getEnduringNodes().get(ImmutableContextSet.empty())) {
+ for (Node node : user.enduringData().immutable().get(ImmutableContextSet.empty())) {
if (node.isGroupNode() && node.getGroupName().equalsIgnoreCase(pg)) {
has = true;
break;
@@ -92,7 +92,7 @@ public abstract class AbstractUserManager extends AbstractManage
// need to find a new primary group for the user.
if (!has) {
- String group = user.getEnduringNodes().get(ImmutableContextSet.empty()).stream()
+ String group = user.enduringData().immutable().get(ImmutableContextSet.empty()).stream()
.filter(Node::isGroupNode)
.findFirst()
.map(Node::getGroupName)
@@ -109,7 +109,7 @@ public abstract class AbstractUserManager extends AbstractManage
// check that all users are member of at least one group
boolean hasGroup = false;
if (user.getPrimaryGroup().getStoredValue().isPresent()) {
- for (Node node : user.getEnduringNodes().values()) {
+ for (Node node : user.enduringData().immutable().values()) {
if (node.hasSpecificContext()) {
continue;
}
@@ -160,11 +160,11 @@ public abstract class AbstractUserManager extends AbstractManage
*/
@Override
public boolean shouldSave(User user) {
- if (user.getEnduringNodes().size() != 1) {
+ if (user.enduringData().immutable().size() != 1) {
return true;
}
- for (Node node : user.getEnduringNodes().values()) {
+ for (Node node : user.enduringData().immutable().values()) {
// There's only one.
if (!node.isGroupNode()) {
return true;
diff --git a/common/src/main/java/me/lucko/luckperms/common/managers/user/StandardUserManager.java b/common/src/main/java/me/lucko/luckperms/common/managers/user/StandardUserManager.java
index 26b4d3b6..fb744fdc 100644
--- a/common/src/main/java/me/lucko/luckperms/common/managers/user/StandardUserManager.java
+++ b/common/src/main/java/me/lucko/luckperms/common/managers/user/StandardUserManager.java
@@ -26,8 +26,8 @@
package me.lucko.luckperms.common.managers.user;
import me.lucko.luckperms.common.model.User;
+import me.lucko.luckperms.common.model.UserIdentifier;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.UserIdentifier;
import java.util.concurrent.TimeUnit;
diff --git a/common/src/main/java/me/lucko/luckperms/common/managers/user/UserHousekeeper.java b/common/src/main/java/me/lucko/luckperms/common/managers/user/UserHousekeeper.java
index 79165bec..222a89f5 100644
--- a/common/src/main/java/me/lucko/luckperms/common/managers/user/UserHousekeeper.java
+++ b/common/src/main/java/me/lucko/luckperms/common/managers/user/UserHousekeeper.java
@@ -25,8 +25,8 @@
package me.lucko.luckperms.common.managers.user;
+import me.lucko.luckperms.common.model.UserIdentifier;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.UserIdentifier;
import me.lucko.luckperms.common.utils.ExpiringSet;
import java.util.UUID;
diff --git a/common/src/main/java/me/lucko/luckperms/common/managers/user/UserManager.java b/common/src/main/java/me/lucko/luckperms/common/managers/user/UserManager.java
index e0061047..b95e0d5d 100644
--- a/common/src/main/java/me/lucko/luckperms/common/managers/user/UserManager.java
+++ b/common/src/main/java/me/lucko/luckperms/common/managers/user/UserManager.java
@@ -27,7 +27,7 @@ package me.lucko.luckperms.common.managers.user;
import me.lucko.luckperms.common.managers.Manager;
import me.lucko.luckperms.common.model.User;
-import me.lucko.luckperms.common.references.UserIdentifier;
+import me.lucko.luckperms.common.model.UserIdentifier;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
diff --git a/common/src/main/java/me/lucko/luckperms/common/model/Group.java b/common/src/main/java/me/lucko/luckperms/common/model/Group.java
index ad648eae..2718d18c 100644
--- a/common/src/main/java/me/lucko/luckperms/common/model/Group.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/Group.java
@@ -29,30 +29,37 @@ import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.api.delegates.model.ApiGroup;
import me.lucko.luckperms.common.buffers.BufferedRequest;
+import me.lucko.luckperms.common.buffers.Cache;
import me.lucko.luckperms.common.caching.GroupCachedData;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.GroupReference;
-import me.lucko.luckperms.common.references.HolderType;
-import me.lucko.luckperms.common.references.Identifiable;
import java.util.Optional;
+import java.util.OptionalInt;
import java.util.concurrent.CompletableFuture;
public class Group extends PermissionHolder implements Identifiable {
+ private final ApiGroup apiDelegate = new ApiGroup(this);
/**
* The name of the group
*/
private final String name;
- private final ApiGroup apiDelegate = new ApiGroup(this);
+ /**
+ * Caches the holders weight
+ * @see #getWeight()
+ */
+ private final Cache weightCache = new WeightCache(this);
/**
* The groups data cache instance
*/
private final GroupCachedData cachedData;
+ /**
+ * The group's cached data refresh buffer
+ */
private final GroupRefreshBuffer refreshBuffer;
public Group(String name, LuckPermsPlugin plugin) {
@@ -67,6 +74,12 @@ public class Group extends PermissionHolder implements Identifiable {
getStateListeners().add(this.refreshBuffer::request);
}
+ @Override
+ protected void invalidateCache() {
+ this.weightCache.invalidate();
+ super.invalidateCache();
+ }
+
public String getName() {
return this.name;
}
@@ -92,7 +105,7 @@ public class Group extends PermissionHolder implements Identifiable {
public Optional getDisplayName() {
String name = null;
- for (Node n : getEnduringNodes().get(ImmutableContextSet.empty())) {
+ for (Node n : enduringData().immutable().get(ImmutableContextSet.empty())) {
if (!n.getPermission().startsWith("displayname.")) {
continue;
}
@@ -116,8 +129,8 @@ public class Group extends PermissionHolder implements Identifiable {
}
@Override
- public GroupReference toReference() {
- return GroupReference.of(getId());
+ public OptionalInt getWeight() {
+ return this.weightCache.get();
}
@Override
diff --git a/common/src/main/java/me/lucko/luckperms/common/references/HolderType.java b/common/src/main/java/me/lucko/luckperms/common/model/HolderType.java
similarity index 94%
rename from common/src/main/java/me/lucko/luckperms/common/references/HolderType.java
rename to common/src/main/java/me/lucko/luckperms/common/model/HolderType.java
index bccd04b0..4678986a 100644
--- a/common/src/main/java/me/lucko/luckperms/common/references/HolderType.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/HolderType.java
@@ -23,9 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.references;
-
-import me.lucko.luckperms.common.model.PermissionHolder;
+package me.lucko.luckperms.common.model;
public enum HolderType {
diff --git a/common/src/main/java/me/lucko/luckperms/common/references/Identifiable.java b/common/src/main/java/me/lucko/luckperms/common/model/Identifiable.java
similarity index 97%
rename from common/src/main/java/me/lucko/luckperms/common/references/Identifiable.java
rename to common/src/main/java/me/lucko/luckperms/common/model/Identifiable.java
index af4f4d6b..b72dd54c 100644
--- a/common/src/main/java/me/lucko/luckperms/common/references/Identifiable.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/Identifiable.java
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.references;
+package me.lucko.luckperms.common.model;
/**
* Interface to represent an identifiable object
diff --git a/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java b/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java
index f61be7dd..7a23d0d6 100644
--- a/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java
@@ -37,9 +37,9 @@ import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.buffers.Cache;
import me.lucko.luckperms.common.contexts.ContextSetComparator;
-import me.lucko.luckperms.common.node.ImmutableLocalizedNode;
-import me.lucko.luckperms.common.node.NodeComparator;
-import me.lucko.luckperms.common.node.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.comparator.NodeComparator;
+import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.model.ImmutableLocalizedNode;
import java.util.ArrayList;
import java.util.Collection;
@@ -207,7 +207,7 @@ public final class NodeMap {
try {
ImmutableContextSet context = node.getFullContexts().makeImmutable();
this.map.put(context, node);
- if (node.isGroupNode() && node.getValuePrimitive()) {
+ if (node.isGroupNode() && node.getValue()) {
this.inheritanceMap.put(context, node);
}
} finally {
@@ -233,7 +233,7 @@ public final class NodeMap {
try {
ImmutableContextSet context = node.getFullContexts().makeImmutable();
this.map.remove(context, node);
- if (node.isGroupNode() && node.getValuePrimitive()) {
+ if (node.isGroupNode() && node.getValue()) {
this.inheritanceMap.remove(context, node);
}
} finally {
@@ -293,7 +293,7 @@ public final class NodeMap {
this.map.putAll(multimap);
for (Map.Entry entry : this.map.entries()) {
- if (entry.getValue().isGroupNode() && entry.getValue().getValuePrimitive()) {
+ if (entry.getValue().isGroupNode() && entry.getValue().getValue()) {
this.inheritanceMap.put(entry.getKey(), entry.getValue());
}
}
@@ -342,7 +342,7 @@ public final class NodeMap {
if (removed != null) {
removed.add(entry);
}
- if (entry.isGroupNode() && entry.getValuePrimitive()) {
+ if (entry.isGroupNode() && entry.getValue()) {
this.inheritanceMap.remove(entry.getFullContexts().makeImmutable(), entry);
}
work = true;
diff --git a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java
index f5e79f1c..9f83e8fe 100644
--- a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java
@@ -27,7 +27,6 @@ package me.lucko.luckperms.common.model;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
@@ -42,23 +41,19 @@ import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.buffers.BufferedRequest;
-import me.lucko.luckperms.common.buffers.Cache;
import me.lucko.luckperms.common.caching.HolderCachedData;
import me.lucko.luckperms.common.caching.handlers.StateListener;
import me.lucko.luckperms.common.caching.type.MetaAccumulator;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.inheritance.InheritanceComparator;
import me.lucko.luckperms.common.inheritance.InheritanceGraph;
-import me.lucko.luckperms.common.node.ImmutableLocalizedNode;
-import me.lucko.luckperms.common.node.InheritanceInfo;
-import me.lucko.luckperms.common.node.MetaType;
-import me.lucko.luckperms.common.node.NodeFactory;
-import me.lucko.luckperms.common.node.NodeTools;
-import me.lucko.luckperms.common.node.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
+import me.lucko.luckperms.common.node.model.ImmutableLocalizedNode;
+import me.lucko.luckperms.common.node.utils.InheritanceInfo;
+import me.lucko.luckperms.common.node.utils.MetaType;
+import me.lucko.luckperms.common.node.utils.NodeTools;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.GroupReference;
-import me.lucko.luckperms.common.references.HolderReference;
-import me.lucko.luckperms.common.references.HolderType;
import java.util.ArrayList;
import java.util.Comparator;
@@ -76,7 +71,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Predicate;
-import java.util.stream.Collectors;
/**
* Represents an object that can hold permissions, (a user or group)
@@ -124,7 +118,7 @@ public abstract class PermissionHolder {
*
* These (unlike transient nodes) are saved to the storage backing.
*
- * @see #getEnduringData()
+ * @see #enduringData()
*/
private final NodeMap enduringNodes = new NodeMap(this);
@@ -136,16 +130,10 @@ public abstract class PermissionHolder {
* when the server stops, and for a user, it's when they log out, or get
* unloaded.)
*
- * @see #getTransientData()
+ * @see #transientData()
*/
private final NodeMap transientNodes = new NodeMap(this);
- /**
- * Caches the holders weight
- * @see #getWeight()
- */
- private final Cache weightCache = WeightCache.getFor(this);
-
/**
* Lock used by Storage implementations to prevent concurrent read/writes
* @see #getIoLock()
@@ -183,10 +171,9 @@ public abstract class PermissionHolder {
return this.stateListeners;
}
- private void invalidateCache() {
+ protected void invalidateCache() {
this.enduringNodes.invalidate();
this.transientNodes.invalidate();
- this.weightCache.invalidate();
// Invalidate listeners
for (StateListener listener : this.stateListeners) {
@@ -196,17 +183,6 @@ public abstract class PermissionHolder {
e.printStackTrace();
}
}
-
- // Declare new state to the state manager
- declareState();
- }
-
- private void declareState() {
- /* only declare state of groups. the state manager isn't really being used now the caches in this class
- are gone, but it's useful for command output. */
- if (this.getType().isGroup()) {
- this.plugin.getCachedStateManager().putAll(toReference(), getGroupReferences());
- }
}
/**
@@ -223,14 +199,12 @@ public abstract class PermissionHolder {
*/
public abstract HolderCachedData> getCachedData();
- public abstract BufferedRequest getRefreshBuffer();
-
/**
- * Forms a HolderReference for this PermissionHolder.
+ * Gets the holders refresh buffer
*
- * @return this holders reference
+ * @return the holders refresh buffer
*/
- public abstract HolderReference, ?> toReference();
+ public abstract BufferedRequest getRefreshBuffer();
/**
* Returns the type of this PermissionHolder.
@@ -254,43 +228,21 @@ public abstract class PermissionHolder {
}
}
- public NodeMap getEnduringData() {
+ public NodeMap enduringData() {
return this.enduringNodes;
}
- public NodeMap getTransientData() {
+ public NodeMap transientData() {
return this.transientNodes;
}
- public ImmutableSetMultimap getNodes(NodeMapType type) {
- return getData(type).immutable();
- }
-
- public ImmutableSetMultimap getEnduringNodes() {
- return this.enduringNodes.immutable();
- }
-
- public ImmutableSetMultimap getTransientNodes() {
- return this.transientNodes.immutable();
- }
-
- /**
- * Sets this objects nodes to the values in the set
- *
- * @param set the set of nodes to apply to the object
- */
- public void setEnduringNodes(Set set) {
- this.enduringNodes.setContent(set);
+ public void setNodes(NodeMapType type, Set set) {
+ getData(type).setContent(set);
invalidateCache();
}
- /**
- * Replaces the multimap backing this object with another
- *
- * @param multimap the replacement multimap
- */
- public void replaceEnduringNodes(Multimap multimap) {
- this.enduringNodes.setContent(multimap);
+ public void replaceNodes(NodeMapType type, Multimap multimap) {
+ getData(type).setContent(multimap);
invalidateCache();
}
@@ -334,7 +286,7 @@ public abstract class PermissionHolder {
}
public boolean removeIf(Predicate predicate, Runnable taskIfSuccess) {
- ImmutableCollection before = getEnduringNodes().values();
+ ImmutableCollection before = enduringData().immutable().values();
if (!this.enduringNodes.removeIf(predicate)) {
return false;
}
@@ -342,7 +294,7 @@ public abstract class PermissionHolder {
taskIfSuccess.run();
}
invalidateCache();
- ImmutableCollection after = getEnduringNodes().values();
+ ImmutableCollection after = enduringData().immutable().values();
this.plugin.getEventFactory().handleNodeClear(this, before, after);
return true;
@@ -353,7 +305,7 @@ public abstract class PermissionHolder {
}
public boolean removeIf(ContextSet contextSet, Predicate predicate, Runnable taskIfSuccess) {
- ImmutableCollection before = getEnduringNodes().values();
+ ImmutableCollection before = enduringData().immutable().values();
if (!this.enduringNodes.removeIf(contextSet, predicate)) {
return false;
}
@@ -361,7 +313,7 @@ public abstract class PermissionHolder {
taskIfSuccess.run();
}
invalidateCache();
- ImmutableCollection after = getEnduringNodes().values();
+ ImmutableCollection after = enduringData().immutable().values();
this.plugin.getEventFactory().handleNodeClear(this, before, after);
return true;
@@ -375,7 +327,7 @@ public abstract class PermissionHolder {
return result;
}
- private void accumulateInheritancesTo(List accumulator, Contexts context) {
+ public void accumulateInheritancesTo(List accumulator, Contexts context) {
InheritanceGraph graph = this.plugin.getInheritanceHandler().getGraph(context);
Iterable traversal = graph.traverse(this.plugin.getConfiguration().get(ConfigKeys.INHERITANCE_TRAVERSAL_ALGORITHM), this);
for (PermissionHolder holder : traversal) {
@@ -393,27 +345,7 @@ public abstract class PermissionHolder {
return accumulator;
}
- public SortedSet resolveInheritancesAlmostEqual(Contexts contexts) {
- List nodes = new LinkedList<>();
- accumulateInheritancesTo(nodes, contexts);
-
- NodeTools.removeEqual(nodes.iterator(), StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
- SortedSet ret = new TreeSet<>(NodeWithContextComparator.reverse());
- ret.addAll(nodes);
- return ret;
- }
-
- public SortedSet resolveInheritancesMergeTemp(Contexts contexts) {
- List nodes = new LinkedList<>();
- accumulateInheritancesTo(nodes, contexts);
-
- NodeTools.removeEqual(nodes.iterator(), StandardNodeEquality.IGNORE_VALUE_OR_IF_TEMPORARY);
- SortedSet ret = new TreeSet<>(NodeWithContextComparator.reverse());
- ret.addAll(nodes);
- return ret;
- }
-
- private void accumulateInheritancesTo(List accumulator) {
+ public void accumulateInheritancesTo(List accumulator) {
InheritanceGraph graph = this.plugin.getInheritanceHandler().getGraph();
Iterable traversal = graph.traverse(this.plugin.getConfiguration().get(ConfigKeys.INHERITANCE_TRAVERSAL_ALGORITHM), this);
for (PermissionHolder holder : traversal) {
@@ -431,27 +363,7 @@ public abstract class PermissionHolder {
return accumulator;
}
- public SortedSet resolveInheritancesAlmostEqual() {
- List nodes = new LinkedList<>();
- accumulateInheritancesTo(nodes);
-
- NodeTools.removeEqual(nodes.iterator(), StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
- SortedSet ret = new TreeSet<>(NodeWithContextComparator.reverse());
- ret.addAll(nodes);
- return ret;
- }
-
- public SortedSet resolveInheritancesMergeTemp() {
- List nodes = new LinkedList<>();
- accumulateInheritancesTo(nodes);
-
- NodeTools.removeEqual(nodes.iterator(), StandardNodeEquality.IGNORE_VALUE_OR_IF_TEMPORARY);
- SortedSet ret = new TreeSet<>(NodeWithContextComparator.reverse());
- ret.addAll(nodes);
- return ret;
- }
-
- private List getAllEntries(Contexts context) {
+ public List getAllEntries(Contexts context) {
List entries = new LinkedList<>();
if (context.hasSetting(LookupSetting.RESOLVE_INHERITANCE)) {
accumulateInheritancesTo(entries, context);
@@ -472,15 +384,6 @@ public abstract class PermissionHolder {
return entries;
}
- public SortedSet getAllNodes(Contexts context) {
- List entries = getAllEntries(context);
-
- NodeTools.removeSamePermission(entries.iterator());
- SortedSet ret = new TreeSet<>(NodeWithContextComparator.reverse());
- ret.addAll(entries);
- return ret;
- }
-
public Map exportNodesAndShorthand(Contexts context, boolean lowerCase) {
List entries = getAllEntries(context);
@@ -489,12 +392,12 @@ public abstract class PermissionHolder {
for (Node node : entries) {
String perm = lowerCase ? node.getPermission().toLowerCase() : node.getPermission();
- if (perms.putIfAbsent(perm, node.getValuePrimitive()) == null) {
+ if (perms.putIfAbsent(perm, node.getValue()) == null) {
if (applyShorthand) {
List shorthand = node.resolveShorthand();
if (!shorthand.isEmpty()) {
for (String s : shorthand) {
- perms.putIfAbsent(lowerCase ? s.toLowerCase() : s, node.getValuePrimitive());
+ perms.putIfAbsent(lowerCase ? s.toLowerCase() : s, node.getValue());
}
}
}
@@ -512,11 +415,11 @@ public abstract class PermissionHolder {
for (Node node : entries) {
String perm = lowerCase ? node.getPermission().toLowerCase().intern() : node.getPermission();
- if (perms.putIfAbsent(perm, node.getValuePrimitive()) == null && applyShorthand) {
+ if (perms.putIfAbsent(perm, node.getValue()) == null && applyShorthand) {
List shorthand = node.resolveShorthand();
if (!shorthand.isEmpty()) {
for (String s : shorthand) {
- perms.putIfAbsent((lowerCase ? s.toLowerCase() : s).intern(), node.getValuePrimitive());
+ perms.putIfAbsent((lowerCase ? s.toLowerCase() : s).intern(), node.getValue());
}
}
}
@@ -535,7 +438,7 @@ public abstract class PermissionHolder {
for (PermissionHolder holder : traversal) {
List nodes = holder.getOwnNodes(context.getContexts());
for (Node node : nodes) {
- if (!node.getValuePrimitive()) continue;
+ if (!node.getValue()) continue;
if (!node.isMeta() && !node.isPrefix() && !node.isSuffix()) continue;
if (!((context.hasSetting(LookupSetting.INCLUDE_NODES_SET_WITHOUT_SERVER) || node.isServerSpecific()) && (context.hasSetting(LookupSetting.INCLUDE_NODES_SET_WITHOUT_WORLD) || node.isWorldSpecific()))) {
@@ -564,7 +467,7 @@ public abstract class PermissionHolder {
for (PermissionHolder holder : traversal) {
List nodes = holder.getOwnNodes();
for (Node node : nodes) {
- if (!node.getValuePrimitive()) continue;
+ if (!node.getValue()) continue;
if (!node.isMeta() && !node.isPrefix() && !node.isSuffix()) continue;
accumulator.accumulateNode(ImmutableLocalizedNode.of(node, holder.getObjectName()));
@@ -589,7 +492,7 @@ public abstract class PermissionHolder {
// we don't call events for transient nodes
boolean transientWork = this.transientNodes.auditTemporaryNodes(null);
- ImmutableCollection before = getEnduringNodes().values();
+ ImmutableCollection before = enduringData().immutable().values();
Set removed = new HashSet<>();
boolean enduringWork = this.enduringNodes.auditTemporaryNodes(removed);
@@ -598,7 +501,7 @@ public abstract class PermissionHolder {
invalidateCache();
// call event
- ImmutableCollection after = getEnduringNodes().values();
+ ImmutableCollection after = enduringData().immutable().values();
for (Node r : removed) {
this.plugin.getEventFactory().handleNodeRemove(r, this, before, after);
}
@@ -636,18 +539,6 @@ public abstract class PermissionHolder {
return searchForMatch(type, node, equalityPredicate).map(Node::getTristate).orElse(Tristate.UNDEFINED);
}
- public Tristate hasPermission(NodeMapType type, Node node) {
- return hasPermission(type, node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
- }
-
- public Tristate hasPermission(Node node, NodeEqualityPredicate equalityPredicate) {
- return hasPermission(NodeMapType.ENDURING, node, equalityPredicate);
- }
-
- public Tristate hasPermission(Node node) {
- return hasPermission(NodeMapType.ENDURING, node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
- }
-
/**
* Check if the holder inherits a node
*
@@ -676,24 +567,20 @@ public abstract class PermissionHolder {
return searchForInheritedMatch(node, equalityPredicate).getResult();
}
- public Tristate inheritsPermission(Node node) {
- return inheritsPermission(node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE);
- }
-
/**
* Sets a permission node
*
* @param node the node to set
*/
public DataMutateResult setPermission(Node node) {
- if (hasPermission(NodeMapType.ENDURING, node) != Tristate.UNDEFINED) {
+ if (hasPermission(NodeMapType.ENDURING, node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE) != Tristate.UNDEFINED) {
return DataMutateResult.ALREADY_HAS;
}
- ImmutableCollection before = getEnduringNodes().values();
+ ImmutableCollection before = enduringData().immutable().values();
this.enduringNodes.add(node);
invalidateCache();
- ImmutableCollection after = getEnduringNodes().values();
+ ImmutableCollection after = enduringData().immutable().values();
this.plugin.getEventFactory().handleNodeAdd(node, this, before, after);
return DataMutateResult.SUCCESS;
@@ -720,10 +607,10 @@ public abstract class PermissionHolder {
Node newNode = node.toBuilder().setExpiry(previous.getExpiryUnixTime() + node.getSecondsTilExpiry()).build();
// Remove the old node & add the new one.
- ImmutableCollection before = getEnduringNodes().values();
+ ImmutableCollection before = enduringData().immutable().values();
this.enduringNodes.replace(newNode, previous);
invalidateCache();
- ImmutableCollection after = getEnduringNodes().values();
+ ImmutableCollection after = enduringData().immutable().values();
this.plugin.getEventFactory().handleNodeAdd(newNode, this, before, after);
return Maps.immutableEntry(DataMutateResult.SUCCESS, newNode);
@@ -740,10 +627,10 @@ public abstract class PermissionHolder {
// Only replace if the new expiry time is greater than the old one.
if (node.getExpiryUnixTime() > previous.getExpiryUnixTime()) {
- ImmutableCollection before = getEnduringNodes().values();
+ ImmutableCollection before = enduringData().immutable().values();
this.enduringNodes.replace(node, previous);
invalidateCache();
- ImmutableCollection after = getEnduringNodes().values();
+ ImmutableCollection after = enduringData().immutable().values();
this.plugin.getEventFactory().handleNodeAdd(node, this, before, after);
return Maps.immutableEntry(DataMutateResult.SUCCESS, node);
@@ -764,7 +651,7 @@ public abstract class PermissionHolder {
* @param node the node to set
*/
public DataMutateResult setTransientPermission(Node node) {
- if (hasPermission(NodeMapType.TRANSIENT, node) != Tristate.UNDEFINED) {
+ if (hasPermission(NodeMapType.TRANSIENT, node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE) != Tristate.UNDEFINED) {
return DataMutateResult.ALREADY_HAS;
}
@@ -779,14 +666,14 @@ public abstract class PermissionHolder {
* @param node the node to unset
*/
public DataMutateResult unsetPermission(Node node) {
- if (hasPermission(NodeMapType.ENDURING, node) == Tristate.UNDEFINED) {
+ if (hasPermission(NodeMapType.ENDURING, node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE) == Tristate.UNDEFINED) {
return DataMutateResult.LACKS;
}
- ImmutableCollection before = getEnduringNodes().values();
+ ImmutableCollection before = enduringData().immutable().values();
this.enduringNodes.remove(node);
invalidateCache();
- ImmutableCollection after = getEnduringNodes().values();
+ ImmutableCollection after = enduringData().immutable().values();
this.plugin.getEventFactory().handleNodeRemove(node, this, before, after);
return DataMutateResult.SUCCESS;
@@ -798,7 +685,7 @@ public abstract class PermissionHolder {
* @param node the node to unset
*/
public DataMutateResult unsetTransientPermission(Node node) {
- if (hasPermission(NodeMapType.TRANSIENT, node) == Tristate.UNDEFINED) {
+ if (hasPermission(NodeMapType.TRANSIENT, node, StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE) == Tristate.UNDEFINED) {
return DataMutateResult.LACKS;
}
@@ -808,21 +695,21 @@ public abstract class PermissionHolder {
}
public boolean inheritsGroup(Group group) {
- return group.getName().equalsIgnoreCase(this.getObjectName()) || hasPermission(NodeFactory.buildGroupNode(group.getName()).build()).asBoolean();
+ return group.getName().equalsIgnoreCase(this.getObjectName()) || hasPermission(NodeMapType.ENDURING, NodeFactory.buildGroupNode(group.getName()).build(), StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE).asBoolean();
}
public boolean inheritsGroup(Group group, ContextSet contextSet) {
- return group.getName().equalsIgnoreCase(this.getObjectName()) || hasPermission(NodeFactory.buildGroupNode(group.getName()).withExtraContext(contextSet).build()).asBoolean();
+ return group.getName().equalsIgnoreCase(this.getObjectName()) || hasPermission(NodeMapType.ENDURING, NodeFactory.buildGroupNode(group.getName()).withExtraContext(contextSet).build(), StandardNodeEquality.IGNORE_EXPIRY_TIME_AND_VALUE).asBoolean();
}
/**
* Clear all of the holders permission nodes
*/
public boolean clearNodes() {
- ImmutableCollection before = getEnduringNodes().values();
+ ImmutableCollection before = enduringData().immutable().values();
this.enduringNodes.clear();
invalidateCache();
- ImmutableCollection after = getEnduringNodes().values();
+ ImmutableCollection after = enduringData().immutable().values();
if (before.size() == after.size()) {
return false;
@@ -833,10 +720,10 @@ public abstract class PermissionHolder {
}
public boolean clearNodes(ContextSet contextSet) {
- ImmutableCollection before = getEnduringNodes().values();
+ ImmutableCollection before = enduringData().immutable().values();
this.enduringNodes.clear(contextSet);
invalidateCache();
- ImmutableCollection after = getEnduringNodes().values();
+ ImmutableCollection after = enduringData().immutable().values();
if (before.size() == after.size()) {
return false;
@@ -847,11 +734,11 @@ public abstract class PermissionHolder {
}
public boolean clearPermissions() {
- return removeIf(Node::isRegularPermissionNode);
+ return removeIf(node -> !node.hasTypeData());
}
public boolean clearPermissions(ContextSet contextSet) {
- return removeIf(contextSet, Node::isRegularPermissionNode);
+ return removeIf(contextSet, node -> !node.hasTypeData());
}
public boolean clearParents(boolean giveDefault) {
@@ -893,14 +780,6 @@ public abstract class PermissionHolder {
}
public OptionalInt getWeight() {
- return this.weightCache.get();
- }
-
- public Set getGroupReferences() {
- return getOwnGroupNodes().stream()
- .map(Node::getGroupName)
- .map(String::toLowerCase)
- .map(GroupReference::of)
- .collect(Collectors.toSet());
+ return OptionalInt.empty();
}
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/model/Track.java b/common/src/main/java/me/lucko/luckperms/common/model/Track.java
index 3c93ab71..aeb0e1e3 100644
--- a/common/src/main/java/me/lucko/luckperms/common/model/Track.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/Track.java
@@ -35,9 +35,8 @@ import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.api.DemotionResults;
import me.lucko.luckperms.common.api.PromotionResults;
import me.lucko.luckperms.common.api.delegates.model.ApiTrack;
-import me.lucko.luckperms.common.node.NodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
-import me.lucko.luckperms.common.references.Identifiable;
import me.lucko.luckperms.common.sender.Sender;
import java.util.ArrayList;
@@ -277,9 +276,9 @@ public final class Track implements Identifiable {
}
// find all groups that are inherited by the user in the exact contexts given and applicable to this track
- List nodes = user.getEnduringNodes().get(context.makeImmutable()).stream()
+ List nodes = user.enduringData().immutable().get(context.makeImmutable()).stream()
.filter(Node::isGroupNode)
- .filter(Node::getValuePrimitive)
+ .filter(Node::getValue)
.filter(node -> containsGroup(node.getGroupName()))
.distinct()
.collect(Collectors.toList());
@@ -339,9 +338,9 @@ public final class Track implements Identifiable {
}
// find all groups that are inherited by the user in the exact contexts given and applicable to this track
- List nodes = user.getEnduringNodes().get(context.makeImmutable()).stream()
+ List nodes = user.enduringData().immutable().get(context.makeImmutable()).stream()
.filter(Node::isGroupNode)
- .filter(Node::getValuePrimitive)
+ .filter(node -> node.getValue())
.filter(node -> containsGroup(node.getGroupName()))
.distinct()
.collect(Collectors.toList());
diff --git a/common/src/main/java/me/lucko/luckperms/common/model/User.java b/common/src/main/java/me/lucko/luckperms/common/model/User.java
index 114949dd..d99bc1a8 100644
--- a/common/src/main/java/me/lucko/luckperms/common/model/User.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/User.java
@@ -31,10 +31,6 @@ import me.lucko.luckperms.common.caching.UserCachedData;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder;
-import me.lucko.luckperms.common.references.HolderType;
-import me.lucko.luckperms.common.references.Identifiable;
-import me.lucko.luckperms.common.references.UserIdentifier;
-import me.lucko.luckperms.common.references.UserReference;
import java.util.Optional;
import java.util.UUID;
@@ -161,11 +157,6 @@ public class User extends PermissionHolder implements Identifiable {
- private static final Cache NULL = new Cache() {
- @Override
- protected OptionalInt supply() {
- return OptionalInt.empty();
- }
- };
-
- public static Cache getFor(PermissionHolder holder) {
- if (holder.getType().isUser()) {
- return NULL;
- }
-
- return new WeightCache(((Group) holder));
- }
-
private final Group group;
- private WeightCache(Group group) {
+ public WeightCache(Group group) {
this.group = group;
}
@@ -64,14 +50,16 @@ public class WeightCache extends Cache {
boolean seen = false;
int best = 0;
for (Node n : this.group.getOwnNodes(ImmutableContextSet.empty())) {
- Integer weight = NodeFactory.parseWeightNode(n.getPermission());
- if (weight == null) {
+ Optional weight = n.getTypeData(WeightType.KEY);
+ if (!weight.isPresent()) {
continue;
}
- if (!seen || weight > best) {
+ int value = weight.get().getWeight();
+
+ if (!seen || value > best) {
seen = true;
- best = weight;
+ best = value;
}
}
OptionalInt weight = seen ? OptionalInt.of(best) : OptionalInt.empty();
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/HeldPermissionComparator.java b/common/src/main/java/me/lucko/luckperms/common/node/comparator/HeldPermissionComparator.java
similarity index 97%
rename from common/src/main/java/me/lucko/luckperms/common/node/HeldPermissionComparator.java
rename to common/src/main/java/me/lucko/luckperms/common/node/comparator/HeldPermissionComparator.java
index e1496061..409fa249 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/HeldPermissionComparator.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/comparator/HeldPermissionComparator.java
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.comparator;
import me.lucko.luckperms.api.HeldPermission;
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/NodeComparator.java b/common/src/main/java/me/lucko/luckperms/common/node/comparator/NodeComparator.java
similarity index 97%
rename from common/src/main/java/me/lucko/luckperms/common/node/NodeComparator.java
rename to common/src/main/java/me/lucko/luckperms/common/node/comparator/NodeComparator.java
index 6e30faa5..0cc08d0c 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/NodeComparator.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/comparator/NodeComparator.java
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.comparator;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.utils.CollationKeyCache;
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/NodeWithContextComparator.java b/common/src/main/java/me/lucko/luckperms/common/node/comparator/NodeWithContextComparator.java
similarity index 98%
rename from common/src/main/java/me/lucko/luckperms/common/node/NodeWithContextComparator.java
rename to common/src/main/java/me/lucko/luckperms/common/node/comparator/NodeWithContextComparator.java
index c0c45c55..f9120cca 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/NodeWithContextComparator.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/comparator/NodeWithContextComparator.java
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.comparator;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.utils.CollationKeyCache;
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/LegacyNodeFactory.java b/common/src/main/java/me/lucko/luckperms/common/node/factory/LegacyNodeFactory.java
similarity index 94%
rename from common/src/main/java/me/lucko/luckperms/common/node/LegacyNodeFactory.java
rename to common/src/main/java/me/lucko/luckperms/common/node/factory/LegacyNodeFactory.java
index 4bf22b3c..fee267ae 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/LegacyNodeFactory.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/factory/LegacyNodeFactory.java
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.factory;
import com.google.common.base.Splitter;
@@ -40,17 +40,17 @@ public final class LegacyNodeFactory {
/**
* The characters which are delimited when serializing a permission string
*/
- static final String[] PERMISSION_DELIMITERS = new String[]{"/", "-", "$", "(", ")", "=", ","};
+ public static final String[] PERMISSION_DELIMITERS = new String[]{"/", "-", "$", "(", ")", "=", ","};
/**
* The characters which are delimited when serializing a server or world string
*/
- static final String[] SERVER_WORLD_DELIMITERS = new String[]{"/", "-"};
+ public static final String[] SERVER_WORLD_DELIMITERS = new String[]{"/", "-"};
/**
* The characters which are delimited when serializing a context set
*/
- static final String[] CONTEXT_DELIMITERS = new String[]{"=", "(", ")", ","};
+ private static final String[] CONTEXT_DELIMITERS = new String[]{"=", "(", ")", ","};
/**
* The characters which are delimited when serializing meta/prefix/suffix strings
@@ -146,7 +146,7 @@ public final class LegacyNodeFactory {
return escapeDelimiters(s, GENERIC_DELIMITERS);
}
- static String unescapeCharacters(String s) {
+ public static String unescapeCharacters(String s) {
if (s == null) {
throw new NullPointerException();
}
@@ -172,7 +172,7 @@ public final class LegacyNodeFactory {
return s;
}
- static String unescapeDelimiters(String s, String... delimiters) {
+ public static String unescapeDelimiters(String s, String... delimiters) {
if (s == null) {
return null;
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/NodeBuilder.java b/common/src/main/java/me/lucko/luckperms/common/node/factory/NodeBuilder.java
similarity index 95%
rename from common/src/main/java/me/lucko/luckperms/common/node/NodeBuilder.java
rename to common/src/main/java/me/lucko/luckperms/common/node/factory/NodeBuilder.java
index 16027117..095fc20b 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/NodeBuilder.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/factory/NodeBuilder.java
@@ -23,12 +23,13 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.factory;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
+import me.lucko.luckperms.common.node.model.ImmutableNode;
import java.util.Map;
import java.util.Objects;
@@ -39,7 +40,7 @@ import javax.annotation.Nonnull;
/**
* Builds node instances
*/
-class NodeBuilder implements Node.Builder {
+public class NodeBuilder implements Node.Builder {
protected String permission;
private ImmutableContextSet.Builder extraContexts = ImmutableContextSet.builder();
private Boolean value = true;
@@ -48,7 +49,7 @@ class NodeBuilder implements Node.Builder {
private String world = null;
private long expireAt = 0L;
- protected NodeBuilder() {
+ NodeBuilder() {
}
@@ -56,7 +57,7 @@ class NodeBuilder implements Node.Builder {
this.permission = permission;
}
- NodeBuilder(Node other) {
+ public NodeBuilder(Node other) {
this.permission = other.getPermission();
copyFrom(other);
}
@@ -64,7 +65,7 @@ class NodeBuilder implements Node.Builder {
@Override
public Node.Builder copyFrom(@Nonnull Node node) {
Objects.requireNonNull(node, "node");
- this.value = node.getValuePrimitive();
+ this.value = node.getValue();
this.override = node.isOverride();
this.server = node.getServer().orElse(null);
this.world = node.getWorld().orElse(null);
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/NodeFactory.java b/common/src/main/java/me/lucko/luckperms/common/node/factory/NodeFactory.java
similarity index 74%
rename from common/src/main/java/me/lucko/luckperms/common/node/NodeFactory.java
rename to common/src/main/java/me/lucko/luckperms/common/node/factory/NodeFactory.java
index ba148643..005dea32 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/NodeFactory.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/factory/NodeFactory.java
@@ -23,19 +23,15 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
-
-import com.google.common.base.Splitter;
-import com.google.common.collect.Maps;
+package me.lucko.luckperms.common.node.factory;
import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.model.Group;
-import me.lucko.luckperms.common.references.HolderType;
-import me.lucko.luckperms.common.utils.PatternCache;
+import me.lucko.luckperms.common.model.HolderType;
+import me.lucko.luckperms.common.node.model.NodeTypes;
-import java.util.Iterator;
import java.util.Map;
/**
@@ -44,20 +40,6 @@ import java.util.Map;
public final class NodeFactory {
public static final String DEFAULT_GROUP_NAME = "default";
- public static final String PREFIX_KEY = "prefix";
- public static final String SUFFIX_KEY = "suffix";
- public static final String META_KEY = "meta";
- public static final String WEIGHT_KEY = "weight";
-
- private static final String GROUP_NODE_MARKER = "group.";
- private static final String PREFIX_NODE_MARKER = PREFIX_KEY + ".";
- private static final String SUFFIX_NODE_MARKER = SUFFIX_KEY + ".";
- private static final String META_NODE_MARKER = META_KEY + ".";
- private static final String WEIGHT_NODE_MARKER = WEIGHT_KEY + ".";
-
- // used to split prefix/suffix/meta nodes
- private static final Splitter META_SPLITTER = Splitter.on(PatternCache.compileDelimiterPattern(".", "\\")).limit(2);
-
public static Node.Builder builder(String s) {
return new NodeBuilder(s);
}
@@ -91,7 +73,7 @@ public final class NodeFactory {
}
public static String groupNode(String groupName) {
- return GROUP_NODE_MARKER + groupName;
+ return NodeTypes.GROUP_NODE_MARKER + groupName;
}
public static String chatMetaNode(ChatMetaType type, int priority, String value) {
@@ -99,19 +81,19 @@ public final class NodeFactory {
}
public static String prefixNode(int priority, String prefix) {
- return PREFIX_NODE_MARKER + priority + "." + LegacyNodeFactory.escapeCharacters(prefix);
+ return NodeTypes.PREFIX_NODE_MARKER + priority + "." + LegacyNodeFactory.escapeCharacters(prefix);
}
public static String suffixNode(int priority, String suffix) {
- return SUFFIX_NODE_MARKER + priority + "." + LegacyNodeFactory.escapeCharacters(suffix);
+ return NodeTypes.SUFFIX_NODE_MARKER + priority + "." + LegacyNodeFactory.escapeCharacters(suffix);
}
public static String metaNode(String key, String value) {
- return META_NODE_MARKER + LegacyNodeFactory.escapeCharacters(key) + "." + LegacyNodeFactory.escapeCharacters(value);
+ return NodeTypes.META_NODE_MARKER + LegacyNodeFactory.escapeCharacters(key) + "." + LegacyNodeFactory.escapeCharacters(value);
}
public static String weightNode(int weight) {
- return WEIGHT_NODE_MARKER + weight;
+ return NodeTypes.WEIGHT_NODE_MARKER + weight;
}
public static Node make(String node) {
@@ -232,7 +214,7 @@ public final class NodeFactory {
return appendContextToCommand(sb, node).toString();
}
- if (node.getValuePrimitive() && (node.isPrefix() || node.isSuffix())) {
+ if (node.getValue() && (node.isPrefix() || node.isSuffix())) {
ChatMetaType chatMetaType = node.isPrefix() ? ChatMetaType.PREFIX : ChatMetaType.SUFFIX;
sb.append("meta ");
@@ -267,7 +249,7 @@ public final class NodeFactory {
return appendContextToCommand(sb, node).toString();
}
- if (node.getValuePrimitive() && node.isMeta()) {
+ if (node.getValue() && node.isMeta()) {
sb.append("meta ");
if (set) {
@@ -329,7 +311,7 @@ public final class NodeFactory {
sb.append(perm);
}
if (set) {
- sb.append(" ").append(node.getValuePrimitive());
+ sb.append(" ").append(node.getValue());
if (node.isTemporary()) {
sb.append(" ").append(node.getExpiryUnixTime());
@@ -355,73 +337,6 @@ public final class NodeFactory {
return sb;
}
- public static String parseGroupNode(String s) {
- String lower = s.toLowerCase();
- if (!lower.startsWith(GROUP_NODE_MARKER)) {
- return null;
- }
- return lower.substring(GROUP_NODE_MARKER.length()).intern();
- }
-
- public static Map.Entry parseMetaNode(String s) {
- if (!s.toLowerCase().startsWith(META_NODE_MARKER)) {
- return null;
- }
-
- Iterator metaParts = META_SPLITTER.split(s.substring(META_NODE_MARKER.length())).iterator();
-
- if (!metaParts.hasNext()) return null;
- String key = metaParts.next();
-
- if (!metaParts.hasNext()) return null;
- String value = metaParts.next();
-
- return Maps.immutableEntry(LegacyNodeFactory.unescapeCharacters(key).intern(), LegacyNodeFactory.unescapeCharacters(value).intern());
- }
-
- private static Map.Entry parseChatMetaNode(String marker, String s) {
- if (!s.toLowerCase().startsWith(marker)) {
- return null;
- }
-
- Iterator metaParts = META_SPLITTER.split(s.substring(marker.length())).iterator();
-
- if (!metaParts.hasNext()) return null;
- String priority = metaParts.next();
-
- if (!metaParts.hasNext()) return null;
- String value = metaParts.next();
-
- try {
- int p = Integer.parseInt(priority);
- String v = LegacyNodeFactory.unescapeCharacters(value).intern();
- return Maps.immutableEntry(p, v);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
- public static Map.Entry parsePrefixNode(String s) {
- return parseChatMetaNode(PREFIX_NODE_MARKER, s);
- }
-
- public static Map.Entry parseSuffixNode(String s) {
- return parseChatMetaNode(SUFFIX_NODE_MARKER, s);
- }
-
- public static Integer parseWeightNode(String s) {
- String lower = s.toLowerCase();
- if (!lower.startsWith(WEIGHT_NODE_MARKER)) {
- return null;
- }
- String i = lower.substring(WEIGHT_NODE_MARKER.length());
- try {
- return Integer.parseInt(i);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
private NodeFactory() {}
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java b/common/src/main/java/me/lucko/luckperms/common/node/model/ForwardingNode.java
similarity index 91%
rename from common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java
rename to common/src/main/java/me/lucko/luckperms/common/node/model/ForwardingNode.java
index a0dcc59d..a861dce6 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/model/ForwardingNode.java
@@ -23,13 +23,15 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.model;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.NodeEqualityPredicate;
import me.lucko.luckperms.api.StandardNodeEquality;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
import java.util.Date;
import java.util.List;
@@ -58,17 +60,11 @@ public abstract class ForwardingNode implements Node {
return delegate().getPermission();
}
- @Nonnull
@Override
- public Boolean getValue() {
+ public boolean getValue() {
return delegate().getValue();
}
- @Override
- public boolean getValuePrimitive() {
- return delegate().getValuePrimitive();
- }
-
@Nonnull
@Override
public Tristate getTristate() {
@@ -171,11 +167,6 @@ public abstract class ForwardingNode implements Node {
return delegate().getFullContexts();
}
- @Override
- public boolean isRegularPermissionNode() {
- return delegate().isRegularPermissionNode();
- }
-
@Override
public boolean isGroupNode() {
return delegate().isGroupNode();
@@ -197,6 +188,21 @@ public abstract class ForwardingNode implements Node {
return delegate().getWildcardLevel();
}
+ @Override
+ public boolean hasTypeData() {
+ return delegate().hasTypeData();
+ }
+
+ @Override
+ public Optional getTypeData(NodeTypeKey key) {
+ return delegate().getTypeData(key);
+ }
+
+ @Override
+ public T typeData(NodeTypeKey key) throws IllegalStateException {
+ return delegate().typeData(key);
+ }
+
@Override
public boolean isMeta() {
return delegate().isMeta();
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableLocalizedNode.java b/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableLocalizedNode.java
similarity index 98%
rename from common/src/main/java/me/lucko/luckperms/common/node/ImmutableLocalizedNode.java
rename to common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableLocalizedNode.java
index 0e474b8c..1de4bc80 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableLocalizedNode.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableLocalizedNode.java
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.model;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableNode.java b/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableNode.java
similarity index 83%
rename from common/src/main/java/me/lucko/luckperms/common/node/ImmutableNode.java
rename to common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableNode.java
index cc8a1660..e49c2e2f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableNode.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableNode.java
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.model;
import com.google.common.collect.ImmutableList;
@@ -33,75 +33,67 @@ import me.lucko.luckperms.api.StandardNodeEquality;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+import me.lucko.luckperms.common.node.factory.LegacyNodeFactory;
+import me.lucko.luckperms.common.node.factory.NodeBuilder;
+import me.lucko.luckperms.common.node.utils.ShorthandParser;
import me.lucko.luckperms.common.processors.WildcardProcessor;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkState;
/**
* An immutable implementation of {@link Node}.
*/
+@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public final class ImmutableNode implements Node {
/**
* The character which separates each part of a permission node
*/
public static final char NODE_SEPARATOR = '.';
- public static final int NODE_SEPARATOR_CODE = Character.getNumericValue('.');
+
+ /**
+ * The numeric value of {@link #NODE_SEPARATOR}
+ */
+ public static final int NODE_SEPARATOR_CODE = Character.getNumericValue(NODE_SEPARATOR);
+
+ // node attributes
private final String permission;
-
private final boolean value;
-
private boolean override;
- // nullable
+ @Nullable
private final String server;
- // nullable
+ @Nullable
private final String world;
- // 0L for no expiry
- private final long expireAt;
-
+ private final long expireAt; // 0L for no expiry
private final ImmutableContextSet contexts;
-
private final ImmutableContextSet fullContexts;
- /*
- * CACHED STATE
- *
- * These values are based upon the node state above, and are stored here
- * to make node comparison and manipulation faster.
- *
- * This increases the memory footprint of this class by a bit, but it is
- * worth it for the gain in speed.
- *
- * The methods on this class are called v. frequently.
- */
- // storing optionals as a field type is usually a bad idea, however, the
- // #getServer and #getWorld methods are called frequently when comparing nodes.
- // without caching these values, it creates quite a bit of object churn
- @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+
+ // cached state
+
private final Optional optServer;
- @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private final Optional optWorld;
+ // this class is immutable, so we can cache the hashcode calculation
private final int hashCode;
- // all nullable
- private String groupName;
private final int wildcardLevel;
- private Map.Entry meta;
- private Map.Entry prefix;
- private Map.Entry suffix;
-
+ private final Map, NodeType> resolvedTypes;
private final List resolvedShorthand;
/**
@@ -114,8 +106,7 @@ public final class ImmutableNode implements Node {
* @param world the world this node applies on
* @param contexts any additional contexts applying to this node
*/
- @SuppressWarnings("deprecation")
- ImmutableNode(String permission, boolean value, boolean override, long expireAt, String server, String world, ContextSet contexts) {
+ public ImmutableNode(String permission, boolean value, boolean override, long expireAt, String server, String world, ContextSet contexts) {
if (permission == null || permission.isEmpty()) {
throw new IllegalArgumentException("Empty permission");
}
@@ -134,11 +125,8 @@ public final class ImmutableNode implements Node {
this.contexts = contexts == null ? ContextSet.empty() : contexts.makeImmutable();
// define cached state
- this.groupName = NodeFactory.parseGroupNode(this.permission);
this.wildcardLevel = this.permission.endsWith(WildcardProcessor.WILDCARD_SUFFIX) ? this.permission.chars().filter(num -> num == NODE_SEPARATOR_CODE).sum() : -1;
- this.meta = NodeFactory.parseMetaNode(this.permission);
- this.prefix = NodeFactory.parsePrefixNode(this.permission);
- this.suffix = NodeFactory.parseSuffixNode(this.permission);
+ this.resolvedTypes = NodeTypes.parseTypes(this.permission);
this.resolvedShorthand = ImmutableList.copyOf(ShorthandParser.parseShorthand(getPermission()));
this.optServer = Optional.ofNullable(this.server);
this.optWorld = Optional.ofNullable(this.world);
@@ -173,7 +161,7 @@ public final class ImmutableNode implements Node {
}
@Override
- public boolean getValuePrimitive() {
+ public boolean getValue() {
return this.value;
}
@@ -226,6 +214,11 @@ public final class ImmutableNode implements Node {
return this.server != null || this.world != null || !this.contexts.isEmpty();
}
+ @Override
+ public boolean shouldApplyWithContext(@Nonnull ContextSet contextSet) {
+ return getFullContexts().isSatisfiedBy(contextSet);
+ }
+
@Override
public boolean isTemporary() {
return this.expireAt != 0L;
@@ -255,23 +248,6 @@ public final class ImmutableNode implements Node {
return isTemporary() && this.expireAt < System.currentTimeMillis() / 1000L;
}
- @Override
- public boolean isRegularPermissionNode() {
- return !isGroupNode() && !isPrefix() && !isSuffix() && !isMeta();
- }
-
- @Override
- public boolean isGroupNode() {
- return this.groupName != null;
- }
-
- @Nonnull
- @Override
- public String getGroupName() {
- checkState(isGroupNode(), "Node is not a group node");
- return this.groupName;
- }
-
@Override
public boolean isWildcard() {
return this.wildcardLevel != -1;
@@ -284,44 +260,17 @@ public final class ImmutableNode implements Node {
}
@Override
- public boolean isMeta() {
- return this.meta != null;
- }
-
- @Nonnull
- @Override
- public Map.Entry getMeta() {
- checkState(isMeta(), "Node is not a meta node");
- return this.meta;
+ public boolean hasTypeData() {
+ return !this.resolvedTypes.isEmpty();
}
@Override
- public boolean isPrefix() {
- return this.prefix != null;
- }
+ public Optional getTypeData(NodeTypeKey key) {
+ Objects.requireNonNull(key, "key");
- @Nonnull
- @Override
- public Map.Entry getPrefix() {
- checkState(isPrefix(), "Node is not a prefix node");
- return this.prefix;
- }
-
- @Override
- public boolean isSuffix() {
- return this.suffix != null;
- }
-
- @Nonnull
- @Override
- public Map.Entry getSuffix() {
- checkState(isSuffix(), "Node is not a suffix node");
- return this.suffix;
- }
-
- @Override
- public boolean shouldApplyWithContext(@Nonnull ContextSet contextSet) {
- return getFullContexts().isSatisfiedBy(contextSet);
+ //noinspection unchecked
+ T result = (T) this.resolvedTypes.get(key);
+ return Optional.ofNullable(result);
}
@Nonnull
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableTransientNode.java b/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableTransientNode.java
similarity index 98%
rename from common/src/main/java/me/lucko/luckperms/common/node/ImmutableTransientNode.java
rename to common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableTransientNode.java
index 7ecf493b..fc330cd1 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableTransientNode.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/model/ImmutableTransientNode.java
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.model;
import me.lucko.luckperms.api.Node;
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/NodeModel.java b/common/src/main/java/me/lucko/luckperms/common/node/model/NodeDataContainer.java
similarity index 81%
rename from common/src/main/java/me/lucko/luckperms/common/node/NodeModel.java
rename to common/src/main/java/me/lucko/luckperms/common/node/model/NodeDataContainer.java
index 11d09ca4..b84cf03b 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/NodeModel.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/model/NodeDataContainer.java
@@ -23,10 +23,11 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.model;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ImmutableContextSet;
+import me.lucko.luckperms.common.node.factory.NodeFactory;
import java.util.Objects;
@@ -36,12 +37,12 @@ import java.util.Objects;
*
* All values are non-null.
*/
-public final class NodeModel {
+public final class NodeDataContainer {
- public static NodeModel fromNode(Node node) {
- NodeModel model = of(
+ public static NodeDataContainer fromNode(Node node) {
+ NodeDataContainer model = of(
node.getPermission(),
- node.getValuePrimitive(),
+ node.getValue(),
node.getServer().orElse("global"),
node.getWorld().orElse("global"),
node.isTemporary() ? node.getExpiryUnixTime() : 0L,
@@ -51,11 +52,11 @@ public final class NodeModel {
return model;
}
- public static NodeModel of(String permission, boolean value, String server, String world, long expiry, ImmutableContextSet contexts) {
- return new NodeModel(permission, value, server, world, expiry, contexts);
+ public static NodeDataContainer of(String permission, boolean value, String server, String world, long expiry, ImmutableContextSet contexts) {
+ return new NodeDataContainer(permission, value, server, world, expiry, contexts);
}
- public static NodeModel of(String permission) {
+ public static NodeDataContainer of(String permission) {
return of(permission, true, "global", "global", 0L, ImmutableContextSet.empty());
}
@@ -67,7 +68,7 @@ public final class NodeModel {
private final ImmutableContextSet contexts;
private Node node = null;
- private NodeModel(String permission, boolean value, String server, String world, long expiry, ImmutableContextSet contexts) {
+ private NodeDataContainer(String permission, boolean value, String server, String world, long expiry, ImmutableContextSet contexts) {
this.permission = Objects.requireNonNull(permission, "permission");
this.value = value;
this.server = Objects.requireNonNull(server, "server");
@@ -114,35 +115,35 @@ public final class NodeModel {
return this.contexts;
}
- public NodeModel setPermission(String permission) {
+ public NodeDataContainer setPermission(String permission) {
return of(permission, this.value, this.server, this.world, this.expiry, this.contexts);
}
- public NodeModel setValue(boolean value) {
+ public NodeDataContainer setValue(boolean value) {
return of(this.permission, value, this.server, this.world, this.expiry, this.contexts);
}
- public NodeModel setServer(String server) {
+ public NodeDataContainer setServer(String server) {
return of(this.permission, this.value, server, this.world, this.expiry, this.contexts);
}
- public NodeModel setWorld(String world) {
+ public NodeDataContainer setWorld(String world) {
return of(this.permission, this.value, this.server, world, this.expiry, this.contexts);
}
- public NodeModel setExpiry(long expiry) {
+ public NodeDataContainer setExpiry(long expiry) {
return of(this.permission, this.value, this.server, this.world, expiry, this.contexts);
}
- public NodeModel setContexts(ImmutableContextSet contexts) {
+ public NodeDataContainer setContexts(ImmutableContextSet contexts) {
return of(this.permission, this.value, this.server, this.world, this.expiry, contexts);
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
- if (!(o instanceof NodeModel)) return false;
- final NodeModel other = (NodeModel) o;
+ if (!(o instanceof NodeDataContainer)) return false;
+ final NodeDataContainer other = (NodeDataContainer) o;
return this.getPermission().equals(other.getPermission()) &&
this.getValue() == other.getValue() &&
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/NodeHeldPermission.java b/common/src/main/java/me/lucko/luckperms/common/node/model/NodeHeldPermission.java
similarity index 94%
rename from common/src/main/java/me/lucko/luckperms/common/node/NodeHeldPermission.java
rename to common/src/main/java/me/lucko/luckperms/common/node/model/NodeHeldPermission.java
index ff57a888..c9f20aed 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/NodeHeldPermission.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/model/NodeHeldPermission.java
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
-package me.lucko.luckperms.common.node;
+package me.lucko.luckperms.common.node.model;
import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.Node;
@@ -31,13 +31,12 @@ import me.lucko.luckperms.api.context.ContextSet;
import java.util.Optional;
import java.util.OptionalLong;
-import java.util.UUID;
import javax.annotation.Nonnull;
public final class NodeHeldPermission> implements HeldPermission {
- public static > NodeHeldPermission of(T holder, NodeModel nodeModel) {
- return of(holder, nodeModel.toNode());
+ public static > NodeHeldPermission of(T holder, NodeDataContainer node) {
+ return of(holder, node.toNode());
}
public static > NodeHeldPermission of(T holder, Node node) {
@@ -60,7 +59,7 @@ public final class NodeHeldPermission> implements HeldPe
@Override
public boolean getValue() {
- return this.node.getValuePrimitive();
+ return this.node.getValue();
}
@Nonnull
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/model/NodeTypes.java b/common/src/main/java/me/lucko/luckperms/common/node/model/NodeTypes.java
new file mode 100644
index 00000000..e1a9be50
--- /dev/null
+++ b/common/src/main/java/me/lucko/luckperms/common/node/model/NodeTypes.java
@@ -0,0 +1,319 @@
+/*
+ * This file is part of LuckPerms, licensed under the MIT License.
+ *
+ * Copyright (c) lucko (Luck)
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.lucko.luckperms.common.node.model;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableMap;
+
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+import me.lucko.luckperms.api.nodetype.types.InheritanceType;
+import me.lucko.luckperms.api.nodetype.types.MetaType;
+import me.lucko.luckperms.api.nodetype.types.PrefixType;
+import me.lucko.luckperms.api.nodetype.types.SuffixType;
+import me.lucko.luckperms.api.nodetype.types.WeightType;
+import me.lucko.luckperms.common.node.factory.LegacyNodeFactory;
+import me.lucko.luckperms.common.utils.PatternCache;
+
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+public final class NodeTypes {
+
+ public static final String PREFIX_KEY = "prefix";
+ public static final String SUFFIX_KEY = "suffix";
+ public static final String META_KEY = "meta";
+ public static final String WEIGHT_KEY = "weight";
+
+ public static final String GROUP_NODE_MARKER = "group.";
+ public static final String PREFIX_NODE_MARKER = PREFIX_KEY + ".";
+ public static final String SUFFIX_NODE_MARKER = SUFFIX_KEY + ".";
+ public static final String META_NODE_MARKER = META_KEY + ".";
+ public static final String WEIGHT_NODE_MARKER = WEIGHT_KEY + ".";
+
+ // used to split prefix/suffix/meta nodes
+ private static final Splitter META_SPLITTER = Splitter.on(PatternCache.compileDelimiterPattern(".", "\\")).limit(2);
+
+ public static Map, NodeType> parseTypes(String s) {
+ Map, NodeType> results = new IdentityHashMap<>();
+
+ NodeType type = parseInheritanceType(s);
+ if (type != null) {
+ results.put(InheritanceType.KEY, type);
+ }
+
+ type = parseMetaType(s);
+ if (type != null) {
+ results.put(MetaType.KEY, type);
+ }
+
+ type = parsePrefixType(s);
+ if (type != null) {
+ results.put(PrefixType.KEY, type);
+ }
+
+ type = parseSuffixType(s);
+ if (type != null) {
+ results.put(SuffixType.KEY, type);
+ }
+
+ type = parseWeightType(s);
+ if (type != null) {
+ results.put(WeightType.KEY, type);
+ }
+
+ if (results.isEmpty()) {
+ return ImmutableMap.of();
+ }
+
+ return results;
+ }
+
+ private static InheritanceType parseInheritanceType(String s) {
+ s = s.toLowerCase();
+ if (!s.startsWith(GROUP_NODE_MARKER)) {
+ return null;
+ }
+
+ String groupName = s.substring(GROUP_NODE_MARKER.length()).intern();
+ return new Inheritance(groupName);
+ }
+
+ private static MetaType parseMetaType(String s) {
+ if (!s.toLowerCase().startsWith(META_NODE_MARKER)) {
+ return null;
+ }
+
+ Iterator metaParts = META_SPLITTER.split(s.substring(META_NODE_MARKER.length())).iterator();
+
+ if (!metaParts.hasNext()) return null;
+ String key = metaParts.next();
+
+ if (!metaParts.hasNext()) return null;
+ String value = metaParts.next();
+
+ return new Meta(
+ LegacyNodeFactory.unescapeCharacters(key).intern(),
+ LegacyNodeFactory.unescapeCharacters(value).intern()
+ );
+ }
+
+ private static PrefixType parsePrefixType(String s) {
+ if (!s.toLowerCase().startsWith(PREFIX_NODE_MARKER)) {
+ return null;
+ }
+
+ Iterator metaParts = META_SPLITTER.split(s.substring(PREFIX_NODE_MARKER.length())).iterator();
+
+ if (!metaParts.hasNext()) return null;
+ String priority = metaParts.next();
+
+ if (!metaParts.hasNext()) return null;
+ String value = metaParts.next();
+
+ try {
+ int p = Integer.parseInt(priority);
+ String v = LegacyNodeFactory.unescapeCharacters(value).intern();
+ return new Prefix(p, v);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ private static SuffixType parseSuffixType(String s) {
+ if (!s.toLowerCase().startsWith(SUFFIX_NODE_MARKER)) {
+ return null;
+ }
+
+ Iterator