A few API javadoc improvements

This commit is contained in:
Luck 2018-07-27 23:45:16 -07:00
parent ae3adf23c8
commit 952e41ad3d
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
15 changed files with 404 additions and 132 deletions

View File

@ -26,10 +26,12 @@
package me.lucko.luckperms.api; package me.lucko.luckperms.api;
import me.lucko.luckperms.api.caching.GroupData; import me.lucko.luckperms.api.caching.GroupData;
import me.lucko.luckperms.api.context.ContextSet;
import java.util.OptionalInt; import java.util.OptionalInt;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* An inheritable holder of permission data. * An inheritable holder of permission data.
@ -44,6 +46,33 @@ public interface Group extends PermissionHolder {
@Nonnull @Nonnull
String getName(); String getName();
/**
* Gets the groups "display name", if it has one that differs from it's actual name.
*
* <p>The lookup is made using the current servers active context.</p>
*
* <p>Will return <code>null</code> if the groups display name is equal to it's
* {@link #getName() actual name}.</p>
*
* @return the display name
* @since 4.3
*/
@Nullable
String getDisplayName();
/**
* Gets the groups "display name", if it has one that differs from it's actual name.
*
* <p>Will return <code>null</code> if the groups display name is equal to it's
* {@link #getName() actual name}.</p>
*
* @param contextSet the contexts to lookup in
* @return the display name
* @since 4.3
*/
@Nullable
String getDisplayName(@Nonnull ContextSet contextSet);
/** /**
* Gets the weight of this group, if present. * Gets the weight of this group, if present.
* *

View File

@ -25,13 +25,12 @@
package me.lucko.luckperms.api; package me.lucko.luckperms.api;
import java.util.function.Predicate;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
/** /**
* A node with a traceable origin * An extension of {@link Node}, providing information about
* where the node originated from.
* *
* @since 2.11 * @since 2.11
*/ */
@ -39,19 +38,9 @@ import javax.annotation.concurrent.Immutable;
public interface LocalizedNode extends Node { public interface LocalizedNode extends Node {
/** /**
* Returns a predicate which unwraps the localised node parameter before delegating * Gets the delegate node.
* the handling to the provided predicate.
* *
* @param delegate the delegate predicate. * <p>Result is never another {@link LocalizedNode} instance.</p>
* @return the composed predicate
* @since 4.3
*/
static Predicate<? super LocalizedNode> composedPredicate(Predicate<Node> delegate) {
return localizedNode -> delegate.test(localizedNode.getNode());
}
/**
* Gets the delegate node
* *
* @return the node this instance is representing * @return the node this instance is representing
*/ */
@ -59,10 +48,15 @@ public interface LocalizedNode extends Node {
Node getNode(); Node getNode();
/** /**
* Gets the location where the {@link Node} is inherited from * Gets the location where the {@link Node} is inherited from.
* *
* @return where the node was inherited from. Will not return null. * <p>The resultant string is the {@link PermissionHolder#getObjectName() object name} of the
* @see PermissionHolder#getObjectName() * permission holder the node was inherited from.</p>
*
* <p>If the node was not inherited, the {@link PermissionHolder#getObjectName() object name}
* of the permission holder itself (the one that defined the node) will be returned.</p>
*
* @return where the node was inherited from.
*/ */
@Nonnull @Nonnull
String getLocation(); String getLocation();

View File

@ -33,8 +33,7 @@ import javax.annotation.Nonnull;
* <p>Generally, individual instances of this interface should fulfil the same * <p>Generally, individual instances of this interface should fulfil the same
* requirements as the {@link Object#equals(Object)} contract.</p> * requirements as the {@link Object#equals(Object)} contract.</p>
* *
* <p>Some standard implementations are provided by * <p>Some standard implementations are provided by {@link StandardNodeEquality}.</p>
* {@link StandardNodeEquality}.</p>
* *
* @since 4.1 * @since 4.1
*/ */

View File

@ -31,29 +31,40 @@ import com.google.common.collect.Multimap;
import me.lucko.luckperms.api.caching.CachedData; import me.lucko.luckperms.api.caching.CachedData;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.manager.GroupManager;
import me.lucko.luckperms.api.manager.UserManager;
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 java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate; import java.util.function.Predicate;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
/** /**
* An object which holds permissions. * Generic superinterface for an object which holds permissions.
*
* <p>Any changes made to permission holding objects will be lost unless the
* instance is saved back to the {@link Storage}.</p>
*/ */
public interface PermissionHolder { public interface PermissionHolder {
/** /**
* Gets the objects name. * Gets the objects generic name.
* *
* <p>{@link User#getUuid()}, {@link User#getName()} or {@link Group#getName()} should normally be used instead of * <p>The result of this method is guaranteed to be a unique identifier for distinct instances
* this method.</p> * of the same type of object.</p>
*
* <p>For {@link User}s, this method returns a {@link UUID#toString() string} representation of
* the users {@link User#getUuid() unique id}.</p>
*
* <p>For {@link Group}s, this method returns the {@link Group#getName() group name}.</p>
*
* <p>The {@link User#getUuid()}, {@link User#getName()} and {@link Group#getName()} methods
* define a "tighter" specification for obtaining object identifiers.</p>
* *
* @return the identifier for this object. Either a uuid string or name. * @return the identifier for this object. Either a uuid string or name.
*/ */
@ -63,8 +74,14 @@ public interface PermissionHolder {
/** /**
* Gets a friendly name for this holder, to be displayed in command output, etc. * Gets a friendly name for this holder, to be displayed in command output, etc.
* *
* <p>This will <strong>always</strong> return a value, eventually falling back to {@link #getObjectName()} if no * <p>This will <strong>always</strong> return a value, eventually falling back to
* other "friendlier" identifiers are present.</p> * {@link #getObjectName()} if no other "friendlier" identifiers are present.</p>
*
* <p>For {@link User}s, this method will attempt to return the {@link User#getName() username},
* before falling back to {@link #getObjectName()}.</p>
*
* <p>For {@link Group}s, this method will attempt to return the groups display name, before
* falling back to {@link #getObjectName()}.</p>
* *
* @return a friendly identifier for this holder * @return a friendly identifier for this holder
* @since 3.2 * @since 3.2
@ -128,6 +145,8 @@ public interface PermissionHolder {
* *
* <p>Use {@link #getPermissions()} for a view without duplicates.</p> * <p>Use {@link #getPermissions()} for a view without duplicates.</p>
* *
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* @return a list of the holders own nodes. * @return a list of the holders own nodes.
* @since 3.3 * @since 3.3
*/ */
@ -137,6 +156,13 @@ public interface PermissionHolder {
/** /**
* Gets a sorted set of all held permissions. * Gets a sorted set of all held permissions.
* *
* <p>Effectively a sorted version of {@link #getOwnNodes()}, without duplicates. Use the
* aforementioned method if you don't require either of these attributes.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getPermissions, it will actually return all types of node.</p>
*
* @return an immutable set of permissions in priority order * @return an immutable set of permissions in priority order
* @since 2.6 * @since 2.6
*/ */
@ -144,9 +170,16 @@ public interface PermissionHolder {
SortedSet<? extends Node> getPermissions(); SortedSet<? extends Node> getPermissions();
/** /**
* Similar to {@link #getPermissions()}, except without transient permissions. * Similar to {@link #getPermissions()}, except only including permissions from the enduring
* node map. (See {@link #getNodes()})
* *
* <p>Unlike transient permissions, enduring permissions will be saved to storage, and exist after the session.</p> * <p>Unlike transient permissions, enduring permissions will be saved to storage, and exist
* after the session.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getEnduringPermissions, it will actually return all types
* of node.</p>
* *
* @return a set of nodes * @return a set of nodes
* @since 2.6 * @since 2.6
@ -155,10 +188,16 @@ public interface PermissionHolder {
Set<? extends Node> getEnduringPermissions(); Set<? extends Node> getEnduringPermissions();
/** /**
* Similar to {@link #getPermissions()}, except without enduring permissions. * Similar to {@link #getPermissions()}, except only including permissions from the enduring
* node map. (See {@link #getTransientNodes()})
* *
* <p>Transient permissions only exist for the duration of the session.</p> * <p>Transient permissions only exist for the duration of the session.</p>
* *
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getTransientPermissions, it will actually return all types
* of node.</p>
*
* @return a set of nodes * @return a set of nodes
* @since 2.6 * @since 2.6
*/ */
@ -166,7 +205,14 @@ public interface PermissionHolder {
Set<? extends Node> getTransientPermissions(); Set<? extends Node> getTransientPermissions();
/** /**
* Processes the nodes and returns the non-temporary ones. * A filtered view of this holders nodes, only including permanent entries.
*
* <p>Data is sourced from {@link #getOwnNodes()}, filtered, and then collected to a set.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getPermanentPermissionNodes, it will actually return all types
* of node.</p>
* *
* @return a set of permanent nodes * @return a set of permanent nodes
* @since 2.6 * @since 2.6
@ -175,7 +221,14 @@ public interface PermissionHolder {
Set<Node> getPermanentPermissionNodes(); Set<Node> getPermanentPermissionNodes();
/** /**
* Processes the nodes and returns the temporary ones. * A filtered view of this holders nodes, only including temporary entries.
*
* <p>Data is sourced from {@link #getOwnNodes()}, filtered, and then collected to a set.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getTemporaryPermissionNodes, it will actually return all types
* of node.</p>
* *
* @return a set of temporary nodes * @return a set of temporary nodes
* @since 2.6 * @since 2.6
@ -191,12 +244,16 @@ public interface PermissionHolder {
* *
* <p>This means the list will contain duplicates.</p> * <p>This means the list will contain duplicates.</p>
* *
* <p>Inheritance is performed according to the platforms rules, and the order will vary
* depending on the accumulation order. By default, the holders own nodes are first in the list,
* with the entries from the end of the inheritance tree appearing last.</p>
*
* @param contexts the contexts for the lookup * @param contexts the contexts for the lookup
* @return a list of nodes * @return a list of nodes
* @since 3.3 * @since 3.3
*/ */
@Nonnull @Nonnull
List<LocalizedNode> resolveInheritances(Contexts contexts); List<LocalizedNode> resolveInheritances(@Nonnull Contexts contexts);
/** /**
* Recursively resolves this holders permissions. * Recursively resolves this holders permissions.
@ -209,6 +266,10 @@ public interface PermissionHolder {
* <p>Unlike {@link #resolveInheritances(Contexts)}, this method does not * <p>Unlike {@link #resolveInheritances(Contexts)}, this method does not
* filter by context, at all.</p> * filter by context, at all.</p>
* *
* <p>Inheritance is performed according to the platforms rules, and the order will vary
* depending on the accumulation order. By default, the holders own nodes are first in the list,
* with the entries from the end of the inheritance tree appearing last.</p>
*
* @return a list of nodes * @return a list of nodes
* @since 3.3 * @since 3.3
*/ */
@ -218,13 +279,14 @@ public interface PermissionHolder {
/** /**
* Gets a mutable sorted set of the nodes that this object has and inherits, filtered by context * Gets a mutable sorted set of the nodes that this object has and inherits, filtered by context
* *
* <p>Unlike {@link #getAllNodesFiltered(Contexts)}, this method will not filter individual nodes. The context is only * <p>Unlike {@link #getAllNodesFiltered(Contexts)}, this method will not filter individual
* used to determine which groups should apply.</p> * nodes by context. The context is only used to determine which groups should apply.</p>
* *
* <p>Nodes are sorted into priority order.</p> * <p>Nodes are sorted into priority order. The order of inheritance is only important during
* the process of flattening inherited entries.</p>
* *
* @param contexts the context for the lookup * @param contexts the context for the lookup
* @return a mutable sorted set of permissions * @return an immutable sorted set of permissions
* @throws NullPointerException if the context is null * @throws NullPointerException if the context is null
* @since 2.11 * @since 2.11
*/ */
@ -236,9 +298,10 @@ public interface PermissionHolder {
* *
* <p>Unlike {@link #getAllNodes(Contexts)}, this method does not filter by context, at all.</p> * <p>Unlike {@link #getAllNodes(Contexts)}, this method does not filter by context, at all.</p>
* *
* <p>Nodes are sorted into priority order.</p> * <p>Nodes are sorted into priority order. The order of inheritance is only important during
* the process of flattening inherited entries.</p>
* *
* @return a mutable sorted set of permissions * @return an immutable sorted set of permissions
* @throws NullPointerException if the context is null * @throws NullPointerException if the context is null
* @since 3.3 * @since 3.3
*/ */
@ -248,8 +311,8 @@ public interface PermissionHolder {
/** /**
* Gets a mutable set of the nodes that this object has and inherits, filtered by context. * Gets a mutable set of the nodes that this object has and inherits, filtered by context.
* *
* <p>Unlike {@link #getAllNodes(Contexts)}, this method WILL filter individual nodes, and only return ones that fully * <p>Unlike {@link #getAllNodes(Contexts)}, this method WILL filter individual nodes,
* meet the context provided.</p> * and only return ones that fully meet the context provided.</p>
* *
* @param contexts the context for the lookup * @param contexts the context for the lookup
* @return a mutable set of permissions * @return a mutable set of permissions
@ -260,22 +323,28 @@ public interface PermissionHolder {
Set<LocalizedNode> getAllNodesFiltered(@Nonnull Contexts contexts); Set<LocalizedNode> getAllNodesFiltered(@Nonnull Contexts contexts);
/** /**
* Converts the output of {@link #getAllNodesFiltered(Contexts)}, and expands shorthand permissions. * Converts the output of {@link #getAllNodesFiltered(Contexts)} into string and boolean form,
* and expands shorthand permissions.
* *
* @param contexts the context for the lookup * @param contexts the context for the lookup
* @param lowerCase if the keys should be made lowercase whilst being exported * @param convertToLowercase if the keys should be made lowercase whilst being exported
* @return a mutable map of permissions * @return a mutable map of permissions
*/ */
@Nonnull @Nonnull
Map<String, Boolean> exportNodes(@Nonnull Contexts contexts, boolean lowerCase); Map<String, Boolean> exportNodes(@Nonnull Contexts contexts, boolean convertToLowercase);
/** /**
* Removes temporary permissions that have expired * Removes any temporary permissions that have expired.
*
* <p>This method is called periodically by the platform, so it is only necessary to run
* if you want to guarentee that the current data is totally up-to-date.</p>
*/ */
void auditTemporaryPermissions(); void auditTemporaryPermissions();
/** /**
* Checks to see if the object has a certain permission * Checks to see if the object has a certain permission.
*
* <p>Although this method is named hasPermission, it can be used for all node types.</p>
* *
* @param node the node to check for * @param node the node to check for
* @param equalityPredicate how to determine if a node matches * @param equalityPredicate how to determine if a node matches
@ -287,7 +356,9 @@ public interface PermissionHolder {
Tristate hasPermission(@Nonnull Node node, @Nonnull NodeEqualityPredicate equalityPredicate); Tristate hasPermission(@Nonnull Node node, @Nonnull NodeEqualityPredicate equalityPredicate);
/** /**
* Checks to see if the object has a certain permission * Checks to see if the object has a certain permission.
*
* <p>Although this method is named hasTransientPermission, it can be used for all node types.</p>
* *
* @param node the node to check for * @param node the node to check for
* @param equalityPredicate how to determine if a node matches * @param equalityPredicate how to determine if a node matches
@ -299,7 +370,9 @@ public interface PermissionHolder {
Tristate hasTransientPermission(@Nonnull Node node, @Nonnull NodeEqualityPredicate equalityPredicate); Tristate hasTransientPermission(@Nonnull Node node, @Nonnull NodeEqualityPredicate equalityPredicate);
/** /**
* Checks to see if the object inherits a certain permission * Checks to see if the object inherits a certain permission.
*
* <p>Although this method is named inheritsPermission, it can be used for all node types.</p>
* *
* @param node the node to check for * @param node the node to check for
* @param equalityPredicate how to determine if a node matches * @param equalityPredicate how to determine if a node matches
@ -311,7 +384,9 @@ public interface PermissionHolder {
Tristate inheritsPermission(@Nonnull Node node, @Nonnull NodeEqualityPredicate equalityPredicate); Tristate inheritsPermission(@Nonnull Node node, @Nonnull NodeEqualityPredicate equalityPredicate);
/** /**
* Checks to see if the object has a certain permission * Checks to see if the object has a certain permission.
*
* <p>Although this method is named hasPermission, it can be used for all node types.</p>
* *
* @param node the node to check for * @param node the node to check for
* @return a Tristate for the holders permission status for the node * @return a Tristate for the holders permission status for the node
@ -322,7 +397,9 @@ public interface PermissionHolder {
Tristate hasPermission(@Nonnull Node node); Tristate hasPermission(@Nonnull Node node);
/** /**
* Checks to see if the object has a certain permission * Checks to see if the object has a certain permission.
*
* <p>Although this method is named hasTransientPermission, it can be used for all node types.</p>
* *
* @param node the node to check for * @param node the node to check for
* @return a Tristate for the holders permission status for the node * @return a Tristate for the holders permission status for the node
@ -333,7 +410,9 @@ public interface PermissionHolder {
Tristate hasTransientPermission(@Nonnull Node node); Tristate hasTransientPermission(@Nonnull Node node);
/** /**
* Checks to see if the object inherits a certain permission * Checks to see if the object inherits a certain permission.
*
* <p>Although this method is named inheritsPermission, it can be used for all node types.</p>
* *
* @param node the node to check for * @param node the node to check for
* @return a Tristate for the holders inheritance status for the node * @return a Tristate for the holders inheritance status for the node
@ -344,7 +423,11 @@ public interface PermissionHolder {
Tristate inheritsPermission(@Nonnull Node node); Tristate inheritsPermission(@Nonnull Node node);
/** /**
* Check to see if this holder inherits another group directly * Check to see if this holder inherits another group in the global context.
*
* <p>"Global context" simply means an empty context set.</p>
*
* <p>This method only checks for direct inheritance - one hop up the inheritance tree.</p>
* *
* @param group The group to check membership of * @param group The group to check membership of
* @return true if the group inherits the other group * @return true if the group inherits the other group
@ -355,7 +438,9 @@ public interface PermissionHolder {
boolean inheritsGroup(@Nonnull Group group); boolean inheritsGroup(@Nonnull Group group);
/** /**
* Check to see if this holder inherits another group directly * Check to see if this holder inherits another group.
*
* <p>This method only checks for direct inheritance - one hop up the inheritance tree.</p>
* *
* @param group The group to check membership of * @param group The group to check membership of
* @param contextSet the context set to filter by * @param contextSet the context set to filter by
@ -367,7 +452,20 @@ public interface PermissionHolder {
boolean inheritsGroup(@Nonnull Group group, @Nonnull ContextSet contextSet); boolean inheritsGroup(@Nonnull Group group, @Nonnull ContextSet contextSet);
/** /**
* Sets a permission for the object * Sets a permission node for the permission holder.
*
* <p>Although this method is named setPermission, it can be used for all node types.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @param node The node to be set * @param node The node to be set
* @return the result of the operation * @return the result of the operation
@ -378,16 +476,20 @@ public interface PermissionHolder {
DataMutateResult setPermission(@Nonnull Node node); DataMutateResult setPermission(@Nonnull Node node);
/** /**
* Sets a transient permission for the object * Sets a transient permission for the permission holder.
* *
* <p>A transient node is a permission that does not persist. * <p>A transient node is a permission that does not persist.
* Whenever a user logs out of the server, or the server restarts, this permission will disappear. * Whenever a user logs out of the server, or the server restarts, this permission will
* It is never saved to the datastore, and therefore will not apply on other servers.</p> * disappear. It is never saved to the datastore, and therefore will not apply on other
* servers.</p>
* *
* <p>This is useful if you want to temporarily set a permission for a user while they're online, but don't * <p>This is useful if you want to temporarily set a permission for a user while they're
* want it to persist, and have to worry about removing it when they log out.</p> * online, but don't want it to persist, and have to worry about removing it when they log
* out.</p>
* *
* <p>For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}</p> * <p>For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}.</p>
*
* <p>Although this method is named setTransientPermission, it can be used for all node types.</p>
* *
* @param node The node to be set * @param node The node to be set
* @return the result of the operation * @return the result of the operation
@ -398,7 +500,20 @@ public interface PermissionHolder {
DataMutateResult setTransientPermission(@Nonnull Node node); DataMutateResult setTransientPermission(@Nonnull Node node);
/** /**
* Unsets a permission for the object * Unsets a permission for the permission holder.
*
* <p>Although this method is named unsetPermission, it can be used for all node types.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @param node The node to be unset * @param node The node to be unset
* @return the result of the operation * @return the result of the operation
@ -409,7 +524,9 @@ public interface PermissionHolder {
DataMutateResult unsetPermission(@Nonnull Node node); DataMutateResult unsetPermission(@Nonnull Node node);
/** /**
* Unsets a transient permission for the object * Unsets a transient permission for the permission holder.
*
* <p>Although this method is named unsetTransientPermission, it can be used for all node types.</p>
* *
* @param node The node to be unset * @param node The node to be unset
* @return the result of the operation * @return the result of the operation
@ -420,7 +537,20 @@ public interface PermissionHolder {
DataMutateResult unsetTransientPermission(@Nonnull Node node); DataMutateResult unsetTransientPermission(@Nonnull Node node);
/** /**
* Clears any nodes from the holder which pass the predicate * Clears any nodes from the holder which pass the predicate.
*
* <p>This method only targets enduring data.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @param test the predicate to test for nodes which should be removed * @param test the predicate to test for nodes which should be removed
* @since 3.2 * @since 3.2
@ -428,7 +558,18 @@ public interface PermissionHolder {
void clearMatching(@Nonnull Predicate<Node> test); void clearMatching(@Nonnull Predicate<Node> test);
/** /**
* Clears any transient nodes from the holder which pass the predicate * Clears any transient nodes from the holder which pass the predicate.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @param test the predicate to test for nodes which should be removed * @param test the predicate to test for nodes which should be removed
* @since 3.2 * @since 3.2
@ -436,14 +577,36 @@ public interface PermissionHolder {
void clearMatchingTransient(@Nonnull Predicate<Node> test); void clearMatchingTransient(@Nonnull Predicate<Node> test);
/** /**
* Clears all nodes held by the object * Clears all nodes held by the permission holder.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @since 2.17 * @since 2.17
*/ */
void clearNodes(); void clearNodes();
/** /**
* Clears all nodes held by the object in a specific context * Clears all nodes held by the permission holder in a specific context.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @param contextSet the contexts to filter by * @param contextSet the contexts to filter by
* @since 3.2 * @since 3.2
@ -451,14 +614,36 @@ public interface PermissionHolder {
void clearNodes(@Nonnull ContextSet contextSet); void clearNodes(@Nonnull ContextSet contextSet);
/** /**
* Clears all parent groups * Clears all parent groups.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @since 2.17 * @since 2.17
*/ */
void clearParents(); void clearParents();
/** /**
* Clears all parent groups in a specific context * Clears all parent groups in a specific context.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @param contextSet the contexts to filter by * @param contextSet the contexts to filter by
* @since 3.2 * @since 3.2
@ -466,14 +651,42 @@ public interface PermissionHolder {
void clearParents(@Nonnull ContextSet contextSet); void clearParents(@Nonnull ContextSet contextSet);
/** /**
* Clears all meta held by the object * Clears all meta held by the permission holder.
*
* <p>Meta nodes in this case, are any nodes which have a {@link MetaType}, {@link PrefixType}
* or {@link SuffixType} type.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @since 2.17 * @since 2.17
*/ */
void clearMeta(); void clearMeta();
/** /**
* Clears all meta held by the object in a specific context * Clears all meta held by the permission holder in a specific context.
*
* <p>Meta nodes in this case, are any nodes which have a {@link MetaType}, {@link PrefixType}
* or {@link SuffixType} type.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* *
* @param contextSet the contexts to filter by * @param contextSet the contexts to filter by
* @since 3.2 * @since 3.2
@ -481,12 +694,12 @@ public interface PermissionHolder {
void clearMeta(@Nonnull ContextSet contextSet); void clearMeta(@Nonnull ContextSet contextSet);
/** /**
* Clears all transient permissions the holder has. * Clears all transient nodes the permission holder has.
*/ */
void clearTransientNodes(); void clearTransientNodes();
/** /**
* Sets a permission for the object * Sets a permission for the permission holder.
* *
* @param node The node to be set * @param node The node to be set
* @return the result of the operation * @return the result of the operation
@ -501,7 +714,7 @@ public interface PermissionHolder {
} }
/** /**
* Sets a transient permission for the object * Sets a transient permission for the permission holder.
* *
* @param node The node to be set * @param node The node to be set
* @return the result of the operation * @return the result of the operation
@ -516,7 +729,7 @@ public interface PermissionHolder {
} }
/** /**
* Unsets a permission for the object * Unsets a permission for the permission holder.
* *
* @param node The node to be unset * @param node The node to be unset
* @throws NullPointerException if the node is null * @throws NullPointerException if the node is null
@ -531,7 +744,7 @@ public interface PermissionHolder {
} }
/** /**
* Unsets a transient permission for the object * Unsets a transient permission for the permission holder.
* *
* @param node The node to be unset * @param node The node to be unset
* @throws NullPointerException if the node is null * @throws NullPointerException if the node is null

View File

@ -25,6 +25,8 @@
package me.lucko.luckperms.api; package me.lucko.luckperms.api;
import me.lucko.luckperms.api.manager.UserManager;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -34,6 +36,9 @@ import javax.annotation.Nullable;
/** /**
* Encapsulates the result of an operation to save uuid data about a player. * Encapsulates the result of an operation to save uuid data about a player.
* *
* <p>The corresponding method can be found at
* {@link UserManager#savePlayerData(UUID, String)}.</p>
*
* @since 4.2 * @since 4.2
*/ */
public interface PlayerSaveResult { public interface PlayerSaveResult {

View File

@ -48,7 +48,7 @@ public interface User extends PermissionHolder {
/** /**
* Gets the users username * Gets the users username
* *
* <p>Returns null if no username is associated with this user.</p> * <p>Returns null if no username is known for the user.</p>
* *
* @return the users username * @return the users username
*/ */
@ -58,8 +58,9 @@ public interface User extends PermissionHolder {
/** /**
* Gets the users current primary group. * Gets the users current primary group.
* *
* <p>The result of this method depends on which method is configured for primary group calculation. It may not * <p>The result of this method depends on which method is configured for primary group
* be the same as any value set through {@link #setPrimaryGroup(String)}.</p> * calculation. It may not be the same as any value set through
* {@link #setPrimaryGroup(String)}.</p>
* *
* @return the users primary group * @return the users primary group
*/ */
@ -67,7 +68,10 @@ public interface User extends PermissionHolder {
String getPrimaryGroup(); String getPrimaryGroup();
/** /**
* Sets a users primary group. This will only take effect if platform is using stored primary groups. * Sets a users primary group.
*
* <p>This modifies the "stored value" for the users primary group, which may or may not
* actually take effect, depending on how the platform is calculating primary groups.</p>
* *
* @param group the new primary group * @param group the new primary group
* @return if the change was applied successfully * @return if the change was applied successfully
@ -90,10 +94,9 @@ public interface User extends PermissionHolder {
/** /**
* Refresh and re-assign the users permissions. * Refresh and re-assign the users permissions.
* *
* <p>This request is not buffered, and the refresh call will be ran directly. This should be called on an * @deprecated Calling this method is no longer necessary. Permissions data is now refreshed on
* asynchronous thread.</p> * demand, as changes are made. Consider use of {@link #refreshCachedData()}
* * instead. This method is now implemented as a no-op.
* @deprecated in favour of {@link #refreshCachedData()}.
*/ */
@Deprecated @Deprecated
void refreshPermissions(); void refreshPermissions();
@ -101,11 +104,8 @@ public interface User extends PermissionHolder {
/** /**
* Pre-calculates some values in the user's data cache. * Pre-calculates some values in the user's data cache.
* *
* <p>Is it <b>not</b> necessary to call this method before
* using {@link #getCachedData()}.</p>
*
* @since 2.17 * @since 2.17
* @deprecated because use of this method is no longer necessary. * @deprecated Use of this method is no longer necessary. It is implemented as a no-op.
*/ */
@Deprecated @Deprecated
void setupDataCache(); void setupDataCache();

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.api.caching;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.PermissionHolder; import me.lucko.luckperms.api.PermissionHolder;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -372,7 +373,14 @@ public interface CachedData {
* @param contexts the contexts to pre-calculate for * @param contexts the contexts to pre-calculate for
* @throws NullPointerException if contexts is null * @throws NullPointerException if contexts is null
*/ */
void preCalculate(@Nonnull Contexts contexts); default void preCalculate(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
// pre-calculate just by requesting the data from this cache.
// if the data isn't already loaded, it will be calculated.
getPermissionData(contexts);
getMetaData(contexts);
}
/** /**
* Invalidates any cached {@link PermissionData} instances mapped to the given * Invalidates any cached {@link PermissionData} instances mapped to the given

View File

@ -32,7 +32,7 @@ import javax.annotation.Nonnull;
/** /**
* Encapsulates the LuckPerms system which accepts incoming {@link Message}s * Encapsulates the LuckPerms system which accepts incoming {@link Message}s
* from implementations of {@link MessengerProvider}. * from implementations of {@link Messenger}.
* *
* @since 4.1 * @since 4.1
*/ */

View File

@ -45,12 +45,18 @@ public interface Messenger extends AutoCloseable {
* of the interfaces extending {@link Message} in the * of the interfaces extending {@link Message} in the
* 'api.messenger.message.type' package.</p> * 'api.messenger.message.type' package.</p>
* *
* <p>3rd party implementations are encouraged to implement this method with consideration
* that new types may be added in the future.</p>
*
* <p>This call is always made async.</p> * <p>This call is always made async.</p>
* *
* @param outgoingMessage the outgoing message * @param outgoingMessage the outgoing message
*/ */
void sendOutgoingMessage(@Nonnull OutgoingMessage outgoingMessage); void sendOutgoingMessage(@Nonnull OutgoingMessage outgoingMessage);
/**
* Performs the necessary action to gracefully shutdown the messenger.
*/
@Override @Override
default void close() { default void close() {

View File

@ -27,13 +27,13 @@ package me.lucko.luckperms.bukkit.model.permissible;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.bukkit.model.dummy.DummyPlugin; import me.lucko.luckperms.bukkit.model.dummy.DummyPlugin;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.factory.NodeFactory; import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.node.model.ImmutableTransientNode; import me.lucko.luckperms.common.node.model.ImmutableTransientNode;
import me.lucko.luckperms.common.node.utils.NodeTools;
import org.bukkit.permissions.PermissionAttachment; import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionRemovedExecutor; import org.bukkit.permissions.PermissionRemovedExecutor;
@ -199,13 +199,13 @@ public class LPPermissionAttachment extends PermissionAttachment {
// remove transient permissions from the holder which were added by this attachment & equal the permission // remove transient permissions from the holder which were added by this attachment & equal the permission
User user = this.permissible.getUser(); User user = this.permissible.getUser();
user.removeIfTransient(LocalizedNode.composedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name))); user.removeIfTransient(NodeTools.localizedNodeComposedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name)));
} }
private void clearInternal() { private void clearInternal() {
// remove all transient permissions added by this attachment // remove all transient permissions added by this attachment
User user = this.permissible.getUser(); User user = this.permissible.getUser();
user.removeIfTransient(LocalizedNode.composedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this)); user.removeIfTransient(NodeTools.localizedNodeComposedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this));
} }
@Override @Override

View File

@ -28,12 +28,14 @@ package me.lucko.luckperms.common.api.delegates.model;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.caching.GroupData; import me.lucko.luckperms.api.caching.GroupData;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import java.util.Objects; import java.util.Objects;
import java.util.OptionalInt; import java.util.OptionalInt;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public final class ApiGroup extends ApiPermissionHolder implements me.lucko.luckperms.api.Group { public final class ApiGroup extends ApiPermissionHolder implements me.lucko.luckperms.api.Group {
public static Group cast(me.lucko.luckperms.api.Group group) { public static Group cast(me.lucko.luckperms.api.Group group) {
@ -60,6 +62,18 @@ public final class ApiGroup extends ApiPermissionHolder implements me.lucko.luck
return this.handle.getName(); return this.handle.getName();
} }
@Nullable
@Override
public String getDisplayName() {
return this.handle.getDisplayName().orElse(null);
}
@Nullable
@Override
public String getDisplayName(@Nonnull ContextSet contextSet) {
return this.handle.getDisplayName(contextSet).orElse(null);
}
@Nonnull @Nonnull
@Override @Override
public OptionalInt getWeight() { public OptionalInt getWeight() {

View File

@ -342,7 +342,7 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.PermissionHol
@Nonnull @Nonnull
@Override @Override
public List<LocalizedNode> resolveInheritances(Contexts contexts) { public List<LocalizedNode> resolveInheritances(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
return ImmutableList.copyOf(this.handle.resolveInheritances(contexts)); return ImmutableList.copyOf(this.handle.resolveInheritances(contexts));
} }

View File

@ -186,7 +186,7 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull @Nonnull
@Override @Override
public PermissionCache getPermissionData(@Nonnull Contexts contexts) { public final PermissionCache getPermissionData(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
//noinspection ConstantConditions //noinspection ConstantConditions
@ -195,7 +195,7 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull @Nonnull
@Override @Override
public MetaCache getMetaData(@Nonnull MetaContexts contexts) { public final MetaCache getMetaData(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
//noinspection ConstantConditions //noinspection ConstantConditions
@ -204,53 +204,53 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull @Nonnull
@Override @Override
public MetaCache getMetaData(@Nonnull Contexts contexts) { public final MetaCache getMetaData(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
return getMetaData(getDefaultMetaContexts(contexts)); return getMetaData(getDefaultMetaContexts(contexts));
} }
@Nonnull @Nonnull
@Override @Override
public PermissionCache calculatePermissions(@Nonnull Contexts contexts) { public final PermissionCache calculatePermissions(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
return calculatePermissions(contexts, null); return calculatePermissions(contexts, null);
} }
@Nonnull @Nonnull
@Override @Override
public MetaCache calculateMeta(@Nonnull MetaContexts contexts) { public final MetaCache calculateMeta(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
return calculateMeta(contexts, null); return calculateMeta(contexts, null);
} }
@Nonnull @Nonnull
@Override @Override
public MetaCache calculateMeta(@Nonnull Contexts contexts) { public final MetaCache calculateMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
return calculateMeta(getDefaultMetaContexts(contexts)); return calculateMeta(getDefaultMetaContexts(contexts));
} }
@Override @Override
public void recalculatePermissions(@Nonnull Contexts contexts) { public final void recalculatePermissions(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
this.permission.synchronous().refresh(contexts); this.permission.synchronous().refresh(contexts);
} }
@Override @Override
public void recalculateMeta(@Nonnull MetaContexts contexts) { public final void recalculateMeta(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
this.meta.synchronous().refresh(contexts); this.meta.synchronous().refresh(contexts);
} }
@Override @Override
public void recalculateMeta(@Nonnull Contexts contexts) { public final void recalculateMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
recalculateMeta(getDefaultMetaContexts(contexts)); recalculateMeta(getDefaultMetaContexts(contexts));
} }
@Nonnull @Nonnull
@Override @Override
public CompletableFuture<PermissionCache> reloadPermissions(@Nonnull Contexts contexts) { public final CompletableFuture<PermissionCache> reloadPermissions(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
// get the previous value - to use when recalculating // get the previous value - to use when recalculating
@ -271,7 +271,7 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull @Nonnull
@Override @Override
public CompletableFuture<MetaCache> reloadMeta(@Nonnull MetaContexts contexts) { public final CompletableFuture<MetaCache> reloadMeta(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
// get the previous value - to use when recalculating // get the previous value - to use when recalculating
@ -292,86 +292,76 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull @Nonnull
@Override @Override
public CompletableFuture<MetaCache> reloadMeta(@Nonnull Contexts contexts) { public final CompletableFuture<MetaCache> reloadMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
return reloadMeta(getDefaultMetaContexts(contexts)); return reloadMeta(getDefaultMetaContexts(contexts));
} }
@Override @Override
public void recalculatePermissions() { public final void recalculatePermissions() {
Set<Contexts> keys = this.permission.synchronous().asMap().keySet(); Set<Contexts> keys = this.permission.synchronous().asMap().keySet();
keys.forEach(this::recalculatePermissions); keys.forEach(this::recalculatePermissions);
} }
@Override @Override
public void recalculateMeta() { public final void recalculateMeta() {
Set<MetaContexts> keys = this.meta.synchronous().asMap().keySet(); Set<MetaContexts> keys = this.meta.synchronous().asMap().keySet();
keys.forEach(this::recalculateMeta); keys.forEach(this::recalculateMeta);
} }
@Nonnull @Nonnull
@Override @Override
public CompletableFuture<Void> reloadPermissions() { public final CompletableFuture<Void> reloadPermissions() {
Set<Contexts> keys = this.permission.synchronous().asMap().keySet(); Set<Contexts> keys = this.permission.synchronous().asMap().keySet();
return CompletableFuture.allOf(keys.stream().map(this::reloadPermissions).toArray(CompletableFuture[]::new)); return CompletableFuture.allOf(keys.stream().map(this::reloadPermissions).toArray(CompletableFuture[]::new));
} }
@Nonnull @Nonnull
@Override @Override
public CompletableFuture<Void> reloadMeta() { public final CompletableFuture<Void> reloadMeta() {
Set<MetaContexts> keys = this.meta.synchronous().asMap().keySet(); Set<MetaContexts> keys = this.meta.synchronous().asMap().keySet();
return CompletableFuture.allOf(keys.stream().map(this::reloadMeta).toArray(CompletableFuture[]::new)); return CompletableFuture.allOf(keys.stream().map(this::reloadMeta).toArray(CompletableFuture[]::new));
} }
@Override @Override
public void preCalculate(@Nonnull Contexts contexts) { public final void invalidatePermissions(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
// pre-calculate just by requesting the data from this cache.
// if the data isn't already loaded, it will be calculated.
getPermissionData(contexts);
getMetaData(contexts);
}
@Override
public void invalidatePermissions(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
this.permission.synchronous().invalidate(contexts); this.permission.synchronous().invalidate(contexts);
} }
@Override @Override
public void invalidateMeta(@Nonnull MetaContexts contexts) { public final void invalidateMeta(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
this.meta.synchronous().invalidate(contexts); this.meta.synchronous().invalidate(contexts);
} }
@Override @Override
public void invalidateMeta(@Nonnull Contexts contexts) { public final void invalidateMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(contexts, "contexts");
this.meta.synchronous().invalidate(getDefaultMetaContexts(contexts)); this.meta.synchronous().invalidate(getDefaultMetaContexts(contexts));
} }
@Override @Override
public void invalidatePermissions() { public final void invalidatePermissions() {
this.permission.synchronous().invalidateAll(); this.permission.synchronous().invalidateAll();
} }
@Override @Override
public void invalidateMeta() { public final void invalidateMeta() {
this.meta.synchronous().invalidateAll(); this.meta.synchronous().invalidateAll();
} }
@Override @Override
public void invalidatePermissionCalculators() { public final void invalidatePermissionCalculators() {
this.permission.synchronous().asMap().values().forEach(PermissionCache::invalidateCache); this.permission.synchronous().asMap().values().forEach(PermissionCache::invalidateCache);
} }
public void invalidate() { public final void invalidate() {
invalidatePermissions(); invalidatePermissions();
invalidateMeta(); invalidateMeta();
} }
public void doCacheCleanup() { public final void doCacheCleanup() {
this.permission.synchronous().cleanUp(); this.permission.synchronous().cleanUp();
this.meta.synchronous().cleanUp(); this.meta.synchronous().cleanUp();
} }

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.node.utils; package me.lucko.luckperms.common.node.utils;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.NodeEqualityPredicate; import me.lucko.luckperms.api.NodeEqualityPredicate;
@ -33,6 +34,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate;
public final class NodeTools { public final class NodeTools {
@ -64,5 +66,17 @@ public final class NodeTools {
} }
} }
/**
* Returns a predicate which unwraps the localised node parameter before delegating
* the handling to the provided predicate.
*
* @param delegate the delegate predicate.
* @return the composed predicate
* @since 4.3
*/
public static Predicate<? super LocalizedNode> localizedNodeComposedPredicate(Predicate<Node> delegate) {
return localizedNode -> delegate.test(localizedNode.getNode());
}
private NodeTools() {} private NodeTools() {}
} }

View File

@ -27,12 +27,12 @@ package me.lucko.luckperms.nukkit.model.permissible;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.factory.NodeFactory; import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.node.model.ImmutableTransientNode; import me.lucko.luckperms.common.node.model.ImmutableTransientNode;
import me.lucko.luckperms.common.node.utils.NodeTools;
import me.lucko.luckperms.nukkit.model.dummy.DummyPlugin; import me.lucko.luckperms.nukkit.model.dummy.DummyPlugin;
import cn.nukkit.permission.Permission; import cn.nukkit.permission.Permission;
@ -200,13 +200,13 @@ public class LPPermissionAttachment extends PermissionAttachment {
// remove transient permissions from the holder which were added by this attachment & equal the permission // remove transient permissions from the holder which were added by this attachment & equal the permission
User user = this.permissible.getUser(); User user = this.permissible.getUser();
user.removeIfTransient(LocalizedNode.composedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name))); user.removeIfTransient(NodeTools.localizedNodeComposedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name)));
} }
private void clearInternal() { private void clearInternal() {
// remove all transient permissions added by this attachment // remove all transient permissions added by this attachment
User user = this.permissible.getUser(); User user = this.permissible.getUser();
user.removeIfTransient(LocalizedNode.composedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this)); user.removeIfTransient(NodeTools.localizedNodeComposedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this));
} }
@Override @Override