mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-26 02:57:56 +01:00
Allow display names to be set in specific contexts (#963)
This commit is contained in:
parent
58bd7de66a
commit
f556c75d94
@ -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;
|
||||
* <li>{@link SuffixType} - represents an assigned suffix</li>
|
||||
* <li>{@link MetaType} - represents an assigned meta option</li>
|
||||
* <li>{@link WeightType} - marks the weight of the object holding this node</li>
|
||||
* <li>{@link DisplayNameType} - marks the display name of the object holding this node</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>The core node state must be immutable in all implementations.</p>
|
||||
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<DisplayNameType> KEY = new NodeTypeKey<DisplayNameType>(){};
|
||||
|
||||
/**
|
||||
* Gets the display name.
|
||||
*
|
||||
* @return the display name
|
||||
*/
|
||||
@Nonnull
|
||||
String getDisplayName();
|
||||
|
||||
}
|
@ -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 <T> the type being stored
|
||||
*/
|
||||
public abstract class Cache<T> {
|
||||
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<T> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<Group> {
|
||||
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<String> args, String label) {
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> 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<Group> {
|
||||
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);
|
||||
|
@ -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",
|
||||
|
@ -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" +
|
||||
|
@ -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<T extends Group> extends AbstractManager<String, Group, T> implements GroupManager<T> {
|
||||
|
||||
@Override
|
||||
@ -40,14 +42,16 @@ public abstract class AbstractGroupManager<T extends Group> extends AbstractMana
|
||||
|
||||
// then try exact display name matches
|
||||
for (T group : getAll().values()) {
|
||||
if (group.getDisplayName().isPresent() && group.getDisplayName().get().equals(name)) {
|
||||
Optional<String> 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<String> displayName = group.getDisplayName();
|
||||
if (displayName.isPresent() && displayName.get().equalsIgnoreCase(name)) {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<Optional<String>> {
|
||||
private final Group group;
|
||||
|
||||
public DisplayNameCache(Group group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected Optional<String> supply() {
|
||||
// query for a displayname node
|
||||
for (Node n : this.group.getOwnNodes(this.group.getPlugin().getContextManager().getStaticContext())) {
|
||||
Optional<DisplayNameType> 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);
|
||||
}
|
||||
}
|
@ -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<String> {
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Caches the holders weight
|
||||
* @see #getWeight()
|
||||
* Caches the groups weight
|
||||
*/
|
||||
private final Cache<OptionalInt> weightCache = new WeightCache(this);
|
||||
|
||||
/**
|
||||
* Caches the groups display name
|
||||
*/
|
||||
private final Cache<Optional<String>> displayNameCache = new DisplayNameCache(this);
|
||||
|
||||
/**
|
||||
* The groups data cache instance
|
||||
*/
|
||||
@ -77,6 +81,7 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
||||
@Override
|
||||
protected void invalidateCache() {
|
||||
this.weightCache.invalidate();
|
||||
this.displayNameCache.invalidate();
|
||||
super.invalidateCache();
|
||||
}
|
||||
|
||||
@ -104,22 +109,17 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
||||
}
|
||||
|
||||
public Optional<String> getDisplayName() {
|
||||
String name = null;
|
||||
for (Node n : enduringData().immutable().get(ImmutableContextSet.empty())) {
|
||||
if (!n.getPermission().startsWith("displayname.")) {
|
||||
continue;
|
||||
return this.displayNameCache.get();
|
||||
}
|
||||
|
||||
public Optional<String> getDisplayName(ContextSet contextSet) {
|
||||
for (Node n : getData(NodeMapType.ENDURING).immutable().get(contextSet.makeImmutable())) {
|
||||
Optional<DisplayNameType> 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
|
||||
|
@ -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<ImmutableContextSet, Node> supply() {
|
||||
this.handle.lock.lock();
|
||||
|
@ -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<OptionalInt> {
|
||||
private final Group group;
|
||||
@ -45,6 +47,7 @@ public class WeightCache extends Cache<OptionalInt> {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected OptionalInt supply() {
|
||||
boolean seen = false;
|
||||
|
@ -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() {}
|
||||
|
||||
}
|
||||
|
@ -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<String> cache = new Cache<String>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
protected String supply() {
|
||||
return calculateValue();
|
||||
|
Loading…
Reference in New Issue
Block a user