From 952e41ad3ddf4220060d3f73b31b1c65bb5e0778 Mon Sep 17 00:00:00 2001
From: Luck The lookup is made using the current servers active context. Will return Will return Result is never another {@link LocalizedNode} instance. The resultant string is the {@link PermissionHolder#getObjectName() object name} of the
+ * permission holder the node was inherited from. 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. Generally, individual instances of this interface should fulfil the same
* requirements as the {@link Object#equals(Object)} contract. Some standard implementations are provided by
- * {@link StandardNodeEquality}. Some standard implementations are provided by {@link StandardNodeEquality}. Any changes made to permission holding objects will be lost unless the
- * instance is saved back to the {@link Storage}. {@link User#getUuid()}, {@link User#getName()} or {@link Group#getName()} should normally be used instead of
- * this method. The result of this method is guaranteed to be a unique identifier for distinct instances
+ * of the same type of object. For {@link User}s, this method returns a {@link UUID#toString() string} representation of
+ * the users {@link User#getUuid() unique id}. For {@link Group}s, this method returns the {@link Group#getName() group name}. The {@link User#getUuid()}, {@link User#getName()} and {@link Group#getName()} methods
+ * define a "tighter" specification for obtaining object identifiers. This will always return a value, eventually falling back to {@link #getObjectName()} if no
- * other "friendlier" identifiers are present. This will always return a value, eventually falling back to
+ * {@link #getObjectName()} if no other "friendlier" identifiers are present. For {@link User}s, this method will attempt to return the {@link User#getName() username},
+ * before falling back to {@link #getObjectName()}. For {@link Group}s, this method will attempt to return the groups display name, before
+ * falling back to {@link #getObjectName()}. Use {@link #getPermissions()} for a view without duplicates. This method does not resolve inheritance rules. Effectively a sorted version of {@link #getOwnNodes()}, without duplicates. Use the
+ * aforementioned method if you don't require either of these attributes. This method does not resolve inheritance rules. Although this method is named getPermissions, it will actually return all types of node. Unlike transient permissions, enduring permissions will be saved to storage, and exist after the session. Unlike transient permissions, enduring permissions will be saved to storage, and exist
+ * after the session. This method does not resolve inheritance rules. Although this method is named getEnduringPermissions, it will actually return all types
+ * of node. Transient permissions only exist for the duration of the session. This method does not resolve inheritance rules. Although this method is named getTransientPermissions, it will actually return all types
+ * of node. Data is sourced from {@link #getOwnNodes()}, filtered, and then collected to a set. This method does not resolve inheritance rules. Although this method is named getPermanentPermissionNodes, it will actually return all types
+ * of node. Data is sourced from {@link #getOwnNodes()}, filtered, and then collected to a set. This method does not resolve inheritance rules. Although this method is named getTemporaryPermissionNodes, it will actually return all types
+ * of node. This means the list will contain duplicates. 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. Unlike {@link #resolveInheritances(Contexts)}, this method does not
* filter by context, at all. 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. Unlike {@link #getAllNodesFiltered(Contexts)}, this method will not filter individual nodes. The context is only
- * used to determine which groups should apply. Unlike {@link #getAllNodesFiltered(Contexts)}, this method will not filter individual
+ * nodes by context. The context is only used to determine which groups should apply. Nodes are sorted into priority order. Nodes are sorted into priority order. The order of inheritance is only important during
+ * the process of flattening inherited entries. Unlike {@link #getAllNodes(Contexts)}, this method does not filter by context, at all. Nodes are sorted into priority order. Nodes are sorted into priority order. The order of inheritance is only important during
+ * the process of flattening inherited entries. Unlike {@link #getAllNodes(Contexts)}, this method WILL filter individual nodes, and only return ones that fully
- * meet the context provided. Unlike {@link #getAllNodes(Contexts)}, this method WILL filter individual nodes,
+ * and only return ones that fully meet the context provided. 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. Although this method is named hasPermission, it can be used for all node types. Although this method is named hasTransientPermission, it can be used for all node types. Although this method is named inheritsPermission, it can be used for all node types. Although this method is named hasPermission, it can be used for all node types. Although this method is named hasTransientPermission, it can be used for all node types. Although this method is named inheritsPermission, it can be used for all node types. "Global context" simply means an empty context set. This method only checks for direct inheritance - one hop up the inheritance tree. This method only checks for direct inheritance - one hop up the inheritance tree. Although this method is named setPermission, it can be used for all node types. 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)}. 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. 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.
- * It is never saved to the datastore, and therefore will not apply on other servers.null if the groups display name is equal to it's
+ * {@link #getName() actual name}.null if the groups display name is equal to it's
+ * {@link #getName() actual name}.
This is useful if you want to temporarily set a permission for a user while they're online, but don't - * want it to persist, and have to worry about removing it when they log out.
+ *This is useful if you want to temporarily set a permission for a user while they're + * online, but don't want it to persist, and have to worry about removing it when they log + * out.
* - *For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}
+ *For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}.
+ * + *Although this method is named setTransientPermission, it can be used for all node types.
* * @param node The node to be set * @return the result of the operation @@ -398,7 +500,20 @@ public interface PermissionHolder { DataMutateResult setTransientPermission(@Nonnull Node node); /** - * Unsets a permission for the object + * Unsets a permission for the permission holder. + * + *Although this method is named unsetPermission, it can be used for all node types.
+ * + *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)}.
+ * + *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.
* * @param node The node to be unset * @return the result of the operation @@ -409,7 +524,9 @@ public interface PermissionHolder { DataMutateResult unsetPermission(@Nonnull Node node); /** - * Unsets a transient permission for the object + * Unsets a transient permission for the permission holder. + * + *Although this method is named unsetTransientPermission, it can be used for all node types.
* * @param node The node to be unset * @return the result of the operation @@ -420,7 +537,20 @@ public interface PermissionHolder { 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. + * + *This method only targets enduring data.
+ * + *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)}.
+ * + *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.
* * @param test the predicate to test for nodes which should be removed * @since 3.2 @@ -428,7 +558,18 @@ public interface PermissionHolder { void clearMatching(@Nonnull PredicateThe 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)}.
+ * + *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.
* * @param test the predicate to test for nodes which should be removed * @since 3.2 @@ -436,14 +577,36 @@ public interface PermissionHolder { void clearMatchingTransient(@Nonnull PredicateThe 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)}.
+ * + *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.
* * @since 2.17 */ 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. + * + *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)}.
+ * + *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.
* * @param contextSet the contexts to filter by * @since 3.2 @@ -451,14 +614,36 @@ public interface PermissionHolder { void clearNodes(@Nonnull ContextSet contextSet); /** - * Clears all parent groups + * Clears all parent groups. + * + *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)}.
+ * + *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.
* * @since 2.17 */ void clearParents(); /** - * Clears all parent groups in a specific context + * Clears all parent groups in a specific context. + * + *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)}.
+ * + *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.
* * @param contextSet the contexts to filter by * @since 3.2 @@ -466,14 +651,42 @@ public interface PermissionHolder { void clearParents(@Nonnull ContextSet contextSet); /** - * Clears all meta held by the object + * Clears all meta held by the permission holder. + * + *Meta nodes in this case, are any nodes which have a {@link MetaType}, {@link PrefixType} + * or {@link SuffixType} type.
+ * + *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)}.
+ * + *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.
* * @since 2.17 */ 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. + * + *Meta nodes in this case, are any nodes which have a {@link MetaType}, {@link PrefixType} + * or {@link SuffixType} type.
+ * + *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)}.
+ * + *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.
* * @param contextSet the contexts to filter by * @since 3.2 @@ -481,12 +694,12 @@ public interface PermissionHolder { void clearMeta(@Nonnull ContextSet contextSet); /** - * Clears all transient permissions the holder has. + * Clears all transient nodes the permission holder has. */ void clearTransientNodes(); /** - * Sets a permission for the object + * Sets a permission for the permission holder. * * @param node The node to be set * @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 * @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 * @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 * @throws NullPointerException if the node is null diff --git a/api/src/main/java/me/lucko/luckperms/api/PlayerSaveResult.java b/api/src/main/java/me/lucko/luckperms/api/PlayerSaveResult.java index e070820a3..37067a596 100644 --- a/api/src/main/java/me/lucko/luckperms/api/PlayerSaveResult.java +++ b/api/src/main/java/me/lucko/luckperms/api/PlayerSaveResult.java @@ -25,6 +25,8 @@ package me.lucko.luckperms.api; +import me.lucko.luckperms.api.manager.UserManager; + import java.util.Set; 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. * + *The corresponding method can be found at + * {@link UserManager#savePlayerData(UUID, String)}.
+ * * @since 4.2 */ public interface PlayerSaveResult { diff --git a/api/src/main/java/me/lucko/luckperms/api/User.java b/api/src/main/java/me/lucko/luckperms/api/User.java index 0420a7e75..a3cd3ee82 100644 --- a/api/src/main/java/me/lucko/luckperms/api/User.java +++ b/api/src/main/java/me/lucko/luckperms/api/User.java @@ -48,7 +48,7 @@ public interface User extends PermissionHolder { /** * Gets the users username * - *Returns null if no username is associated with this user.
+ *Returns null if no username is known for the user.
* * @return the users username */ @@ -58,8 +58,9 @@ public interface User extends PermissionHolder { /** * Gets the users current primary group. * - *The result of this method depends on which method is configured for primary group calculation. It may not - * be the same as any value set through {@link #setPrimaryGroup(String)}.
+ *The result of this method depends on which method is configured for primary group + * calculation. It may not be the same as any value set through + * {@link #setPrimaryGroup(String)}.
* * @return the users primary group */ @@ -67,7 +68,10 @@ public interface User extends PermissionHolder { String getPrimaryGroup(); /** - * Sets a users primary group. This will only take effect if platform is using stored primary groups. + * Sets a users primary group. + * + *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.
* * @param group the new primary group * @return if the change was applied successfully @@ -90,10 +94,9 @@ public interface User extends PermissionHolder { /** * Refresh and re-assign the users permissions. * - *This request is not buffered, and the refresh call will be ran directly. This should be called on an - * asynchronous thread.
- * - * @deprecated in favour of {@link #refreshCachedData()}. + * @deprecated Calling this method is no longer necessary. Permissions data is now refreshed on + * demand, as changes are made. Consider use of {@link #refreshCachedData()} + * instead. This method is now implemented as a no-op. */ @Deprecated void refreshPermissions(); @@ -101,11 +104,8 @@ public interface User extends PermissionHolder { /** * Pre-calculates some values in the user's data cache. * - *Is it not necessary to call this method before - * using {@link #getCachedData()}.
- * * @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 void setupDataCache(); diff --git a/api/src/main/java/me/lucko/luckperms/api/caching/CachedData.java b/api/src/main/java/me/lucko/luckperms/api/caching/CachedData.java index 04a8d9704..f40366401 100644 --- a/api/src/main/java/me/lucko/luckperms/api/caching/CachedData.java +++ b/api/src/main/java/me/lucko/luckperms/api/caching/CachedData.java @@ -28,6 +28,7 @@ package me.lucko.luckperms.api.caching; import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.PermissionHolder; +import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -372,7 +373,14 @@ public interface CachedData { * @param contexts the contexts to pre-calculate for * @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 diff --git a/api/src/main/java/me/lucko/luckperms/api/messenger/IncomingMessageConsumer.java b/api/src/main/java/me/lucko/luckperms/api/messenger/IncomingMessageConsumer.java index 5de6f04d8..c568c1f65 100644 --- a/api/src/main/java/me/lucko/luckperms/api/messenger/IncomingMessageConsumer.java +++ b/api/src/main/java/me/lucko/luckperms/api/messenger/IncomingMessageConsumer.java @@ -32,7 +32,7 @@ import javax.annotation.Nonnull; /** * Encapsulates the LuckPerms system which accepts incoming {@link Message}s - * from implementations of {@link MessengerProvider}. + * from implementations of {@link Messenger}. * * @since 4.1 */ diff --git a/api/src/main/java/me/lucko/luckperms/api/messenger/Messenger.java b/api/src/main/java/me/lucko/luckperms/api/messenger/Messenger.java index 3324203aa..54bb8fe24 100644 --- a/api/src/main/java/me/lucko/luckperms/api/messenger/Messenger.java +++ b/api/src/main/java/me/lucko/luckperms/api/messenger/Messenger.java @@ -45,12 +45,18 @@ public interface Messenger extends AutoCloseable { * of the interfaces extending {@link Message} in the * 'api.messenger.message.type' package. * + *3rd party implementations are encouraged to implement this method with consideration + * that new types may be added in the future.
+ * *This call is always made async.
* * @param outgoingMessage the outgoing message */ void sendOutgoingMessage(@Nonnull OutgoingMessage outgoingMessage); + /** + * Performs the necessary action to gracefully shutdown the messenger. + */ @Override default void close() { 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 9ecd71812..4beabacf4 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 @@ -27,13 +27,13 @@ package me.lucko.luckperms.bukkit.model.permissible; import com.google.common.base.Preconditions; -import me.lucko.luckperms.api.LocalizedNode; 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.factory.NodeFactory; 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.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 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() { // remove all transient permissions added by this attachment 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 diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiGroup.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiGroup.java index e2c4101eb..d468d3504 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiGroup.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiGroup.java @@ -28,12 +28,14 @@ package me.lucko.luckperms.common.api.delegates.model; import com.google.common.base.Preconditions; import me.lucko.luckperms.api.caching.GroupData; +import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.common.model.Group; import java.util.Objects; import java.util.OptionalInt; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public final class ApiGroup extends ApiPermissionHolder implements me.lucko.luckperms.api.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(); } + @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 @Override public OptionalInt getWeight() { 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 d2267ed95..711ff279a 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 @@ -342,7 +342,7 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.PermissionHol @Nonnull @Override - public List