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 5b52e7e67..87f43e5a7 100644 --- a/api/src/main/java/me/lucko/luckperms/api/Node.java +++ b/api/src/main/java/me/lucko/luckperms/api/Node.java @@ -25,13 +25,17 @@ package me.lucko.luckperms.api; +import com.google.common.base.Preconditions; + import me.lucko.luckperms.api.context.ContextSet; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.stream.Stream; import javax.annotation.Nonnull; @@ -87,7 +91,10 @@ import javax.annotation.concurrent.Immutable; public interface Node { /** - * Gets the permission string + * Gets the permission string this node encapsulates. + * + *
The exact value of this string may vary for nodes which aren't regular + * permission settings.
* * @return the actual permission node */ @@ -95,11 +102,11 @@ public interface Node { String getPermission(); /** - * Gets the value. + * Gets the value of the node. * - *A negated node would return a value of false.
A negated setting would result in a value of false.
A negated node would return a value of false.
A negated setting would result in a value of false.
This is the inverse of the {@link #getValuePrimitive() value}.
* * @return true if the node is negated */ @@ -137,14 +146,15 @@ public interface Node { /** * Gets if this node is set to override explicitly. * - *This value does not persist across saves, and is therefore only useful for transient nodes
+ *This value does not persist across saves, and is therefore only + * useful for transient nodes.
* * @return true if this node is set to override explicitly */ boolean isOverride(); /** - * Gets the server this node applies on, if the node is server specific + * Gets the server this node applies on, if the node is server specific. * * @return an {@link Optional} containing the server, if one is defined */ @@ -152,7 +162,7 @@ public interface Node { OptionalThe list will not contain the exact permission itself.
* * @return a list of full nodes */ @@ -207,14 +219,14 @@ public interface Node { ListWill return a negative value if the node has already expired.
* * @return the number of seconds until this permission will expire * @throws IllegalStateException if the node is not temporary @@ -250,14 +264,14 @@ public interface Node { /** * Gets if the node has expired. * - *This also returns false if the node is not temporary.
+ *This returns false if the node is not temporary.
* * @return true if this node has expired */ boolean hasExpired(); /** - * Gets the extra contexts required for this node to apply + * Gets the extra contexts required for this node to apply. * * @return the extra contexts required for this node to apply * @since 2.13 @@ -266,16 +280,19 @@ public interface Node { ContextSet getContexts(); /** - * The same as {@link #getContexts()}, but also includes values for "server" and "world" keys if present. + * The same as {@link #getContexts()}, but also includes context pairs for + * "server" and "world" keys if present. * * @return the full contexts required for this node to apply * @since 3.1 + * @see Contexts#SERVER_KEY + * @see Contexts#WORLD_KEY */ @Nonnull ContextSet getFullContexts(); /** - * Gets if this is a group node + * Returns if this is a group node. * * @return true if this is a group node */ @@ -291,14 +308,14 @@ public interface Node { String getGroupName() throws IllegalStateException; /** - * Gets if this node is a wildcard node + * Gets if this node is a wildcard permission. * - * @return true if this node is a wildcard node + * @return true if this node is a wildcard permission */ boolean isWildcard(); /** - * Gets the level of this wildcard, higher is more specific + * Gets the level of this wildcard. * * @return the wildcard level * @throws IllegalStateException if this is not a wildcard @@ -306,14 +323,14 @@ public interface Node { int getWildcardLevel() throws IllegalStateException; /** - * Gets if this node is a meta node + * Gets if this node is a meta node. * * @return true if this node is a meta node */ boolean isMeta(); /** - * Gets the meta value from this node + * Gets the meta value from this node. * * @return the meta value * @throws IllegalStateException if this node is not a meta node @@ -322,14 +339,14 @@ public interface Node { Map.EntryNote that this copies all attributes except the + * permission itself.
+ * * @param node the node to copy from * @return the builder * @since 4.2 @@ -488,14 +508,45 @@ public interface Node { Builder setOverride(boolean override); /** - * Sets the nodes expiry as a unix timestamp in seconds. + * Sets the time when the node should expire. * - * @param expireAt the expiry time + *The parameter passed to this method must be the unix timestamp + * (in seconds) when the node should expire.
+ * + * @param expiryUnixTimestamp the expiry timestamp (unix seconds) * @return the builder * @see Node#getExpiryUnixTime() */ @Nonnull - Builder setExpiry(long expireAt); + Builder setExpiry(long expiryUnixTimestamp); + + /** + * Sets the time when the node should expire. + * + *The expiry timestamp is calculated relative to the current + * system time.
+ * + * @param duration how long the node should be added for + * @param unit the unitduration is measured in
+ * @return the builder
+ * @since 4.2
+ */
+ @Nonnull
+ default Builder setExpiry(long duration, TimeUnit unit) {
+ Preconditions.checkArgument(duration > 0, "duration must be positive");
+ long seconds = Objects.requireNonNull(unit, "unit").toSeconds(duration);
+ long timeNow = System.currentTimeMillis() / 1000L;
+ return setExpiry(timeNow + seconds);
+ }
+
+ /**
+ * Marks that the node being built should never expire.
+ *
+ * @return the builder
+ * @since 4.2
+ */
+ @Nonnull
+ Builder clearExpiry();
/**
* Sets the world value for the node.
@@ -565,13 +616,25 @@ public interface Node {
/**
* Appends extra contexts onto the node.
*
- * @param set a contextset
+ * @param contextSet a context set
* @return the builder
* @see ContextSet
* @see Node#getContexts()
*/
@Nonnull
- Builder withExtraContext(@Nonnull ContextSet set);
+ Builder withExtraContext(@Nonnull ContextSet contextSet);
+
+ /**
+ * Sets the extra contexts for the node.
+ *
+ * @param contextSet a context set
+ * @return the builder
+ * @see ContextSet
+ * @see Node#getContexts()
+ * @since 4.2
+ */
+ @Nonnull
+ Builder setExtraContext(@Nonnull ContextSet contextSet);
/**
* Creates a {@link Node} instance from the builder.
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java b/common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java
index 18c58d60b..3255899b9 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java
@@ -26,6 +26,7 @@
package me.lucko.luckperms.common.node;
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;
@@ -117,8 +118,8 @@ public abstract class ForwardingNode implements Node {
}
@Override
- public boolean shouldApplyWithContext(@Nonnull ContextSet context) {
- return delegate().shouldApplyWithContext(context);
+ public boolean shouldApplyWithContext(@Nonnull ContextSet contextSet) {
+ return delegate().shouldApplyWithContext(contextSet);
}
@Nonnull
@@ -229,6 +230,11 @@ public abstract class ForwardingNode implements Node {
return delegate().standardEquals(other, equalityPredicate);
}
+ @Override
+ public boolean equals(Node other, NodeEqualityPredicate equalityPredicate) {
+ return delegate().equals(other, equalityPredicate);
+ }
+
@Override
public Builder toBuilder() {
return delegate().toBuilder();
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableNode.java b/common/src/main/java/me/lucko/luckperms/common/node/ImmutableNode.java
index 60b027dd0..cb4764c82 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableNode.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/ImmutableNode.java
@@ -316,8 +316,8 @@ public final class ImmutableNode implements Node {
}
@Override
- public boolean shouldApplyWithContext(@Nonnull ContextSet context) {
- return getFullContexts().isSatisfiedBy(context, false);
+ public boolean shouldApplyWithContext(@Nonnull ContextSet contextSet) {
+ return getFullContexts().isSatisfiedBy(contextSet, false);
}
@Nonnull
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/NodeBuilder.java b/common/src/main/java/me/lucko/luckperms/common/node/NodeBuilder.java
index b7e9404c1..daf58801b 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/NodeBuilder.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/NodeBuilder.java
@@ -41,7 +41,7 @@ import javax.annotation.Nonnull;
*/
class NodeBuilder implements Node.Builder {
protected String permission;
- private final ImmutableContextSet.Builder extraContexts = ImmutableContextSet.builder();
+ private ImmutableContextSet.Builder extraContexts = ImmutableContextSet.builder();
private Boolean value = true;
private boolean override = false;
private String server = null;
@@ -69,7 +69,7 @@ class NodeBuilder implements Node.Builder {
this.server = node.getServer().orElse(null);
this.world = node.getWorld().orElse(null);
this.expireAt = node.isPermanent() ? 0L : node.getExpiryUnixTime();
- this.extraContexts.addAll(node.getContexts());
+ this.extraContexts = ImmutableContextSet.builder().addAll(node.getContexts());
return this;
}