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 67d27210..ad277631 100644
--- a/api/src/main/java/me/lucko/luckperms/api/Node.java
+++ b/api/src/main/java/me/lucko/luckperms/api/Node.java
@@ -30,6 +30,7 @@ import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.nodetype.NodeType;
import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+import me.lucko.luckperms.api.nodetype.types.DisplayNameType;
import me.lucko.luckperms.api.nodetype.types.InheritanceType;
import me.lucko.luckperms.api.nodetype.types.MetaType;
import me.lucko.luckperms.api.nodetype.types.PrefixType;
@@ -95,6 +96,7 @@ import javax.annotation.concurrent.Immutable;
*
{@link SuffixType} - represents an assigned suffix
* {@link MetaType} - represents an assigned meta option
* {@link WeightType} - marks the weight of the object holding this node
+ * {@link DisplayNameType} - marks the display name of the object holding this node
*
*
* The core node state must be immutable in all implementations.
diff --git a/api/src/main/java/me/lucko/luckperms/api/nodetype/types/DisplayNameType.java b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/DisplayNameType.java
new file mode 100644
index 00000000..34547034
--- /dev/null
+++ b/api/src/main/java/me/lucko/luckperms/api/nodetype/types/DisplayNameType.java
@@ -0,0 +1,54 @@
+/*
+ * This file is part of LuckPerms, licensed under the MIT License.
+ *
+ * Copyright (c) lucko (Luck)
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.lucko.luckperms.api.nodetype.types;
+
+import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.nodetype.NodeType;
+import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A sub-type of {@link Node} used to mark the display name of the node's holder.
+ *
+ * @since 4.2
+ */
+public interface DisplayNameType extends NodeType {
+
+ /**
+ * The key for this type.
+ */
+ NodeTypeKey KEY = new NodeTypeKey(){};
+
+ /**
+ * Gets the display name.
+ *
+ * @return the display name
+ */
+ @Nonnull
+ String getDisplayName();
+
+}
diff --git a/common/src/main/java/me/lucko/luckperms/common/buffers/Cache.java b/common/src/main/java/me/lucko/luckperms/common/buffers/Cache.java
index 6ced4455..0ed2464f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/buffers/Cache.java
+++ b/common/src/main/java/me/lucko/luckperms/common/buffers/Cache.java
@@ -26,63 +26,42 @@
package me.lucko.luckperms.common.buffers;
import java.util.Optional;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import javax.annotation.Nonnull;
/**
- * Thread-safe caching utility
+ * Simple one element cache implementation.
*
* @param the type being stored
*/
public abstract class Cache {
- private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
- private T cached = null;
+ private volatile T value = null;
+ @Nonnull
protected abstract T supply();
public final T get() {
- // try to just read from the cached value
- this.lock.readLock().lock();
- try {
- if (this.cached != null) {
- return this.cached;
+ T val = this.value;
+
+ // double checked locking
+ if (val == null) {
+ synchronized (this) {
+ val = this.value;
+ if (val == null) {
+ val = supply();
+ this.value = val;
+ }
}
- } finally {
- // we have to release the read lock, as it is not possible
- // to acquire the write lock whilst holding a read lock
- this.lock.readLock().unlock();
}
- this.lock.writeLock().lock();
- try {
- // Since the lock was unlocked momentarily, we need
- // to check again for a cached value
- if (this.cached != null) {
- return this.cached;
- }
-
- // call the supplier and set the cached value
- this.cached = supply();
- return this.cached;
- } finally {
- this.lock.writeLock().unlock();
- }
+ return val;
}
public final Optional getIfPresent() {
- this.lock.readLock().lock();
- try {
- return Optional.ofNullable(this.cached);
- } finally {
- this.lock.readLock().unlock();
- }
+ return Optional.ofNullable(this.value);
}
public final void invalidate() {
- this.lock.writeLock().lock();
- try {
- this.cached = null;
- } finally {
- this.lock.writeLock().unlock();
- }
+ this.value = null;
}
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetDisplayName.java b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetDisplayName.java
index 04f42fd1..9035c36a 100644
--- a/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetDisplayName.java
+++ b/common/src/main/java/me/lucko/luckperms/common/commands/group/GroupSetDisplayName.java
@@ -25,12 +25,16 @@
package me.lucko.luckperms.common.commands.group;
+import me.lucko.luckperms.api.context.MutableContextSet;
+import me.lucko.luckperms.api.nodetype.types.DisplayNameType;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.command.CommandResult;
+import me.lucko.luckperms.common.command.abstraction.CommandException;
import me.lucko.luckperms.common.command.abstraction.SubCommand;
import me.lucko.luckperms.common.command.access.ArgumentPermissions;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.command.utils.ArgumentParser;
+import me.lucko.luckperms.common.command.utils.MessageUtils;
import me.lucko.luckperms.common.command.utils.StorageAssistant;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.command.CommandSpec;
@@ -45,18 +49,20 @@ import java.util.List;
public class GroupSetDisplayName extends SubCommand {
public GroupSetDisplayName(LocaleManager locale) {
- super(CommandSpec.GROUP_SET_DISPLAY_NAME.localize(locale), "setdisplayname", CommandPermission.GROUP_SET_DISPLAY_NAME, Predicates.not(1));
+ super(CommandSpec.GROUP_SET_DISPLAY_NAME.localize(locale), "setdisplayname", CommandPermission.GROUP_SET_DISPLAY_NAME, Predicates.is(0));
}
@Override
- public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) {
+ public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List args, String label) throws CommandException {
if (ArgumentPermissions.checkModifyPerms(plugin, sender, getPermission().get(), group)) {
Message.COMMAND_NO_PERMISSION.send(sender);
return CommandResult.NO_PERMISSION;
}
String name = ArgumentParser.parseString(0, args);
- String previousName = group.getDisplayName().orElse(null);
+ MutableContextSet context = ArgumentParser.parseContext(1, args, plugin);
+
+ String previousName = group.getDisplayName(context).orElse(null);
if (previousName == null && name.equals(group.getName())) {
Message.GROUP_SET_DISPLAY_NAME_DOESNT_HAVE.send(sender, group.getName());
@@ -74,25 +80,25 @@ public class GroupSetDisplayName extends SubCommand {
return CommandResult.STATE_ERROR;
}
- group.removeIf(n -> n.getPermission().startsWith("displayname."));
+ group.removeIf(context, n -> n.getTypeData(DisplayNameType.KEY).isPresent());
if (name.equals(group.getName())) {
- Message.GROUP_SET_DISPLAY_NAME_REMOVED.send(sender, group.getName());
+ Message.GROUP_SET_DISPLAY_NAME_REMOVED.send(sender, group.getName(), MessageUtils.contextSetToString(context));
ExtendedLogEntry.build().actor(sender).acted(group)
- .action("setdisplayname", name)
+ .action("setdisplayname", name, context)
.build().submit(plugin, sender);
StorageAssistant.save(group, sender, plugin);
return CommandResult.SUCCESS;
}
- group.setPermission(NodeFactory.builder("displayname." + name).build());
+ group.setPermission(NodeFactory.builder("displayname." + name).withExtraContext(context).build());
- Message.GROUP_SET_DISPLAY_NAME.send(sender, name, group.getName());
+ Message.GROUP_SET_DISPLAY_NAME.send(sender, name, group.getName(), MessageUtils.contextSetToString(context));
ExtendedLogEntry.build().actor(sender).acted(group)
- .action("setdisplayname", name)
+ .action("setdisplayname", name, context)
.build().submit(plugin, sender);
StorageAssistant.save(group, sender, plugin);
diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java b/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java
index 6e592381..fde271f5 100644
--- a/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java
+++ b/common/src/main/java/me/lucko/luckperms/common/locale/command/CommandSpec.java
@@ -169,7 +169,8 @@ public enum CommandSpec {
),
GROUP_SET_DISPLAY_NAME("Set the groups display name",
Argument.list(
- Argument.create("name", true, "the name to set")
+ Argument.create("name", true, "the name to set"),
+ Argument.create("context...", false, "the contexts to set the name in")
)
),
GROUP_RENAME("Rename the group",
diff --git a/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java b/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java
index b3cfb1df..f5bc2a4c 100644
--- a/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java
+++ b/common/src/main/java/me/lucko/luckperms/common/locale/message/Message.java
@@ -364,8 +364,8 @@ public enum Message {
GROUP_SET_DISPLAY_NAME_DOESNT_HAVE("&b{}&a doesn't have a display name set.", true),
GROUP_SET_DISPLAY_NAME_ALREADY_HAS("&b{}&a already has a display name of &b{}&a.", true),
GROUP_SET_DISPLAY_NAME_ALREADY_IN_USE("&aThe display name &b{}&a is already being used by &b{}&a.", true),
- GROUP_SET_DISPLAY_NAME("&aSet display name to &b{}&a for group &b{}&a.", true),
- GROUP_SET_DISPLAY_NAME_REMOVED("&aRemoved display name for group &b{}&a.", true),
+ GROUP_SET_DISPLAY_NAME("&aSet display name to &b{}&a for group &b{}&a in context {}&a.", true),
+ GROUP_SET_DISPLAY_NAME_REMOVED("&aRemoved display name for group &b{}&a in context {}&a.", true),
TRACK_INFO(
"{PREFIX}&b&l> &bShowing Track: &f{}" + "\n" +
diff --git a/common/src/main/java/me/lucko/luckperms/common/managers/group/AbstractGroupManager.java b/common/src/main/java/me/lucko/luckperms/common/managers/group/AbstractGroupManager.java
index fc53b7bf..0ae70a6f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/managers/group/AbstractGroupManager.java
+++ b/common/src/main/java/me/lucko/luckperms/common/managers/group/AbstractGroupManager.java
@@ -28,6 +28,8 @@ package me.lucko.luckperms.common.managers.group;
import me.lucko.luckperms.common.managers.AbstractManager;
import me.lucko.luckperms.common.model.Group;
+import java.util.Optional;
+
public abstract class AbstractGroupManager extends AbstractManager implements GroupManager {
@Override
@@ -40,14 +42,16 @@ public abstract class AbstractGroupManager extends AbstractMana
// then try exact display name matches
for (T group : getAll().values()) {
- if (group.getDisplayName().isPresent() && group.getDisplayName().get().equals(name)) {
+ Optional displayName = group.getDisplayName();
+ if (displayName.isPresent() && displayName.get().equals(name)) {
return group;
}
}
// then try case insensitive name matches
for (T group : getAll().values()) {
- if (group.getDisplayName().isPresent() && group.getDisplayName().get().equalsIgnoreCase(name)) {
+ Optional displayName = group.getDisplayName();
+ if (displayName.isPresent() && displayName.get().equalsIgnoreCase(name)) {
return group;
}
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/model/DisplayNameCache.java b/common/src/main/java/me/lucko/luckperms/common/model/DisplayNameCache.java
new file mode 100644
index 00000000..94dc65e7
--- /dev/null
+++ b/common/src/main/java/me/lucko/luckperms/common/model/DisplayNameCache.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of LuckPerms, licensed under the MIT License.
+ *
+ * Copyright (c) lucko (Luck)
+ * Copyright (c) contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.lucko.luckperms.common.model;
+
+import me.lucko.luckperms.api.Node;
+import me.lucko.luckperms.api.nodetype.types.DisplayNameType;
+import me.lucko.luckperms.common.buffers.Cache;
+import me.lucko.luckperms.common.config.ConfigKeys;
+
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Cache instance to supply the display name of a {@link Group}.
+ */
+public class DisplayNameCache extends Cache> {
+ private final Group group;
+
+ public DisplayNameCache(Group group) {
+ this.group = group;
+ }
+
+ @Nonnull
+ @Override
+ protected Optional supply() {
+ // query for a displayname node
+ for (Node n : this.group.getOwnNodes(this.group.getPlugin().getContextManager().getStaticContext())) {
+ Optional displayName = n.getTypeData(DisplayNameType.KEY);
+ if (displayName.isPresent()) {
+ return Optional.of(displayName.get().getDisplayName());
+ }
+ }
+
+ // fallback to config
+ String name = this.group.getPlugin().getConfiguration().get(ConfigKeys.GROUP_NAME_REWRITES).get(this.group.getObjectName());
+ return name == null || name.equals(this.group.getObjectName()) ? Optional.empty() : Optional.of(name);
+ }
+}
diff --git a/common/src/main/java/me/lucko/luckperms/common/model/Group.java b/common/src/main/java/me/lucko/luckperms/common/model/Group.java
index 2718d18c..4eed7d47 100644
--- a/common/src/main/java/me/lucko/luckperms/common/model/Group.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/Group.java
@@ -26,12 +26,12 @@
package me.lucko.luckperms.common.model;
import me.lucko.luckperms.api.Node;
-import me.lucko.luckperms.api.context.ImmutableContextSet;
+import me.lucko.luckperms.api.context.ContextSet;
+import me.lucko.luckperms.api.nodetype.types.DisplayNameType;
import me.lucko.luckperms.common.api.delegates.model.ApiGroup;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.buffers.Cache;
import me.lucko.luckperms.common.caching.GroupCachedData;
-import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Optional;
@@ -47,11 +47,15 @@ public class Group extends PermissionHolder implements Identifiable {
private final String name;
/**
- * Caches the holders weight
- * @see #getWeight()
+ * Caches the groups weight
*/
private final Cache weightCache = new WeightCache(this);
+ /**
+ * Caches the groups display name
+ */
+ private final Cache> displayNameCache = new DisplayNameCache(this);
+
/**
* The groups data cache instance
*/
@@ -77,6 +81,7 @@ public class Group extends PermissionHolder implements Identifiable {
@Override
protected void invalidateCache() {
this.weightCache.invalidate();
+ this.displayNameCache.invalidate();
super.invalidateCache();
}
@@ -104,22 +109,17 @@ public class Group extends PermissionHolder implements Identifiable {
}
public Optional getDisplayName() {
- String name = null;
- for (Node n : enduringData().immutable().get(ImmutableContextSet.empty())) {
- if (!n.getPermission().startsWith("displayname.")) {
- continue;
+ return this.displayNameCache.get();
+ }
+
+ public Optional getDisplayName(ContextSet contextSet) {
+ for (Node n : getData(NodeMapType.ENDURING).immutable().get(contextSet.makeImmutable())) {
+ Optional displayName = n.getTypeData(DisplayNameType.KEY);
+ if (displayName.isPresent()) {
+ return Optional.of(displayName.get().getDisplayName());
}
-
- name = n.getPermission().substring("displayname.".length());
- break;
}
-
- if (name != null) {
- return Optional.of(name);
- }
-
- name = getPlugin().getConfiguration().get(ConfigKeys.GROUP_NAME_REWRITES).get(getObjectName());
- return name == null || name.equals(getObjectName()) ? Optional.empty() : Optional.of(name);
+ return Optional.empty();
}
@Override
diff --git a/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java b/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java
index 7a23d0d6..6bdd19b1 100644
--- a/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/NodeMap.java
@@ -53,6 +53,7 @@ import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Predicate;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
@@ -363,6 +364,7 @@ public final class NodeMap {
this.handle = handle;
}
+ @Nonnull
@Override
protected ImmutableSetMultimap supply() {
this.handle.lock.lock();
diff --git a/common/src/main/java/me/lucko/luckperms/common/model/WeightCache.java b/common/src/main/java/me/lucko/luckperms/common/model/WeightCache.java
index a77899ce..3923de9f 100644
--- a/common/src/main/java/me/lucko/luckperms/common/model/WeightCache.java
+++ b/common/src/main/java/me/lucko/luckperms/common/model/WeightCache.java
@@ -35,8 +35,10 @@ import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
+import javax.annotation.Nonnull;
+
/**
- * Cache instance to supply the weight of a {@link PermissionHolder}.
+ * Cache instance to supply the weight of a {@link Group}.
*/
public class WeightCache extends Cache {
private final Group group;
@@ -45,6 +47,7 @@ public class WeightCache extends Cache {
this.group = group;
}
+ @Nonnull
@Override
protected OptionalInt supply() {
boolean seen = false;
diff --git a/common/src/main/java/me/lucko/luckperms/common/node/model/NodeTypes.java b/common/src/main/java/me/lucko/luckperms/common/node/model/NodeTypes.java
index 4ca128fc..af6632bf 100644
--- a/common/src/main/java/me/lucko/luckperms/common/node/model/NodeTypes.java
+++ b/common/src/main/java/me/lucko/luckperms/common/node/model/NodeTypes.java
@@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.api.nodetype.NodeType;
import me.lucko.luckperms.api.nodetype.NodeTypeKey;
+import me.lucko.luckperms.api.nodetype.types.DisplayNameType;
import me.lucko.luckperms.api.nodetype.types.InheritanceType;
import me.lucko.luckperms.api.nodetype.types.MetaType;
import me.lucko.luckperms.api.nodetype.types.PrefixType;
@@ -51,12 +52,14 @@ public final class NodeTypes {
public static final String SUFFIX_KEY = "suffix";
public static final String META_KEY = "meta";
public static final String WEIGHT_KEY = "weight";
+ public static final String DISPLAY_NAME_KEY = "displayname";
public static final String GROUP_NODE_MARKER = "group.";
public static final String PREFIX_NODE_MARKER = PREFIX_KEY + ".";
public static final String SUFFIX_NODE_MARKER = SUFFIX_KEY + ".";
public static final String META_NODE_MARKER = META_KEY + ".";
public static final String WEIGHT_NODE_MARKER = WEIGHT_KEY + ".";
+ public static final String DISPLAY_NAME_NODE_MARKER = DISPLAY_NAME_KEY + ".";
// used to split prefix/suffix/meta nodes
private static final Splitter META_SPLITTER = Splitter.on(PatternCache.compileDelimiterPattern(".", "\\")).limit(2);
@@ -89,6 +92,11 @@ public final class NodeTypes {
results.put(WeightType.KEY, type);
}
+ type = parseDisplayNameType(s);
+ if (type != null) {
+ results.put(DisplayNameType.KEY, type);
+ }
+
if (results.isEmpty()) {
return ImmutableMap.of();
}
@@ -182,6 +190,14 @@ public final class NodeTypes {
}
}
+ private static DisplayNameType parseDisplayNameType(String s) {
+ if (!s.toLowerCase().startsWith(DISPLAY_NAME_NODE_MARKER)) {
+ return null;
+ }
+
+ return new DisplayName(s.substring(DISPLAY_NAME_NODE_MARKER.length()));
+ }
+
private static final class Inheritance implements InheritanceType {
private final String groupName;
@@ -408,6 +424,38 @@ public final class NodeTypes {
}
}
+ private static final class DisplayName implements DisplayNameType {
+ private final String displayName;
+
+ private DisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ @Nonnull
+ @Override
+ public String getDisplayName() {
+ return this.displayName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DisplayName that = (DisplayName) o;
+ return Objects.equals(this.displayName, that.displayName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.displayName);
+ }
+
+ @Override
+ public String toString() {
+ return "DisplayName{displayName='" + this.displayName + '\'' + '}';
+ }
+ }
+
private NodeTypes() {}
}
diff --git a/common/src/main/java/me/lucko/luckperms/common/primarygroup/CachedPrimaryGroupHolder.java b/common/src/main/java/me/lucko/luckperms/common/primarygroup/CachedPrimaryGroupHolder.java
index b55f81de..a718754a 100644
--- a/common/src/main/java/me/lucko/luckperms/common/primarygroup/CachedPrimaryGroupHolder.java
+++ b/common/src/main/java/me/lucko/luckperms/common/primarygroup/CachedPrimaryGroupHolder.java
@@ -30,6 +30,8 @@ import me.lucko.luckperms.common.caching.handlers.StateListener;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.factory.NodeFactory;
+import javax.annotation.Nonnull;
+
/**
* Abstract implementation of {@link StateListener} which caches all lookups.
*/
@@ -37,6 +39,7 @@ public abstract class CachedPrimaryGroupHolder extends StoredHolder implements S
// cache lookups
private final Cache cache = new Cache() {
+ @Nonnull
@Override
protected String supply() {
return calculateValue();