mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-11-30 22:53:27 +01:00
Refactor meta stacking to be mapped in MetaCache - towards lucko/LuckPermsPlaceholders#1
This commit is contained in:
parent
99c6fe20c2
commit
dc801464ef
@ -41,6 +41,7 @@ import me.lucko.luckperms.common.commands.sender.Sender;
|
|||||||
import me.lucko.luckperms.common.core.NodeFactory;
|
import me.lucko.luckperms.common.core.NodeFactory;
|
||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.core.model.User;
|
import me.lucko.luckperms.common.core.model.User;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.common.utils.Predicates;
|
import me.lucko.luckperms.common.utils.Predicates;
|
||||||
import me.lucko.luckperms.common.utils.ProgressLogger;
|
import me.lucko.luckperms.common.utils.ProgressLogger;
|
||||||
@ -224,7 +225,8 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (meta.getKey().equalsIgnoreCase("prefix") || meta.getKey().equalsIgnoreCase("suffix")) {
|
if (meta.getKey().equalsIgnoreCase("prefix") || meta.getKey().equalsIgnoreCase("suffix")) {
|
||||||
holder.setPermission(NodeFactory.makeChatMetaNode(meta.getKey().equalsIgnoreCase("prefix"), c.getPriority(), meta.getValue()).setWorld(world.getName()).build());
|
MetaType type = MetaType.valueOf(meta.getKey().toUpperCase());
|
||||||
|
holder.setPermission(NodeFactory.makeChatMetaNode(type, c.getPriority(), meta.getValue()).setWorld(world.getName()).build());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ import me.lucko.luckperms.common.commands.impl.migration.MigrationUtils;
|
|||||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||||
import me.lucko.luckperms.common.constants.Permission;
|
import me.lucko.luckperms.common.constants.Permission;
|
||||||
import me.lucko.luckperms.common.core.NodeFactory;
|
import me.lucko.luckperms.common.core.NodeFactory;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.common.utils.Predicates;
|
import me.lucko.luckperms.common.utils.Predicates;
|
||||||
import me.lucko.luckperms.common.utils.ProgressLogger;
|
import me.lucko.luckperms.common.utils.ProgressLogger;
|
||||||
@ -172,7 +173,8 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key.equals("prefix") || key.equals("suffix")) {
|
if (key.equals("prefix") || key.equals("suffix")) {
|
||||||
groups.get(groupName).add(NodeFactory.makeChatMetaNode(key.equals("prefix"), 50, value).setWorld(worldMappingFunc.apply(world)).build());
|
MetaType type = MetaType.valueOf(key.toUpperCase());
|
||||||
|
groups.get(groupName).add(NodeFactory.makeChatMetaNode(type, 50, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||||
} else {
|
} else {
|
||||||
groups.get(groupName).add(NodeFactory.makeMetaNode(key, value).setWorld(worldMappingFunc.apply(world)).build());
|
groups.get(groupName).add(NodeFactory.makeMetaNode(key, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||||
}
|
}
|
||||||
@ -228,7 +230,8 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key.equals("prefix") || key.equals("suffix")) {
|
if (key.equals("prefix") || key.equals("suffix")) {
|
||||||
users.get(uuid).add(NodeFactory.makeChatMetaNode(key.equals("prefix"), 100, value).setWorld(worldMappingFunc.apply(world)).build());
|
MetaType type = MetaType.valueOf(key.toUpperCase());
|
||||||
|
users.get(uuid).add(NodeFactory.makeChatMetaNode(type, 100, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||||
} else {
|
} else {
|
||||||
users.get(uuid).add(NodeFactory.makeMetaNode(key, value).setWorld(worldMappingFunc.apply(world)).build());
|
users.get(uuid).add(NodeFactory.makeMetaNode(key, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ import me.lucko.luckperms.common.core.model.Group;
|
|||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.core.model.Track;
|
import me.lucko.luckperms.common.core.model.Track;
|
||||||
import me.lucko.luckperms.common.core.model.User;
|
import me.lucko.luckperms.common.core.model.User;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.common.utils.Predicates;
|
import me.lucko.luckperms.common.utils.Predicates;
|
||||||
import me.lucko.luckperms.common.utils.ProgressLogger;
|
import me.lucko.luckperms.common.utils.ProgressLogger;
|
||||||
@ -213,7 +214,8 @@ public class MigrationZPermissions extends SubCommand<Object> {
|
|||||||
String key = metadata.getName().toLowerCase();
|
String key = metadata.getName().toLowerCase();
|
||||||
|
|
||||||
if (key.equals("prefix") || key.equals("suffix")) {
|
if (key.equals("prefix") || key.equals("suffix")) {
|
||||||
holder.setPermission(NodeFactory.makeChatMetaNode(key.equals("prefix"), weight, metadata.getStringValue()).build());
|
MetaType type = MetaType.valueOf(key.toUpperCase());
|
||||||
|
holder.setPermission(NodeFactory.makeChatMetaNode(type, weight, metadata.getStringValue()).build());
|
||||||
} else {
|
} else {
|
||||||
holder.setPermission(NodeFactory.makeMetaNode(key, metadata.getStringValue()).build());
|
holder.setPermission(NodeFactory.makeMetaNode(key, metadata.getStringValue()).build());
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import me.lucko.luckperms.common.core.NodeFactory;
|
|||||||
import me.lucko.luckperms.common.core.model.Group;
|
import me.lucko.luckperms.common.core.model.Group;
|
||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.core.model.User;
|
import me.lucko.luckperms.common.core.model.User;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||||
|
|
||||||
import net.milkbowl.vault.chat.Chat;
|
import net.milkbowl.vault.chat.Chat;
|
||||||
@ -83,23 +84,23 @@ public class VaultChatHook extends Chat {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setChatMeta(boolean prefix, PermissionHolder holder, String value, String world) {
|
private void setChatMeta(MetaType type, PermissionHolder holder, String value, String world) {
|
||||||
String finalWorld = perms.isIgnoreWorld() ? null : world;
|
String finalWorld = perms.isIgnoreWorld() ? null : world;
|
||||||
if (holder == null) return;
|
if (holder == null) return;
|
||||||
if (value.equals("")) return;
|
if (value.equals("")) return;
|
||||||
|
|
||||||
perms.log("Setting " + (prefix ? "prefix" : "suffix") + " for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
perms.log("Setting " + type.name().toLowerCase() + " for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
||||||
|
|
||||||
perms.getScheduler().execute(() -> {
|
perms.getScheduler().execute(() -> {
|
||||||
// remove all prefixes/suffixes directly set on the user/group
|
// remove all prefixes/suffixes directly set on the user/group
|
||||||
holder.removeIf(n -> prefix ? n.isPrefix() : n.isSuffix());
|
holder.removeIf(type::matches);
|
||||||
|
|
||||||
// find the max inherited priority & add 10
|
// find the max inherited priority & add 10
|
||||||
MetaAccumulator metaAccumulator = holder.accumulateMeta(null, null, ExtractedContexts.generate(perms.createContextForWorldSet(finalWorld)));
|
MetaAccumulator metaAccumulator = holder.accumulateMeta(null, null, ExtractedContexts.generate(perms.createContextForWorldSet(finalWorld)));
|
||||||
int priority = (prefix ? metaAccumulator.getPrefixes() : metaAccumulator.getSuffixes()).keySet().stream()
|
int priority = (type == MetaType.PREFIX ? metaAccumulator.getPrefixes() : metaAccumulator.getSuffixes()).keySet().stream()
|
||||||
.mapToInt(e -> e).max().orElse(0) + 10;
|
.mapToInt(e -> e).max().orElse(0) + 10;
|
||||||
|
|
||||||
Node.Builder chatMetaNode = NodeFactory.makeChatMetaNode(prefix, priority, value);
|
Node.Builder chatMetaNode = NodeFactory.makeChatMetaNode(type, priority, value);
|
||||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||||
chatMetaNode.setServer(perms.getServer());
|
chatMetaNode.setServer(perms.getServer());
|
||||||
}
|
}
|
||||||
@ -122,14 +123,14 @@ public class VaultChatHook extends Chat {
|
|||||||
return ret != null ? ret : defaultValue;
|
return ret != null ? ret : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUserChatMeta(boolean prefix, User user, String world) {
|
private String getUserChatMeta(MetaType type, User user, String world) {
|
||||||
if (user == null) return "";
|
if (user == null) return "";
|
||||||
world = perms.isIgnoreWorld() ? null : world;
|
world = perms.isIgnoreWorld() ? null : world;
|
||||||
|
|
||||||
perms.log("Getting " + (prefix ? "prefix" : "suffix") + " for user " + user.getFriendlyName() + " on world " + world + ", server " + perms.getServer());
|
perms.log("Getting " + type.name().toLowerCase() + " for user " + user.getFriendlyName() + " on world " + world + ", server " + perms.getServer());
|
||||||
|
|
||||||
MetaData data = user.getUserData().getMetaData(perms.createContextForWorldLookup(perms.getPlugin().getPlayer(user), world));
|
MetaData data = user.getUserData().getMetaData(perms.createContextForWorldLookup(perms.getPlugin().getPlayer(user), world));
|
||||||
String ret = prefix ? data.getPrefix() : data.getSuffix();
|
String ret = type == MetaType.PREFIX ? data.getPrefix() : data.getSuffix();
|
||||||
return ret != null ? ret : "";
|
return ret != null ? ret : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,11 +154,11 @@ public class VaultChatHook extends Chat {
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getGroupChatMeta(boolean prefix, Group group, String world) {
|
private String getGroupChatMeta(MetaType type, Group group, String world) {
|
||||||
world = perms.isIgnoreWorld() ? null : world;
|
world = perms.isIgnoreWorld() ? null : world;
|
||||||
if (group == null) return "";
|
if (group == null) return "";
|
||||||
|
|
||||||
perms.log("Getting " + (prefix ? "prefix" : "suffix") + " for group " + group + " on world " + world + ", server " + perms.getServer());
|
perms.log("Getting " + type.name().toLowerCase() + " for group " + group + " on world " + world + ", server " + perms.getServer());
|
||||||
|
|
||||||
int priority = Integer.MIN_VALUE;
|
int priority = Integer.MIN_VALUE;
|
||||||
String meta = null;
|
String meta = null;
|
||||||
@ -165,10 +166,10 @@ public class VaultChatHook extends Chat {
|
|||||||
ExtractedContexts ec = ExtractedContexts.generate(Contexts.of(perms.createContextForWorldLookup(world).getContexts(), perms.isIncludeGlobal(), true, true, true, true, false));
|
ExtractedContexts ec = ExtractedContexts.generate(Contexts.of(perms.createContextForWorldLookup(world).getContexts(), perms.isIncludeGlobal(), true, true, true, true, false));
|
||||||
for (Node n : group.getAllNodes(ec)) {
|
for (Node n : group.getAllNodes(ec)) {
|
||||||
if (!n.getValue()) continue;
|
if (!n.getValue()) continue;
|
||||||
if (prefix ? !n.isPrefix() : !n.isSuffix()) continue;
|
if (type.shouldIgnore(n)) continue;
|
||||||
if (!n.shouldApplyWithContext(perms.createContextForWorldLookup(world).getContexts())) continue;
|
if (!n.shouldApplyWithContext(perms.createContextForWorldLookup(world).getContexts())) continue;
|
||||||
|
|
||||||
Map.Entry<Integer, String> value = prefix ? n.getPrefix() : n.getSuffix();
|
Map.Entry<Integer, String> value = type.getEntry(n);
|
||||||
if (value.getKey() > priority) {
|
if (value.getKey() > priority) {
|
||||||
meta = value.getValue();
|
meta = value.getValue();
|
||||||
priority = value.getKey();
|
priority = value.getKey();
|
||||||
@ -181,49 +182,49 @@ public class VaultChatHook extends Chat {
|
|||||||
@Override
|
@Override
|
||||||
public String getPlayerPrefix(String world, @NonNull String player) {
|
public String getPlayerPrefix(String world, @NonNull String player) {
|
||||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||||
return getUserChatMeta(true, user, world);
|
return getUserChatMeta(MetaType.PREFIX, user, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPlayerPrefix(String world, @NonNull String player, @NonNull String prefix) {
|
public void setPlayerPrefix(String world, @NonNull String player, @NonNull String prefix) {
|
||||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||||
setChatMeta(true, user, prefix, world);
|
setChatMeta(MetaType.PREFIX, user, prefix, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPlayerSuffix(String world, @NonNull String player) {
|
public String getPlayerSuffix(String world, @NonNull String player) {
|
||||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||||
return getUserChatMeta(false, user, world);
|
return getUserChatMeta(MetaType.SUFFIX, user, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPlayerSuffix(String world, @NonNull String player, @NonNull String suffix) {
|
public void setPlayerSuffix(String world, @NonNull String player, @NonNull String suffix) {
|
||||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||||
setChatMeta(false, user, suffix, world);
|
setChatMeta(MetaType.SUFFIX, user, suffix, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getGroupPrefix(String world, @NonNull String group) {
|
public String getGroupPrefix(String world, @NonNull String group) {
|
||||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||||
return getGroupChatMeta(true, g, world);
|
return getGroupChatMeta(MetaType.PREFIX, g, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
|
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
|
||||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||||
setChatMeta(true, g, prefix, world);
|
setChatMeta(MetaType.PREFIX, g, prefix, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getGroupSuffix(String world, @NonNull String group) {
|
public String getGroupSuffix(String world, @NonNull String group) {
|
||||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||||
return getGroupChatMeta(false, g, world);
|
return getGroupChatMeta(MetaType.SUFFIX, g, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
|
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
|
||||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||||
setChatMeta(false, g, suffix, world);
|
setChatMeta(MetaType.SUFFIX, g, suffix, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,10 +27,14 @@ package me.lucko.luckperms.common.caching;
|
|||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
import me.lucko.luckperms.api.LocalizedNode;
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStack;
|
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaStack;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -44,6 +48,12 @@ import java.util.TreeMap;
|
|||||||
@Getter
|
@Getter
|
||||||
@ToString
|
@ToString
|
||||||
public class MetaAccumulator {
|
public class MetaAccumulator {
|
||||||
|
public static MetaAccumulator makeFromConfig(LuckPermsPlugin plugin) {
|
||||||
|
return new MetaAccumulator(
|
||||||
|
plugin.getConfiguration().get(ConfigKeys.PREFIX_FORMATTING_OPTIONS).newStack(MetaType.PREFIX),
|
||||||
|
plugin.getConfiguration().get(ConfigKeys.SUFFIX_FORMATTING_OPTIONS).newStack(MetaType.SUFFIX)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Getter(AccessLevel.NONE)
|
@Getter(AccessLevel.NONE)
|
||||||
private final Map<String, String> meta;
|
private final Map<String, String> meta;
|
||||||
@ -54,7 +64,7 @@ public class MetaAccumulator {
|
|||||||
private final MetaStack prefixStack;
|
private final MetaStack prefixStack;
|
||||||
private final MetaStack suffixStack;
|
private final MetaStack suffixStack;
|
||||||
|
|
||||||
public MetaAccumulator(MetaStack prefixStack, MetaStack suffixStack) {
|
public MetaAccumulator(@NonNull MetaStack prefixStack, @NonNull MetaStack suffixStack) {
|
||||||
this.meta = new HashMap<>();
|
this.meta = new HashMap<>();
|
||||||
this.prefixes = new TreeMap<>(Comparator.reverseOrder());
|
this.prefixes = new TreeMap<>(Comparator.reverseOrder());
|
||||||
this.suffixes = new TreeMap<>(Comparator.reverseOrder());
|
this.suffixes = new TreeMap<>(Comparator.reverseOrder());
|
||||||
@ -103,4 +113,12 @@ public class MetaAccumulator {
|
|||||||
return this.meta;
|
return this.meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<Integer, String> getChatMeta(MetaType type) {
|
||||||
|
return type == MetaType.PREFIX ? prefixes : suffixes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetaStack getStack(MetaType type) {
|
||||||
|
return type == MetaType.PREFIX ? prefixStack : suffixStack;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,7 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
import com.google.common.collect.ImmutableSortedMap;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
|
|
||||||
import me.lucko.luckperms.api.caching.MetaData;
|
import me.lucko.luckperms.api.caching.MetaData;
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStack;
|
import me.lucko.luckperms.common.metastacking.MetaStack;
|
||||||
import me.lucko.luckperms.common.caching.stacking.NoopMetaStack;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
@ -57,10 +56,10 @@ public class MetaCache implements MetaData {
|
|||||||
private SortedMap<Integer, String> suffixes = ImmutableSortedMap.of();
|
private SortedMap<Integer, String> suffixes = ImmutableSortedMap.of();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private MetaStack prefixStack = NoopMetaStack.INSTANCE;
|
private MetaStack prefixStack = null;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private MetaStack suffixStack = NoopMetaStack.INSTANCE;
|
private MetaStack suffixStack = null;
|
||||||
|
|
||||||
public void loadMeta(MetaAccumulator meta) {
|
public void loadMeta(MetaAccumulator meta) {
|
||||||
lock.writeLock().lock();
|
lock.writeLock().lock();
|
||||||
@ -79,7 +78,7 @@ public class MetaCache implements MetaData {
|
|||||||
public String getPrefix() {
|
public String getPrefix() {
|
||||||
lock.readLock().lock();
|
lock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
return prefixStack.toFormattedString();
|
return prefixStack == null ? null : prefixStack.toFormattedString();
|
||||||
} finally {
|
} finally {
|
||||||
lock.readLock().unlock();
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
@ -89,7 +88,7 @@ public class MetaCache implements MetaData {
|
|||||||
public String getSuffix() {
|
public String getSuffix() {
|
||||||
lock.readLock().lock();
|
lock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
return suffixStack.toFormattedString();
|
return suffixStack == null ? null : suffixStack.toFormattedString();
|
||||||
} finally {
|
} finally {
|
||||||
lock.readLock().unlock();
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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.caching;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import me.lucko.luckperms.api.Contexts;
|
||||||
|
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
|
import me.lucko.luckperms.common.metastacking.definition.MetaStackDefinition;
|
||||||
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public final class MetaContexts {
|
||||||
|
public static MetaContexts makeFromConfig(Contexts contexts, LuckPermsPlugin plugin) {
|
||||||
|
return new MetaContexts(
|
||||||
|
contexts,
|
||||||
|
plugin.getConfiguration().get(ConfigKeys.PREFIX_FORMATTING_OPTIONS),
|
||||||
|
plugin.getConfiguration().get(ConfigKeys.SUFFIX_FORMATTING_OPTIONS)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Contexts contexts;
|
||||||
|
private final MetaStackDefinition prefixStackDefinition;
|
||||||
|
private final MetaStackDefinition suffixStackDefinition;
|
||||||
|
|
||||||
|
public MetaContexts(@NonNull Contexts contexts, @NonNull MetaStackDefinition prefixStackDefinition, @NonNull MetaStackDefinition suffixStackDefinition) {
|
||||||
|
this.contexts = contexts;
|
||||||
|
this.prefixStackDefinition = prefixStackDefinition;
|
||||||
|
this.suffixStackDefinition = suffixStackDefinition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetaAccumulator newAccumulator() {
|
||||||
|
return new MetaAccumulator(
|
||||||
|
prefixStackDefinition.newStack(MetaType.PREFIX),
|
||||||
|
suffixStackDefinition.newStack(MetaType.SUFFIX)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -69,17 +69,17 @@ public class UserCache implements UserData {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
private final LoadingCache<Contexts, MetaCache> meta = Caffeine.newBuilder()
|
private final LoadingCache<MetaContexts, MetaCache> meta = Caffeine.newBuilder()
|
||||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||||
.build(new CacheLoader<Contexts, MetaCache>() {
|
.build(new CacheLoader<MetaContexts, MetaCache>() {
|
||||||
@Override
|
@Override
|
||||||
public MetaCache load(Contexts contexts) {
|
public MetaCache load(MetaContexts contexts) {
|
||||||
return calculateMeta(contexts);
|
return calculateMeta(contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaCache reload(Contexts contexts, MetaCache oldData) {
|
public MetaCache reload(MetaContexts contexts, MetaCache oldData) {
|
||||||
oldData.loadMeta(user.accumulateMeta(null, null, ExtractedContexts.generate(contexts)));
|
oldData.loadMeta(user.accumulateMeta(contexts.newAccumulator(), null, ExtractedContexts.generate(contexts.getContexts())));
|
||||||
return oldData;
|
return oldData;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -91,6 +91,11 @@ public class UserCache implements UserData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaData getMetaData(@NonNull Contexts contexts) {
|
public MetaData getMetaData(@NonNull Contexts contexts) {
|
||||||
|
// just create a MetaContexts instance using the values in the config
|
||||||
|
return getMetaData(MetaContexts.makeFromConfig(contexts, user.getPlugin()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetaData getMetaData(@NonNull MetaContexts contexts) {
|
||||||
return meta.get(contexts);
|
return meta.get(contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,8 +108,13 @@ public class UserCache implements UserData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaCache calculateMeta(@NonNull Contexts contexts) {
|
public MetaCache calculateMeta(@NonNull Contexts contexts) {
|
||||||
|
// just create a MetaContexts instance using the values in the config
|
||||||
|
return calculateMeta(MetaContexts.makeFromConfig(contexts, user.getPlugin()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetaCache calculateMeta(@NonNull MetaContexts contexts) {
|
||||||
MetaCache data = new MetaCache();
|
MetaCache data = new MetaCache();
|
||||||
data.loadMeta(user.accumulateMeta(null, null, ExtractedContexts.generate(contexts)));
|
data.loadMeta(user.accumulateMeta(contexts.newAccumulator(), null, ExtractedContexts.generate(contexts.getContexts())));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +125,10 @@ public class UserCache implements UserData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recalculateMeta(@NonNull Contexts contexts) {
|
public void recalculateMeta(@NonNull Contexts contexts) {
|
||||||
|
recalculateMeta(MetaContexts.makeFromConfig(contexts, user.getPlugin()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recalculateMeta(@NonNull MetaContexts contexts) {
|
||||||
meta.refresh(contexts);
|
meta.refresh(contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +140,7 @@ public class UserCache implements UserData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recalculateMeta() {
|
public void recalculateMeta() {
|
||||||
Set<Contexts> keys = ImmutableSet.copyOf(meta.asMap().keySet());
|
Set<MetaContexts> keys = ImmutableSet.copyOf(meta.asMap().keySet());
|
||||||
keys.forEach(meta::refresh);
|
keys.forEach(meta::refresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +152,7 @@ public class UserCache implements UserData {
|
|||||||
@Override
|
@Override
|
||||||
public void preCalculate(@NonNull Contexts contexts) {
|
public void preCalculate(@NonNull Contexts contexts) {
|
||||||
permission.get(contexts);
|
permission.get(contexts);
|
||||||
meta.get(contexts);
|
meta.get(MetaContexts.makeFromConfig(contexts, user.getPlugin()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidateCache() {
|
public void invalidateCache() {
|
||||||
|
@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.caching.stacking;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
|
||||||
import me.lucko.luckperms.api.Node;
|
|
||||||
import me.lucko.luckperms.common.core.model.Track;
|
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public interface MetaStackElement {
|
|
||||||
|
|
||||||
Optional<Map.Entry<Integer, String>> getEntry();
|
|
||||||
|
|
||||||
boolean accumulateNode(LocalizedNode node);
|
|
||||||
|
|
||||||
MetaStackElement copy();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the types do not match
|
|
||||||
* @param expectingPrefix if the method is expecting a prefix
|
|
||||||
* @param node the node to check
|
|
||||||
* @return true if the accumulation should return
|
|
||||||
*/
|
|
||||||
static boolean checkMetaType(boolean expectingPrefix, Node node) {
|
|
||||||
if (expectingPrefix) {
|
|
||||||
if (!node.isPrefix()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!node.isSuffix()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the node is not held by a user
|
|
||||||
* @param node the node to check
|
|
||||||
* @return true if the accumulation should return
|
|
||||||
*/
|
|
||||||
static boolean checkOwnElement(LocalizedNode node) {
|
|
||||||
if (node.getLocation() == null || node.getLocation().equals("")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
UUID.fromString(node.getLocation());
|
|
||||||
return false;
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the node is not held by a group on the track
|
|
||||||
* @param node the node to check
|
|
||||||
* @param track the track
|
|
||||||
* @return true if the accumulation should return
|
|
||||||
*/
|
|
||||||
static boolean checkTrackElement(LuckPermsPlugin plugin, LocalizedNode node, String track) {
|
|
||||||
if (node.getLocation() == null || node.getLocation().equals("")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Track t = plugin.getTrackManager().getIfLoaded(track);
|
|
||||||
return t == null || !t.containsGroup(node.getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the node is held by a group on the track
|
|
||||||
* @param node the node to check
|
|
||||||
* @param track the track
|
|
||||||
* @return true if the accumulation should return
|
|
||||||
*/
|
|
||||||
static boolean checkNotTrackElement(LuckPermsPlugin plugin, LocalizedNode node, String track) {
|
|
||||||
// it's not come from a group on this track (from the user directly)
|
|
||||||
if (node.getLocation() == null || node.getLocation().equals("")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Track t = plugin.getTrackManager().getIfLoaded(track);
|
|
||||||
return t == null || t.containsGroup(node.getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.caching.stacking;
|
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.elements.HighestPriorityElement;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.elements.HighestPriorityNotOnTrackElement;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.elements.HighestPriorityOwnElement;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.elements.HighestPriorityTrackElement;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.elements.LowestPriorityElement;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.elements.LowestPriorityNotOnTrackElement;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.elements.LowestPriorityOwnElement;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.elements.LowestPriorityTrackElement;
|
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
|
||||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class StackElementFactory {
|
|
||||||
|
|
||||||
public static Optional<MetaStackElement> fromString(LuckPermsPlugin plugin, String s, boolean prefix) {
|
|
||||||
s = s.toLowerCase();
|
|
||||||
|
|
||||||
if (s.equals("highest")) {
|
|
||||||
return Optional.of(new HighestPriorityElement(prefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.equals("lowest")) {
|
|
||||||
return Optional.of(new LowestPriorityElement(prefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.equals("highest_own")) {
|
|
||||||
return Optional.of(new HighestPriorityOwnElement(prefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.equals("lowest_own")) {
|
|
||||||
return Optional.of(new LowestPriorityOwnElement(prefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.startsWith("highest_on_track_") && s.length() > "highest_on_track_".length()) {
|
|
||||||
String track = s.substring("highest_on_track_".length());
|
|
||||||
return Optional.of(new HighestPriorityTrackElement(prefix, plugin, track));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.startsWith("lowest_on_track_") && s.length() > "lowest_on_track_".length()) {
|
|
||||||
String track = s.substring("lowest_on_track_".length());
|
|
||||||
return Optional.of(new LowestPriorityTrackElement(prefix, plugin, track));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.startsWith("highest_not_on_track_") && s.length() > "highest_not_on_track_".length()) {
|
|
||||||
String track = s.substring("highest_not_on_track_".length());
|
|
||||||
return Optional.of(new HighestPriorityNotOnTrackElement(prefix, plugin, track));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.startsWith("lowest_not_on_track_") && s.length() > "lowest_not_on_track_".length()) {
|
|
||||||
String track = s.substring("lowest_not_on_track_".length());
|
|
||||||
return Optional.of(new LowestPriorityNotOnTrackElement(prefix, plugin, track));
|
|
||||||
}
|
|
||||||
|
|
||||||
new IllegalArgumentException("Cannot parse MetaStackElement: " + s).printStackTrace();
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<MetaStackElement> fromList(LuckPermsPlugin plugin, List<String> strings, boolean prefix) {
|
|
||||||
return strings.stream().map(s -> fromString(plugin, s, prefix)).filter(Optional::isPresent).map(Optional::get).collect(ImmutableCollectors.toImmutableList());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.caching.stacking.elements;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class HighestPriorityElement implements MetaStackElement {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the current node has the greater priority
|
|
||||||
* @param current the current entry
|
|
||||||
* @param newEntry the new entry
|
|
||||||
* @return true if the accumulation should return
|
|
||||||
*/
|
|
||||||
public static boolean compareEntries(Map.Entry<Integer, String> current, Map.Entry<Integer, String> newEntry) {
|
|
||||||
return current != null && current.getKey() >= newEntry.getKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final boolean prefix;
|
|
||||||
private Map.Entry<Integer, String> entry = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<Map.Entry<Integer, String>> getEntry() {
|
|
||||||
return Optional.ofNullable(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accumulateNode(LocalizedNode node) {
|
|
||||||
if (MetaStackElement.checkMetaType(prefix, node)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
|
|
||||||
if (compareEntries(this.entry, entry)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entry = entry;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MetaStackElement copy() {
|
|
||||||
return new HighestPriorityElement(prefix);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.caching.stacking.elements;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
|
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class HighestPriorityNotOnTrackElement implements MetaStackElement {
|
|
||||||
private final boolean prefix;
|
|
||||||
private final LuckPermsPlugin plugin;
|
|
||||||
private final String trackName;
|
|
||||||
|
|
||||||
private Map.Entry<Integer, String> entry = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<Map.Entry<Integer, String>> getEntry() {
|
|
||||||
return Optional.ofNullable(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accumulateNode(LocalizedNode node) {
|
|
||||||
if (MetaStackElement.checkMetaType(prefix, node)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
|
|
||||||
if (HighestPriorityElement.compareEntries(this.entry, entry)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MetaStackElement.checkNotTrackElement(plugin, node, trackName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entry = entry;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MetaStackElement copy() {
|
|
||||||
return new HighestPriorityNotOnTrackElement(prefix, plugin, trackName);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.caching.stacking.elements;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
|
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class HighestPriorityTrackElement implements MetaStackElement {
|
|
||||||
private final boolean prefix;
|
|
||||||
private final LuckPermsPlugin plugin;
|
|
||||||
private final String trackName;
|
|
||||||
|
|
||||||
private Map.Entry<Integer, String> entry = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<Map.Entry<Integer, String>> getEntry() {
|
|
||||||
return Optional.ofNullable(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accumulateNode(LocalizedNode node) {
|
|
||||||
if (MetaStackElement.checkMetaType(prefix, node)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
|
|
||||||
if (HighestPriorityElement.compareEntries(this.entry, entry)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MetaStackElement.checkTrackElement(plugin, node, trackName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entry = entry;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MetaStackElement copy() {
|
|
||||||
return new HighestPriorityTrackElement(prefix, plugin, trackName);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.caching.stacking.elements;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class LowestPriorityElement implements MetaStackElement {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the current node has the lesser priority
|
|
||||||
* @param current the current entry
|
|
||||||
* @param newEntry the new entry
|
|
||||||
* @return true if the accumulation should return
|
|
||||||
*/
|
|
||||||
public static boolean compareEntries(Map.Entry<Integer, String> current, Map.Entry<Integer, String> newEntry) {
|
|
||||||
return current != null && current.getKey() <= newEntry.getKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final boolean prefix;
|
|
||||||
private Map.Entry<Integer, String> entry = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<Map.Entry<Integer, String>> getEntry() {
|
|
||||||
return Optional.ofNullable(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accumulateNode(LocalizedNode node) {
|
|
||||||
if (MetaStackElement.checkMetaType(prefix, node)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
|
|
||||||
if (compareEntries(this.entry, entry)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entry = entry;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MetaStackElement copy() {
|
|
||||||
return new LowestPriorityElement(prefix);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.caching.stacking.elements;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
|
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class LowestPriorityNotOnTrackElement implements MetaStackElement {
|
|
||||||
private final boolean prefix;
|
|
||||||
private final LuckPermsPlugin plugin;
|
|
||||||
private final String trackName;
|
|
||||||
|
|
||||||
private Map.Entry<Integer, String> entry = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<Map.Entry<Integer, String>> getEntry() {
|
|
||||||
return Optional.ofNullable(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accumulateNode(LocalizedNode node) {
|
|
||||||
if (MetaStackElement.checkMetaType(prefix, node)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
|
|
||||||
if (LowestPriorityElement.compareEntries(this.entry, entry)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MetaStackElement.checkNotTrackElement(plugin, node, trackName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entry = entry;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MetaStackElement copy() {
|
|
||||||
return new LowestPriorityNotOnTrackElement(prefix, plugin, trackName);
|
|
||||||
}
|
|
||||||
}
|
|
@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import me.lucko.luckperms.common.commands.abstraction.SharedMainCommand;
|
import me.lucko.luckperms.common.commands.abstraction.SharedMainCommand;
|
||||||
import me.lucko.luckperms.common.commands.abstraction.SharedSubCommand;
|
import me.lucko.luckperms.common.commands.abstraction.SharedSubCommand;
|
||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
|
|
||||||
public class CommandMeta<T extends PermissionHolder> extends SharedMainCommand<T> {
|
public class CommandMeta<T extends PermissionHolder> extends SharedMainCommand<T> {
|
||||||
public CommandMeta(boolean user) {
|
public CommandMeta(boolean user) {
|
||||||
@ -39,14 +40,14 @@ public class CommandMeta<T extends PermissionHolder> extends SharedMainCommand<T
|
|||||||
.add(new MetaUnset())
|
.add(new MetaUnset())
|
||||||
.add(new MetaSetTemp())
|
.add(new MetaSetTemp())
|
||||||
.add(new MetaUnsetTemp())
|
.add(new MetaUnsetTemp())
|
||||||
.add(new MetaAddChatMeta(true))
|
.add(new MetaAddChatMeta(MetaType.PREFIX))
|
||||||
.add(new MetaAddChatMeta(false))
|
.add(new MetaAddChatMeta(MetaType.SUFFIX))
|
||||||
.add(new MetaRemoveChatMeta(true))
|
.add(new MetaRemoveChatMeta(MetaType.PREFIX))
|
||||||
.add(new MetaRemoveChatMeta(false))
|
.add(new MetaRemoveChatMeta(MetaType.SUFFIX))
|
||||||
.add(new MetaAddTempChatMeta(true))
|
.add(new MetaAddTempChatMeta(MetaType.PREFIX))
|
||||||
.add(new MetaAddTempChatMeta(false))
|
.add(new MetaAddTempChatMeta(MetaType.SUFFIX))
|
||||||
.add(new MetaRemoveTempChatMeta(true))
|
.add(new MetaRemoveTempChatMeta(MetaType.PREFIX))
|
||||||
.add(new MetaRemoveTempChatMeta(false))
|
.add(new MetaRemoveTempChatMeta(MetaType.SUFFIX))
|
||||||
.add(new MetaClear())
|
.add(new MetaClear())
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
@ -39,30 +39,29 @@ import me.lucko.luckperms.common.constants.Permission;
|
|||||||
import me.lucko.luckperms.common.core.NodeFactory;
|
import me.lucko.luckperms.common.core.NodeFactory;
|
||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.data.LogEntry;
|
import me.lucko.luckperms.common.data.LogEntry;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.common.utils.Predicates;
|
import me.lucko.luckperms.common.utils.Predicates;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class MetaAddChatMeta extends SharedSubCommand {
|
public class MetaAddChatMeta extends SharedSubCommand {
|
||||||
private static final Function<Boolean, String> DESCRIPTOR = b -> b ? "prefix" : "suffix";
|
private final MetaType type;
|
||||||
private final boolean isPrefix;
|
|
||||||
|
|
||||||
public MetaAddChatMeta(boolean isPrefix) {
|
public MetaAddChatMeta(MetaType type) {
|
||||||
super("add" + DESCRIPTOR.apply(isPrefix),
|
super("add" + type.name().toLowerCase(),
|
||||||
"Adds a " + DESCRIPTOR.apply(isPrefix),
|
"Adds a " + type.name().toLowerCase(),
|
||||||
isPrefix ? Permission.USER_META_ADDPREFIX : Permission.USER_META_ADDSUFFIX,
|
type == MetaType.PREFIX ? Permission.USER_META_ADDPREFIX : Permission.USER_META_ADDSUFFIX,
|
||||||
isPrefix ? Permission.GROUP_META_ADDPREFIX : Permission.GROUP_META_ADDSUFFIX,
|
type == MetaType.PREFIX ? Permission.GROUP_META_ADDPREFIX : Permission.GROUP_META_ADDSUFFIX,
|
||||||
Predicates.inRange(0, 1),
|
Predicates.inRange(0, 1),
|
||||||
Arg.list(
|
Arg.list(
|
||||||
Arg.create("priority", true, "the priority to add the " + DESCRIPTOR.apply(isPrefix) + " at"),
|
Arg.create("priority", true, "the priority to add the " + type.name().toLowerCase() + " at"),
|
||||||
Arg.create(DESCRIPTOR.apply(isPrefix), true, "the " + DESCRIPTOR.apply(isPrefix) + " string"),
|
Arg.create(type.name().toLowerCase(), true, "the " + type.name().toLowerCase() + " string"),
|
||||||
Arg.create("context...", false, "the contexts to add the " + DESCRIPTOR.apply(isPrefix) + " in")
|
Arg.create("context...", false, "the contexts to add the " + type.name().toLowerCase() + " in")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
this.isPrefix = isPrefix;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -71,18 +70,18 @@ public class MetaAddChatMeta extends SharedSubCommand {
|
|||||||
String meta = ArgumentUtils.handleString(1, args);
|
String meta = ArgumentUtils.handleString(1, args);
|
||||||
MutableContextSet context = ArgumentUtils.handleContext(2, args, plugin);
|
MutableContextSet context = ArgumentUtils.handleContext(2, args, plugin);
|
||||||
|
|
||||||
DataMutateResult result = holder.setPermission(NodeFactory.makeChatMetaNode(isPrefix, priority, meta).withExtraContext(context).build());
|
DataMutateResult result = holder.setPermission(NodeFactory.makeChatMetaNode(type, priority, meta).withExtraContext(context).build());
|
||||||
if (result.asBoolean()) {
|
if (result.asBoolean()) {
|
||||||
Message.ADD_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix), meta, priority, Util.contextSetToString(context));
|
Message.ADD_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), type.name().toLowerCase(), meta, priority, Util.contextSetToString(context));
|
||||||
|
|
||||||
LogEntry.build().actor(sender).acted(holder)
|
LogEntry.build().actor(sender).acted(holder)
|
||||||
.action("meta add" + DESCRIPTOR.apply(isPrefix) + " " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
.action("meta add" + type.name().toLowerCase() + " " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||||
.build().submit(plugin, sender);
|
.build().submit(plugin, sender);
|
||||||
|
|
||||||
save(holder, sender, plugin);
|
save(holder, sender, plugin);
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
Message.ALREADY_HAS_CHAT_META.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix));
|
Message.ALREADY_HAS_CHAT_META.send(sender, holder.getFriendlyName(), type.name().toLowerCase());
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,33 +42,32 @@ import me.lucko.luckperms.common.core.NodeFactory;
|
|||||||
import me.lucko.luckperms.common.core.TemporaryModifier;
|
import me.lucko.luckperms.common.core.TemporaryModifier;
|
||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.data.LogEntry;
|
import me.lucko.luckperms.common.data.LogEntry;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.common.utils.DateUtil;
|
import me.lucko.luckperms.common.utils.DateUtil;
|
||||||
import me.lucko.luckperms.common.utils.Predicates;
|
import me.lucko.luckperms.common.utils.Predicates;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class MetaAddTempChatMeta extends SharedSubCommand {
|
public class MetaAddTempChatMeta extends SharedSubCommand {
|
||||||
private static final Function<Boolean, String> DESCRIPTOR = b -> b ? "prefix" : "suffix";
|
private final MetaType type;
|
||||||
private final boolean isPrefix;
|
|
||||||
|
|
||||||
public MetaAddTempChatMeta(boolean isPrefix) {
|
public MetaAddTempChatMeta(MetaType type) {
|
||||||
super("addtemp" + DESCRIPTOR.apply(isPrefix),
|
super("addtemp" + type.name().toLowerCase(),
|
||||||
"Adds a " + DESCRIPTOR.apply(isPrefix) + " temporarily",
|
"Adds a " + type.name().toLowerCase() + " temporarily",
|
||||||
isPrefix ? Permission.USER_META_ADDTEMP_PREFIX : Permission.USER_META_ADDTEMP_SUFFIX,
|
type == MetaType.PREFIX ? Permission.USER_META_ADDTEMP_PREFIX : Permission.USER_META_ADDTEMP_SUFFIX,
|
||||||
isPrefix ? Permission.GROUP_META_ADDTEMP_PREFIX : Permission.GROUP_META_ADDTEMP_SUFFIX,
|
type == MetaType.PREFIX ? Permission.GROUP_META_ADDTEMP_PREFIX : Permission.GROUP_META_ADDTEMP_SUFFIX,
|
||||||
Predicates.inRange(0, 2),
|
Predicates.inRange(0, 2),
|
||||||
Arg.list(
|
Arg.list(
|
||||||
Arg.create("priority", true, "the priority to add the " + DESCRIPTOR.apply(isPrefix) + " at"),
|
Arg.create("priority", true, "the priority to add the " + type.name().toLowerCase() + " at"),
|
||||||
Arg.create(DESCRIPTOR.apply(isPrefix), true, "the " + DESCRIPTOR.apply(isPrefix) + " string"),
|
Arg.create(type.name().toLowerCase(), true, "the " + type.name().toLowerCase() + " string"),
|
||||||
Arg.create("duration", true, "the duration until the " + DESCRIPTOR.apply(isPrefix) + " expires"),
|
Arg.create("duration", true, "the duration until the " + type.name().toLowerCase() + " expires"),
|
||||||
Arg.create("context...", false, "the contexts to add the " + DESCRIPTOR.apply(isPrefix) + " in")
|
Arg.create("context...", false, "the contexts to add the " + type.name().toLowerCase() + " in")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
this.isPrefix = isPrefix;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -79,21 +78,21 @@ public class MetaAddTempChatMeta extends SharedSubCommand {
|
|||||||
MutableContextSet context = ArgumentUtils.handleContext(3, args, plugin);
|
MutableContextSet context = ArgumentUtils.handleContext(3, args, plugin);
|
||||||
TemporaryModifier modifier = plugin.getConfiguration().get(ConfigKeys.TEMPORARY_ADD_BEHAVIOUR);
|
TemporaryModifier modifier = plugin.getConfiguration().get(ConfigKeys.TEMPORARY_ADD_BEHAVIOUR);
|
||||||
|
|
||||||
Map.Entry<DataMutateResult, Node> ret = holder.setPermission(NodeFactory.makeChatMetaNode(isPrefix, priority, meta).setExpiry(duration).withExtraContext(context).build(), modifier);
|
Map.Entry<DataMutateResult, Node> ret = holder.setPermission(NodeFactory.makeChatMetaNode(type, priority, meta).setExpiry(duration).withExtraContext(context).build(), modifier);
|
||||||
|
|
||||||
if (ret.getKey().asBoolean()) {
|
if (ret.getKey().asBoolean()) {
|
||||||
duration = ret.getValue().getExpiryUnixTime();
|
duration = ret.getValue().getExpiryUnixTime();
|
||||||
|
|
||||||
Message.ADD_TEMP_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix), meta, priority, DateUtil.formatDateDiff(duration), Util.contextSetToString(context));
|
Message.ADD_TEMP_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), type.name().toLowerCase(), meta, priority, DateUtil.formatDateDiff(duration), Util.contextSetToString(context));
|
||||||
|
|
||||||
LogEntry.build().actor(sender).acted(holder)
|
LogEntry.build().actor(sender).acted(holder)
|
||||||
.action("meta addtemp" + DESCRIPTOR.apply(isPrefix) + " " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
.action("meta addtemp" + type.name().toLowerCase() + " " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||||
.build().submit(plugin, sender);
|
.build().submit(plugin, sender);
|
||||||
|
|
||||||
save(holder, sender, plugin);
|
save(holder, sender, plugin);
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
Message.ALREADY_HAS_CHAT_META.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix));
|
Message.ALREADY_HAS_CHAT_META.send(sender, holder.getFriendlyName(), type.name().toLowerCase());
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,30 +39,29 @@ import me.lucko.luckperms.common.constants.Permission;
|
|||||||
import me.lucko.luckperms.common.core.NodeFactory;
|
import me.lucko.luckperms.common.core.NodeFactory;
|
||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.data.LogEntry;
|
import me.lucko.luckperms.common.data.LogEntry;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.common.utils.Predicates;
|
import me.lucko.luckperms.common.utils.Predicates;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class MetaRemoveChatMeta extends SharedSubCommand {
|
public class MetaRemoveChatMeta extends SharedSubCommand {
|
||||||
private static final Function<Boolean, String> DESCRIPTOR = b -> b ? "prefix" : "suffix";
|
private final MetaType type;
|
||||||
private final boolean isPrefix;
|
|
||||||
|
|
||||||
public MetaRemoveChatMeta(boolean isPrefix) {
|
public MetaRemoveChatMeta(MetaType type) {
|
||||||
super("remove" + DESCRIPTOR.apply(isPrefix),
|
super("remove" + type.name().toLowerCase(),
|
||||||
"Removes a " + DESCRIPTOR.apply(isPrefix),
|
"Removes a " + type.name().toLowerCase(),
|
||||||
isPrefix ? Permission.USER_META_REMOVEPREFIX : Permission.USER_META_REMOVESUFFIX,
|
type == MetaType.PREFIX ? Permission.USER_META_REMOVEPREFIX : Permission.USER_META_REMOVESUFFIX,
|
||||||
isPrefix ? Permission.GROUP_META_REMOVEPREFIX : Permission.GROUP_META_REMOVESUFFIX,
|
type == MetaType.PREFIX ? Permission.GROUP_META_REMOVEPREFIX : Permission.GROUP_META_REMOVESUFFIX,
|
||||||
Predicates.is(0),
|
Predicates.is(0),
|
||||||
Arg.list(
|
Arg.list(
|
||||||
Arg.create("priority", true, "the priority to remove the " + DESCRIPTOR.apply(isPrefix) + " at"),
|
Arg.create("priority", true, "the priority to remove the " + type.name().toLowerCase() + " at"),
|
||||||
Arg.create(DESCRIPTOR.apply(isPrefix), false, "the " + DESCRIPTOR.apply(isPrefix) + " string"),
|
Arg.create(type.name().toLowerCase(), false, "the " + type.name().toLowerCase() + " string"),
|
||||||
Arg.create("context...", false, "the contexts to remove the " + DESCRIPTOR.apply(isPrefix) + " in")
|
Arg.create("context...", false, "the contexts to remove the " + type.name().toLowerCase() + " in")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
this.isPrefix = isPrefix;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -74,29 +73,29 @@ public class MetaRemoveChatMeta extends SharedSubCommand {
|
|||||||
// Handle bulk removal
|
// Handle bulk removal
|
||||||
if (meta.equalsIgnoreCase("null") || meta.equals("*")) {
|
if (meta.equalsIgnoreCase("null") || meta.equals("*")) {
|
||||||
holder.removeIf(n ->
|
holder.removeIf(n ->
|
||||||
(isPrefix ? n.isPrefix() : n.isSuffix()) &&
|
type.matches(n) &&
|
||||||
(isPrefix ? n.getPrefix() : n.getSuffix()).getKey() == priority &&
|
type.getEntry(n).getKey() == priority &&
|
||||||
!n.isTemporary() &&
|
!n.isTemporary() &&
|
||||||
n.getFullContexts().makeImmutable().equals(context.makeImmutable())
|
n.getFullContexts().makeImmutable().equals(context.makeImmutable())
|
||||||
);
|
);
|
||||||
Message.BULK_REMOVE_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix), priority, Util.contextSetToString(context));
|
Message.BULK_REMOVE_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), type.name().toLowerCase(), priority, Util.contextSetToString(context));
|
||||||
save(holder, sender, plugin);
|
save(holder, sender, plugin);
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataMutateResult result = holder.unsetPermission(NodeFactory.makeChatMetaNode(isPrefix, priority, meta).withExtraContext(context).build());
|
DataMutateResult result = holder.unsetPermission(NodeFactory.makeChatMetaNode(type, priority, meta).withExtraContext(context).build());
|
||||||
|
|
||||||
if (result.asBoolean()) {
|
if (result.asBoolean()) {
|
||||||
Message.REMOVE_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix), meta, priority, Util.contextSetToString(context));
|
Message.REMOVE_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), type.name().toLowerCase(), meta, priority, Util.contextSetToString(context));
|
||||||
|
|
||||||
LogEntry.build().actor(sender).acted(holder)
|
LogEntry.build().actor(sender).acted(holder)
|
||||||
.action("meta remove" + DESCRIPTOR.apply(isPrefix) + " " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
.action("meta remove" + type.name().toLowerCase() + " " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||||
.build().submit(plugin, sender);
|
.build().submit(plugin, sender);
|
||||||
|
|
||||||
save(holder, sender, plugin);
|
save(holder, sender, plugin);
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
Message.DOES_NOT_HAVE_CHAT_META.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix));
|
Message.DOES_NOT_HAVE_CHAT_META.send(sender, holder.getFriendlyName(), type.name().toLowerCase());
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,30 +39,29 @@ import me.lucko.luckperms.common.constants.Permission;
|
|||||||
import me.lucko.luckperms.common.core.NodeFactory;
|
import me.lucko.luckperms.common.core.NodeFactory;
|
||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.data.LogEntry;
|
import me.lucko.luckperms.common.data.LogEntry;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
import me.lucko.luckperms.common.utils.Predicates;
|
import me.lucko.luckperms.common.utils.Predicates;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class MetaRemoveTempChatMeta extends SharedSubCommand {
|
public class MetaRemoveTempChatMeta extends SharedSubCommand {
|
||||||
private static final Function<Boolean, String> DESCRIPTOR = b -> b ? "prefix" : "suffix";
|
private final MetaType type;
|
||||||
private final boolean isPrefix;
|
|
||||||
|
|
||||||
public MetaRemoveTempChatMeta(boolean isPrefix) {
|
public MetaRemoveTempChatMeta(MetaType type) {
|
||||||
super("removetemp" + DESCRIPTOR.apply(isPrefix),
|
super("removetemp" +type.name().toLowerCase(),
|
||||||
"Removes a temporary " + DESCRIPTOR.apply(isPrefix),
|
"Removes a temporary " + type.name().toLowerCase(),
|
||||||
isPrefix ? Permission.USER_META_REMOVETEMP_PREFIX : Permission.USER_META_REMOVETEMP_SUFFIX,
|
type == MetaType.PREFIX ? Permission.USER_META_REMOVETEMP_PREFIX : Permission.USER_META_REMOVETEMP_SUFFIX,
|
||||||
isPrefix ? Permission.GROUP_META_REMOVETEMP_PREFIX : Permission.GROUP_META_REMOVETEMP_SUFFIX,
|
type == MetaType.PREFIX ? Permission.GROUP_META_REMOVETEMP_PREFIX : Permission.GROUP_META_REMOVETEMP_SUFFIX,
|
||||||
Predicates.is(0),
|
Predicates.is(0),
|
||||||
Arg.list(
|
Arg.list(
|
||||||
Arg.create("priority", true, "the priority to remove the " + DESCRIPTOR.apply(isPrefix) + " at"),
|
Arg.create("priority", true, "the priority to remove the " + type.name().toLowerCase() + " at"),
|
||||||
Arg.create(DESCRIPTOR.apply(isPrefix), false, "the " + DESCRIPTOR.apply(isPrefix) + " string"),
|
Arg.create(type.name().toLowerCase(), false, "the " +type.name().toLowerCase() + " string"),
|
||||||
Arg.create("context...", false, "the contexts to remove the " + DESCRIPTOR.apply(isPrefix) + " in")
|
Arg.create("context...", false, "the contexts to remove the " + type.name().toLowerCase() + " in")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
this.isPrefix = isPrefix;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -74,29 +73,29 @@ public class MetaRemoveTempChatMeta extends SharedSubCommand {
|
|||||||
// Handle bulk removal
|
// Handle bulk removal
|
||||||
if (meta.equalsIgnoreCase("null") || meta.equals("*")) {
|
if (meta.equalsIgnoreCase("null") || meta.equals("*")) {
|
||||||
holder.removeIf(n ->
|
holder.removeIf(n ->
|
||||||
(isPrefix ? n.isPrefix() : n.isSuffix()) &&
|
type.matches(n) &&
|
||||||
(isPrefix ? n.getPrefix() : n.getSuffix()).getKey() == priority &&
|
type.getEntry(n).getKey() == priority &&
|
||||||
!n.isPermanent() &&
|
!n.isPermanent() &&
|
||||||
n.getFullContexts().makeImmutable().equals(context.makeImmutable())
|
n.getFullContexts().makeImmutable().equals(context.makeImmutable())
|
||||||
);
|
);
|
||||||
Message.BULK_REMOVE_TEMP_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix), priority, Util.contextSetToString(context));
|
Message.BULK_REMOVE_TEMP_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), type.name().toLowerCase(), priority, Util.contextSetToString(context));
|
||||||
save(holder, sender, plugin);
|
save(holder, sender, plugin);
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataMutateResult result = holder.unsetPermission(NodeFactory.makeChatMetaNode(isPrefix, priority, meta).setExpiry(10L).withExtraContext(context).build());
|
DataMutateResult result = holder.unsetPermission(NodeFactory.makeChatMetaNode(type, priority, meta).setExpiry(10L).withExtraContext(context).build());
|
||||||
|
|
||||||
if (result.asBoolean()) {
|
if (result.asBoolean()) {
|
||||||
Message.REMOVE_TEMP_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix), meta, priority, Util.contextSetToString(context));
|
Message.REMOVE_TEMP_CHATMETA_SUCCESS.send(sender, holder.getFriendlyName(), type.name().toLowerCase(), meta, priority, Util.contextSetToString(context));
|
||||||
|
|
||||||
LogEntry.build().actor(sender).acted(holder)
|
LogEntry.build().actor(sender).acted(holder)
|
||||||
.action("meta removetemp" + DESCRIPTOR.apply(isPrefix) + " " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
.action("meta removetemp" + type.name().toLowerCase() + " " + args.stream().map(ArgumentUtils.WRAPPER).collect(Collectors.joining(" ")))
|
||||||
.build().submit(plugin, sender);
|
.build().submit(plugin, sender);
|
||||||
|
|
||||||
save(holder, sender, plugin);
|
save(holder, sender, plugin);
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
Message.DOES_NOT_HAVE_CHAT_META.send(sender, holder.getFriendlyName(), DESCRIPTOR.apply(isPrefix));
|
Message.DOES_NOT_HAVE_CHAT_META.send(sender, holder.getFriendlyName(), type.name().toLowerCase());
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,6 @@ import lombok.experimental.UtilityClass;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.GenericMetaStack;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.StackElementFactory;
|
|
||||||
import me.lucko.luckperms.common.config.keys.AbstractKey;
|
import me.lucko.luckperms.common.config.keys.AbstractKey;
|
||||||
import me.lucko.luckperms.common.config.keys.BooleanKey;
|
import me.lucko.luckperms.common.config.keys.BooleanKey;
|
||||||
import me.lucko.luckperms.common.config.keys.EnduringKey;
|
import me.lucko.luckperms.common.config.keys.EnduringKey;
|
||||||
@ -43,6 +41,8 @@ import me.lucko.luckperms.common.config.keys.StringKey;
|
|||||||
import me.lucko.luckperms.common.core.TemporaryModifier;
|
import me.lucko.luckperms.common.core.TemporaryModifier;
|
||||||
import me.lucko.luckperms.common.core.model.User;
|
import me.lucko.luckperms.common.core.model.User;
|
||||||
import me.lucko.luckperms.common.defaults.Rule;
|
import me.lucko.luckperms.common.defaults.Rule;
|
||||||
|
import me.lucko.luckperms.common.metastacking.definition.MetaStackDefinition;
|
||||||
|
import me.lucko.luckperms.common.metastacking.definition.StandardStackElements;
|
||||||
import me.lucko.luckperms.common.primarygroup.AllParentsByWeightHolder;
|
import me.lucko.luckperms.common.primarygroup.AllParentsByWeightHolder;
|
||||||
import me.lucko.luckperms.common.primarygroup.ParentsByWeightHolder;
|
import me.lucko.luckperms.common.primarygroup.ParentsByWeightHolder;
|
||||||
import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder;
|
import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder;
|
||||||
@ -216,9 +216,9 @@ public class ConfigKeys {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new prefix MetaStack element based upon the configured values. Be aware that this instance should be copied for each unique user.
|
* Creates a new prefix MetaStack element based upon the configured values.
|
||||||
*/
|
*/
|
||||||
public static final ConfigKey<GenericMetaStack> PREFIX_FORMATTING_OPTIONS = AbstractKey.of(l -> {
|
public static final ConfigKey<MetaStackDefinition> PREFIX_FORMATTING_OPTIONS = AbstractKey.of(l -> {
|
||||||
List<String> format = l.getList("meta-formatting.prefix.format", new ArrayList<>());
|
List<String> format = l.getList("meta-formatting.prefix.format", new ArrayList<>());
|
||||||
if (format.isEmpty()) {
|
if (format.isEmpty()) {
|
||||||
format.add("highest");
|
format.add("highest");
|
||||||
@ -227,13 +227,13 @@ public class ConfigKeys {
|
|||||||
String middleSpacer = l.getString("meta-formatting.prefix.middle-spacer", " ");
|
String middleSpacer = l.getString("meta-formatting.prefix.middle-spacer", " ");
|
||||||
String endSpacer = l.getString("meta-formatting.prefix.end-spacer", "");
|
String endSpacer = l.getString("meta-formatting.prefix.end-spacer", "");
|
||||||
|
|
||||||
return new GenericMetaStack(StackElementFactory.fromList(l.getPlugin(), format, true), startSpacer, middleSpacer, endSpacer);
|
return MetaStackDefinition.create(StandardStackElements.parseList(l.getPlugin(), format), startSpacer, middleSpacer, endSpacer);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new suffix MetaStack element based upon the configured values. Be aware that this instance should be copied for each unique user.
|
* Creates a new suffix MetaStack element based upon the configured values.
|
||||||
*/
|
*/
|
||||||
public static final ConfigKey<GenericMetaStack> SUFFIX_FORMATTING_OPTIONS = AbstractKey.of(l -> {
|
public static final ConfigKey<MetaStackDefinition> SUFFIX_FORMATTING_OPTIONS = AbstractKey.of(l -> {
|
||||||
List<String> format = l.getList("meta-formatting.suffix.format", new ArrayList<>());
|
List<String> format = l.getList("meta-formatting.suffix.format", new ArrayList<>());
|
||||||
if (format.isEmpty()) {
|
if (format.isEmpty()) {
|
||||||
format.add("highest");
|
format.add("highest");
|
||||||
@ -242,7 +242,7 @@ public class ConfigKeys {
|
|||||||
String middleSpacer = l.getString("meta-formatting.suffix.middle-spacer", " ");
|
String middleSpacer = l.getString("meta-formatting.suffix.middle-spacer", " ");
|
||||||
String endSpacer = l.getString("meta-formatting.suffix.end-spacer", "");
|
String endSpacer = l.getString("meta-formatting.suffix.end-spacer", "");
|
||||||
|
|
||||||
return new GenericMetaStack(StackElementFactory.fromList(l.getPlugin(), format, false), startSpacer, middleSpacer, endSpacer);
|
return MetaStackDefinition.create(StandardStackElements.parseList(l.getPlugin(), format), startSpacer, middleSpacer, endSpacer);
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,6 +35,7 @@ import me.lucko.luckperms.api.MetaUtils;
|
|||||||
import me.lucko.luckperms.api.Node;
|
import me.lucko.luckperms.api.Node;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.core.model.Group;
|
import me.lucko.luckperms.common.core.model.Group;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.utils.PatternCache;
|
import me.lucko.luckperms.common.utils.PatternCache;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -122,8 +123,8 @@ public class NodeFactory {
|
|||||||
return new NodeBuilder("meta." + MetaUtils.escapeCharacters(key) + "." + MetaUtils.escapeCharacters(value));
|
return new NodeBuilder("meta." + MetaUtils.escapeCharacters(key) + "." + MetaUtils.escapeCharacters(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Node.Builder makeChatMetaNode(boolean prefix, int priority, String s) {
|
public static Node.Builder makeChatMetaNode(MetaType type, int priority, String s) {
|
||||||
return prefix ? makePrefixNode(priority, s) : makeSuffixNode(priority, s);
|
return type == MetaType.PREFIX ? makePrefixNode(priority, s) : makeSuffixNode(priority, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Node.Builder makePrefixNode(int priority, String prefix) {
|
public static Node.Builder makePrefixNode(int priority, String prefix) {
|
||||||
|
@ -663,10 +663,7 @@ public abstract class PermissionHolder {
|
|||||||
|
|
||||||
public MetaAccumulator accumulateMeta(MetaAccumulator accumulator, Set<String> excludedGroups, ExtractedContexts context) {
|
public MetaAccumulator accumulateMeta(MetaAccumulator accumulator, Set<String> excludedGroups, ExtractedContexts context) {
|
||||||
if (accumulator == null) {
|
if (accumulator == null) {
|
||||||
accumulator = new MetaAccumulator(
|
accumulator = MetaAccumulator.makeFromConfig(plugin);
|
||||||
plugin.getConfiguration().get(ConfigKeys.PREFIX_FORMATTING_OPTIONS).copy(),
|
|
||||||
plugin.getConfiguration().get(ConfigKeys.SUFFIX_FORMATTING_OPTIONS).copy()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (excludedGroups == null) {
|
if (excludedGroups == null) {
|
||||||
|
@ -23,28 +23,38 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.common.caching.stacking;
|
package me.lucko.luckperms.common.metastacking;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
|
import me.lucko.luckperms.api.LocalizedNode;
|
||||||
|
import me.lucko.luckperms.common.metastacking.definition.MetaStackDefinition;
|
||||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class GenericMetaStack implements MetaStack {
|
public class GenericMetaStack implements MetaStack {
|
||||||
|
|
||||||
private final List<MetaStackElement> elements;
|
private final MetaStackDefinition definition;
|
||||||
private final String startSpacer;
|
private final MetaType targetType;
|
||||||
private final String middleSpacer;
|
|
||||||
private final String endSpacer;
|
@Getter(AccessLevel.NONE)
|
||||||
|
private final List<MetaStackEntry> entries;
|
||||||
|
|
||||||
|
public GenericMetaStack(MetaStackDefinition definition, MetaType targetType) {
|
||||||
|
this.definition = definition;
|
||||||
|
this.targetType = targetType;
|
||||||
|
this.entries = definition.getElements().stream()
|
||||||
|
.map(element -> new SimpleMetaStackEntry(this, element, targetType))
|
||||||
|
.collect(ImmutableCollectors.toImmutableList());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toFormattedString() {
|
public String toFormattedString() {
|
||||||
List<MetaStackElement> ret = new ArrayList<>(elements);
|
List<MetaStackEntry> ret = new ArrayList<>(entries);
|
||||||
ret.removeIf(m -> !m.getEntry().isPresent());
|
ret.removeIf(m -> !m.getEntry().isPresent());
|
||||||
|
|
||||||
if (ret.isEmpty()) {
|
if (ret.isEmpty()) {
|
||||||
@ -52,27 +62,22 @@ public class GenericMetaStack implements MetaStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(startSpacer);
|
sb.append(definition.getStartSpacer());
|
||||||
for (int i = 0; i < ret.size(); i++) {
|
for (int i = 0; i < ret.size(); i++) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
sb.append(middleSpacer);
|
sb.append(definition.getMiddleSpacer());
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaStackElement e = ret.get(i);
|
MetaStackEntry e = ret.get(i);
|
||||||
sb.append(e.getEntry().get().getValue());
|
sb.append(e.getEntry().get().getValue());
|
||||||
}
|
}
|
||||||
sb.append(endSpacer);
|
sb.append(definition.getEndSpacer());
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaStack copy() {
|
public void accumulateToAll(LocalizedNode node) {
|
||||||
return new GenericMetaStack(
|
entries.forEach(e -> e.accumulateNode(node));
|
||||||
elements.stream().map(MetaStackElement::copy).collect(ImmutableCollectors.toImmutableList()),
|
|
||||||
startSpacer,
|
|
||||||
middleSpacer,
|
|
||||||
endSpacer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,20 +23,19 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.common.caching.stacking;
|
package me.lucko.luckperms.common.metastacking;
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
import me.lucko.luckperms.api.LocalizedNode;
|
||||||
|
import me.lucko.luckperms.common.metastacking.definition.MetaStackDefinition;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface MetaStack {
|
public interface MetaStack {
|
||||||
|
|
||||||
List<MetaStackElement> getElements();
|
MetaStackDefinition getDefinition();
|
||||||
|
|
||||||
|
MetaType getTargetType();
|
||||||
|
|
||||||
String toFormattedString();
|
String toFormattedString();
|
||||||
MetaStack copy();
|
|
||||||
|
|
||||||
default void accumulateToAll(LocalizedNode node) {
|
void accumulateToAll(LocalizedNode node);
|
||||||
getElements().forEach(m -> m.accumulateNode(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -23,26 +23,22 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.common.caching.stacking;
|
package me.lucko.luckperms.common.metastacking;
|
||||||
|
|
||||||
import java.util.Collections;
|
import me.lucko.luckperms.api.LocalizedNode;
|
||||||
import java.util.List;
|
import me.lucko.luckperms.common.metastacking.definition.MetaStackElement;
|
||||||
|
|
||||||
public class NoopMetaStack implements MetaStack {
|
import java.util.Map;
|
||||||
public static final NoopMetaStack INSTANCE = new NoopMetaStack();
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface MetaStackEntry {
|
||||||
|
|
||||||
|
MetaStack getParentStack();
|
||||||
|
|
||||||
|
MetaStackElement getElement();
|
||||||
|
|
||||||
|
Optional<Map.Entry<Integer, String>> getEntry();
|
||||||
|
|
||||||
|
boolean accumulateNode(LocalizedNode node);
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<MetaStackElement> getElements() {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toFormattedString() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MetaStack copy() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -23,51 +23,52 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.common.caching.stacking.elements;
|
package me.lucko.luckperms.common.metastacking;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import me.lucko.luckperms.api.Node;
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
|
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
public enum MetaType {
|
||||||
public class LowestPriorityTrackElement implements MetaStackElement {
|
|
||||||
private final boolean prefix;
|
|
||||||
private final LuckPermsPlugin plugin;
|
|
||||||
private final String trackName;
|
|
||||||
|
|
||||||
private Map.Entry<Integer, String> entry = null;
|
|
||||||
|
|
||||||
|
PREFIX {
|
||||||
@Override
|
@Override
|
||||||
public Optional<Map.Entry<Integer, String>> getEntry() {
|
public boolean matches(Node node) {
|
||||||
return Optional.ofNullable(entry);
|
return node.isPrefix();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accumulateNode(LocalizedNode node) {
|
public boolean shouldIgnore(Node node) {
|
||||||
if (MetaStackElement.checkMetaType(prefix, node)) {
|
return !node.isPrefix();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
|
|
||||||
if (LowestPriorityElement.compareEntries(this.entry, entry)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MetaStackElement.checkTrackElement(plugin, node, trackName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entry = entry;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaStackElement copy() {
|
public Map.Entry<Integer, String> getEntry(Node node) {
|
||||||
return new LowestPriorityTrackElement(prefix, plugin, trackName);
|
return node.getPrefix();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
SUFFIX {
|
||||||
|
@Override
|
||||||
|
public boolean matches(Node node) {
|
||||||
|
return node.isSuffix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldIgnore(Node node) {
|
||||||
|
return !node.isSuffix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map.Entry<Integer, String> getEntry(Node node) {
|
||||||
|
return node.getSuffix();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public abstract boolean matches(Node node);
|
||||||
|
|
||||||
|
public abstract boolean shouldIgnore(Node node);
|
||||||
|
|
||||||
|
public abstract Map.Entry<Integer, String> getEntry(Node node);
|
||||||
|
|
||||||
}
|
}
|
@ -23,47 +23,40 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.common.caching.stacking.elements;
|
package me.lucko.luckperms.common.metastacking;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
import me.lucko.luckperms.api.LocalizedNode;
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
|
import me.lucko.luckperms.common.metastacking.definition.MetaStackElement;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class LowestPriorityOwnElement implements MetaStackElement {
|
public class SimpleMetaStackEntry implements MetaStackEntry {
|
||||||
private final boolean prefix;
|
|
||||||
private Map.Entry<Integer, String> entry = null;
|
private final MetaStack parentStack;
|
||||||
|
private final MetaStackElement element;
|
||||||
|
private final MetaType type;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
|
private Map.Entry<Integer, String> current = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Map.Entry<Integer, String>> getEntry() {
|
public Optional<Map.Entry<Integer, String>> getEntry() {
|
||||||
return Optional.ofNullable(entry);
|
return Optional.ofNullable(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accumulateNode(LocalizedNode node) {
|
public boolean accumulateNode(LocalizedNode node) {
|
||||||
if (MetaStackElement.checkMetaType(prefix, node)) {
|
if (element.shouldAccumulate(node, type, current)) {
|
||||||
return false;
|
this.current = type.getEntry(node);
|
||||||
}
|
|
||||||
|
|
||||||
if (MetaStackElement.checkOwnElement(node)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
|
|
||||||
if (LowestPriorityElement.compareEntries(this.entry, entry)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entry = entry;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
@Override
|
|
||||||
public MetaStackElement copy() {
|
|
||||||
return new LowestPriorityOwnElement(prefix);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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.metastacking.definition;
|
||||||
|
|
||||||
|
import me.lucko.luckperms.common.metastacking.GenericMetaStack;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaStack;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface MetaStackDefinition {
|
||||||
|
|
||||||
|
static MetaStackDefinition create(List<MetaStackElement> elements, String startSpacer, String middleSpacer, String endSpacer) {
|
||||||
|
return new SimpleMetaStackDefinition(elements, startSpacer, middleSpacer, endSpacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MetaStackElement> getElements();
|
||||||
|
|
||||||
|
String getStartSpacer();
|
||||||
|
|
||||||
|
String getMiddleSpacer();
|
||||||
|
|
||||||
|
String getEndSpacer();
|
||||||
|
|
||||||
|
default MetaStack newStack(MetaType type) {
|
||||||
|
return new GenericMetaStack(this, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,48 +23,15 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.common.caching.stacking.elements;
|
package me.lucko.luckperms.common.metastacking.definition;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.LocalizedNode;
|
import me.lucko.luckperms.api.LocalizedNode;
|
||||||
import me.lucko.luckperms.common.caching.stacking.MetaStackElement;
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
public interface MetaStackElement {
|
||||||
public class HighestPriorityOwnElement implements MetaStackElement {
|
|
||||||
private final boolean prefix;
|
|
||||||
private Map.Entry<Integer, String> entry = null;
|
|
||||||
|
|
||||||
@Override
|
boolean shouldAccumulate(LocalizedNode node, MetaType type, Map.Entry<Integer, String> current);
|
||||||
public Optional<Map.Entry<Integer, String>> getEntry() {
|
|
||||||
return Optional.ofNullable(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accumulateNode(LocalizedNode node) {
|
|
||||||
if (MetaStackElement.checkMetaType(prefix, node)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MetaStackElement.checkOwnElement(node)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map.Entry<Integer, String> entry = prefix ? node.getPrefix() : node.getSuffix();
|
|
||||||
if (HighestPriorityElement.compareEntries(this.entry, entry)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entry = entry;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MetaStackElement copy() {
|
|
||||||
return new HighestPriorityOwnElement(prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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.metastacking.definition;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@ToString
|
||||||
|
final class SimpleMetaStackDefinition implements MetaStackDefinition {
|
||||||
|
|
||||||
|
private final List<MetaStackElement> elements;
|
||||||
|
private final String startSpacer;
|
||||||
|
private final String middleSpacer;
|
||||||
|
private final String endSpacer;
|
||||||
|
|
||||||
|
public SimpleMetaStackDefinition(@NonNull List<MetaStackElement> elements, @NonNull String startSpacer, @NonNull String middleSpacer, @NonNull String endSpacer) {
|
||||||
|
this.elements = ImmutableList.copyOf(elements);
|
||||||
|
this.startSpacer = startSpacer;
|
||||||
|
this.middleSpacer = middleSpacer;
|
||||||
|
this.endSpacer = endSpacer;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,298 @@
|
|||||||
|
/*
|
||||||
|
* 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.metastacking.definition;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
import me.lucko.luckperms.api.LocalizedNode;
|
||||||
|
import me.lucko.luckperms.common.core.model.Track;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
|
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class StandardStackElements {
|
||||||
|
|
||||||
|
public static Optional<MetaStackElement> parseFromString(LuckPermsPlugin plugin, String s) {
|
||||||
|
s = s.toLowerCase();
|
||||||
|
|
||||||
|
if (s.equals("highest")) {
|
||||||
|
return Optional.of(new HighestPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.equals("lowest")) {
|
||||||
|
return Optional.of(new LowestPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.equals("highest_own")) {
|
||||||
|
return Optional.of(new HighestPriorityOwn());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.equals("lowest_own")) {
|
||||||
|
return Optional.of(new LowestPriorityOwn());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.startsWith("highest_on_track_") && s.length() > "highest_on_track_".length()) {
|
||||||
|
String track = s.substring("highest_on_track_".length());
|
||||||
|
return Optional.of(new HighestPriorityTrack(plugin, track));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.startsWith("lowest_on_track_") && s.length() > "lowest_on_track_".length()) {
|
||||||
|
String track = s.substring("lowest_on_track_".length());
|
||||||
|
return Optional.of(new LowestPriorityTrack(plugin, track));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.startsWith("highest_not_on_track_") && s.length() > "highest_not_on_track_".length()) {
|
||||||
|
String track = s.substring("highest_not_on_track_".length());
|
||||||
|
return Optional.of(new HighestPriorityNotOnTrack(plugin, track));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.startsWith("lowest_not_on_track_") && s.length() > "lowest_not_on_track_".length()) {
|
||||||
|
String track = s.substring("lowest_not_on_track_".length());
|
||||||
|
return Optional.of(new LowestPriorityNotOnTrack(plugin, track));
|
||||||
|
}
|
||||||
|
|
||||||
|
new IllegalArgumentException("Cannot parse MetaStackElement: " + s).printStackTrace();
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<MetaStackElement> parseList(LuckPermsPlugin plugin, List<String> strings) {
|
||||||
|
return strings.stream()
|
||||||
|
.map(s -> parseFromString(plugin, s))
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::get)
|
||||||
|
.collect(ImmutableCollectors.toImmutableList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the current node has the greater priority
|
||||||
|
* @param current the current entry
|
||||||
|
* @param newEntry the new entry
|
||||||
|
* @return true if the accumulation should return
|
||||||
|
*/
|
||||||
|
private static boolean compareEntriesHighest(Map.Entry<Integer, String> current, Map.Entry<Integer, String> newEntry) {
|
||||||
|
return current != null && current.getKey() >= newEntry.getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the current node has the lesser priority
|
||||||
|
* @param current the current entry
|
||||||
|
* @param newEntry the new entry
|
||||||
|
* @return true if the accumulation should return
|
||||||
|
*/
|
||||||
|
private static boolean compareEntriesLowest(Map.Entry<Integer, String> current, Map.Entry<Integer, String> newEntry) {
|
||||||
|
return current != null && current.getKey() <= newEntry.getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the node is not held by a user
|
||||||
|
* @param node the node to check
|
||||||
|
* @return true if the accumulation should return
|
||||||
|
*/
|
||||||
|
private static boolean checkOwnElement(LocalizedNode node) {
|
||||||
|
if (node.getLocation() == null || node.getLocation().equals("")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
UUID.fromString(node.getLocation());
|
||||||
|
return false;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the node is not held by a group on the track
|
||||||
|
* @param node the node to check
|
||||||
|
* @param track the track
|
||||||
|
* @return true if the accumulation should return
|
||||||
|
*/
|
||||||
|
private static boolean checkTrackElement(LuckPermsPlugin plugin, LocalizedNode node, String track) {
|
||||||
|
if (node.getLocation() == null || node.getLocation().equals("")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Track t = plugin.getTrackManager().getIfLoaded(track);
|
||||||
|
return t == null || !t.containsGroup(node.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the node is held by a group on the track
|
||||||
|
* @param node the node to check
|
||||||
|
* @param track the track
|
||||||
|
* @return true if the accumulation should return
|
||||||
|
*/
|
||||||
|
private static boolean checkNotTrackElement(LuckPermsPlugin plugin, LocalizedNode node, String track) {
|
||||||
|
// it's not come from a group on this track (from the user directly)
|
||||||
|
if (node.getLocation() == null || node.getLocation().equals("")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Track t = plugin.getTrackManager().getIfLoaded(track);
|
||||||
|
return t == null || t.containsGroup(node.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
private static final class HighestPriority implements MetaStackElement {
|
||||||
|
@Override
|
||||||
|
public boolean shouldAccumulate(LocalizedNode node, MetaType type, Map.Entry<Integer, String> current) {
|
||||||
|
if (type.shouldIgnore(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> newEntry = type.getEntry(node);
|
||||||
|
return !compareEntriesHighest(current, newEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
private static final class HighestPriorityOwn implements MetaStackElement {
|
||||||
|
@Override
|
||||||
|
public boolean shouldAccumulate(LocalizedNode node, MetaType type, Map.Entry<Integer, String> current) {
|
||||||
|
if (type.shouldIgnore(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkOwnElement(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> newEntry = type.getEntry(node);
|
||||||
|
return !compareEntriesHighest(current, newEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@EqualsAndHashCode(of = "trackName")
|
||||||
|
private static final class HighestPriorityTrack implements MetaStackElement {
|
||||||
|
private final LuckPermsPlugin plugin;
|
||||||
|
private final String trackName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldAccumulate(LocalizedNode node, MetaType type, Map.Entry<Integer, String> current) {
|
||||||
|
if (type.shouldIgnore(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> newEntry = type.getEntry(node);
|
||||||
|
return !compareEntriesHighest(current, newEntry) && !checkTrackElement(plugin, node, trackName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@EqualsAndHashCode(of = "trackName")
|
||||||
|
private static final class HighestPriorityNotOnTrack implements MetaStackElement {
|
||||||
|
private final LuckPermsPlugin plugin;
|
||||||
|
private final String trackName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldAccumulate(LocalizedNode node, MetaType type, Map.Entry<Integer, String> current) {
|
||||||
|
if (type.shouldIgnore(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> newEntry = type.getEntry(node);
|
||||||
|
return !compareEntriesHighest(current, newEntry) && !checkNotTrackElement(plugin, node, trackName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
private static final class LowestPriority implements MetaStackElement {
|
||||||
|
@Override
|
||||||
|
public boolean shouldAccumulate(LocalizedNode node, MetaType type, Map.Entry<Integer, String> current) {
|
||||||
|
if (type.shouldIgnore(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> newEntry = type.getEntry(node);
|
||||||
|
return !compareEntriesLowest(current, newEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
private static final class LowestPriorityOwn implements MetaStackElement {
|
||||||
|
@Override
|
||||||
|
public boolean shouldAccumulate(LocalizedNode node, MetaType type, Map.Entry<Integer, String> current) {
|
||||||
|
if (type.shouldIgnore(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkOwnElement(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> newEntry = type.getEntry(node);
|
||||||
|
return !compareEntriesLowest(current, newEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@EqualsAndHashCode(of = "trackName")
|
||||||
|
private static final class LowestPriorityTrack implements MetaStackElement {
|
||||||
|
private final LuckPermsPlugin plugin;
|
||||||
|
private final String trackName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldAccumulate(LocalizedNode node, MetaType type, Map.Entry<Integer, String> current) {
|
||||||
|
if (type.shouldIgnore(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> entry = type.getEntry(node);
|
||||||
|
return !compareEntriesLowest(current, entry) && !checkTrackElement(plugin, node, trackName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@EqualsAndHashCode(of = "trackName")
|
||||||
|
private static final class LowestPriorityNotOnTrack implements MetaStackElement {
|
||||||
|
private final LuckPermsPlugin plugin;
|
||||||
|
private final String trackName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldAccumulate(LocalizedNode node, MetaType type, Map.Entry<Integer, String> current) {
|
||||||
|
if (type.shouldIgnore(node)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map.Entry<Integer, String> newEntry = type.getEntry(node);
|
||||||
|
return !compareEntriesLowest(current, newEntry) && !checkNotTrackElement(plugin, node, trackName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -58,9 +58,9 @@ public class SpongeSenderFactory extends SenderFactory<CommandSource> {
|
|||||||
return Constants.CONSOLE_UUID;
|
return Constants.CONSOLE_UUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
@Override
|
||||||
protected void sendMessage(CommandSource source, String s) {
|
protected void sendMessage(CommandSource source, String s) {
|
||||||
|
//noinspection deprecation
|
||||||
source.sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(s));
|
source.sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,18 @@ public class SpongeCalculatorLink implements ContextCalculator<Subject> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MutableContextSet giveApplicableContext(Subject subject, MutableContextSet accumulator) {
|
public MutableContextSet giveApplicableContext(Subject subject, MutableContextSet accumulator) {
|
||||||
Set<Context> contexts = new HashSet<>();
|
Set<Context> contexts = new HashSet<Context>() {
|
||||||
|
|
||||||
|
// don't allow null elements
|
||||||
|
@Override
|
||||||
|
public boolean add(Context context) {
|
||||||
|
if (context == null) {
|
||||||
|
throw new NullPointerException("context");
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.add(context);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
delegate.accumulateContexts(subject, contexts);
|
delegate.accumulateContexts(subject, contexts);
|
||||||
|
@ -37,6 +37,7 @@ import me.lucko.luckperms.api.Tristate;
|
|||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||||
import me.lucko.luckperms.common.caching.MetaAccumulator;
|
import me.lucko.luckperms.common.caching.MetaAccumulator;
|
||||||
import me.lucko.luckperms.common.core.model.Group;
|
import me.lucko.luckperms.common.core.model.Group;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
@ -197,10 +198,10 @@ public class SpongeGroup extends Group {
|
|||||||
try (Timing ignored = plugin.getService().getPlugin().getTimings().time(LPTiming.GROUP_GET_OPTION)) {
|
try (Timing ignored = plugin.getService().getPlugin().getTimings().time(LPTiming.GROUP_GET_OPTION)) {
|
||||||
Optional<String> option;
|
Optional<String> option;
|
||||||
if (s.equalsIgnoreCase("prefix")) {
|
if (s.equalsIgnoreCase("prefix")) {
|
||||||
option = getChatMeta(contexts, true);
|
option = getChatMeta(contexts, MetaType.PREFIX);
|
||||||
|
|
||||||
} else if (s.equalsIgnoreCase("suffix")) {
|
} else if (s.equalsIgnoreCase("suffix")) {
|
||||||
option = getChatMeta(contexts, false);
|
option = getChatMeta(contexts, MetaType.SUFFIX);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
option = getMeta(contexts, s);
|
option = getMeta(contexts, s);
|
||||||
@ -226,13 +227,9 @@ public class SpongeGroup extends Group {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> getChatMeta(ImmutableContextSet contexts, boolean prefix) {
|
private Optional<String> getChatMeta(ImmutableContextSet contexts, MetaType type) {
|
||||||
MetaAccumulator metaAccumulator = parent.accumulateMeta(null, null, ExtractedContexts.generate(plugin.getService().calculateContexts(contexts)));
|
MetaAccumulator metaAccumulator = parent.accumulateMeta(null, null, ExtractedContexts.generate(plugin.getService().calculateContexts(contexts)));
|
||||||
if (prefix) {
|
return Optional.ofNullable(metaAccumulator.getStack(type).toFormattedString());
|
||||||
return Optional.ofNullable(metaAccumulator.getPrefixStack().toFormattedString());
|
|
||||||
} else {
|
|
||||||
return Optional.ofNullable(metaAccumulator.getSuffixStack().toFormattedString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> getMeta(ImmutableContextSet contexts, String key) {
|
private Optional<String> getMeta(ImmutableContextSet contexts, String key) {
|
||||||
|
@ -41,6 +41,7 @@ import me.lucko.luckperms.common.core.NodeFactory;
|
|||||||
import me.lucko.luckperms.common.core.model.Group;
|
import me.lucko.luckperms.common.core.model.Group;
|
||||||
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
import me.lucko.luckperms.common.core.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.core.model.User;
|
import me.lucko.luckperms.common.core.model.User;
|
||||||
|
import me.lucko.luckperms.common.metastacking.MetaType;
|
||||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||||
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
||||||
@ -369,26 +370,24 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_SET_OPTION)) {
|
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_SET_OPTION)) {
|
||||||
if (key.equalsIgnoreCase("prefix") || key.equalsIgnoreCase("suffix")) {
|
if (key.equalsIgnoreCase("prefix") || key.equalsIgnoreCase("suffix")) {
|
||||||
// special handling.
|
// special handling.
|
||||||
String type = key.toLowerCase();
|
MetaType type = MetaType.valueOf(key.toUpperCase());
|
||||||
boolean prefix = type.equals("prefix");
|
|
||||||
|
|
||||||
// remove all prefixes/suffixes from the user
|
// remove all prefixes/suffixes from the user
|
||||||
List<Node> toRemove = streamNodes(enduring)
|
List<Node> toRemove = streamNodes(enduring)
|
||||||
.filter(n -> prefix ? n.isPrefix() : n.isSuffix())
|
.filter(type::matches)
|
||||||
.filter(n -> n.getFullContexts().equals(context))
|
.filter(n -> n.getFullContexts().equals(context))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
toRemove.forEach(makeUnsetConsumer(enduring));
|
toRemove.forEach(makeUnsetConsumer(enduring));
|
||||||
|
|
||||||
MetaAccumulator metaAccumulator = holder.accumulateMeta(null, null, ExtractedContexts.generate(service.calculateContexts(context)));
|
MetaAccumulator metaAccumulator = holder.accumulateMeta(null, null, ExtractedContexts.generate(service.calculateContexts(context)));
|
||||||
int priority = (type.equals("prefix") ? metaAccumulator.getPrefixes() : metaAccumulator.getSuffixes()).keySet().stream()
|
int priority = metaAccumulator.getChatMeta(type).keySet().stream().mapToInt(e -> e).max().orElse(0);
|
||||||
.mapToInt(e -> e).max().orElse(0);
|
|
||||||
priority += 10;
|
priority += 10;
|
||||||
|
|
||||||
if (enduring) {
|
if (enduring) {
|
||||||
holder.setPermission(NodeFactory.makeChatMetaNode(type.equals("prefix"), priority, value).withExtraContext(context).build());
|
holder.setPermission(NodeFactory.makeChatMetaNode(type, priority, value).withExtraContext(context).build());
|
||||||
} else {
|
} else {
|
||||||
holder.setTransientPermission(NodeFactory.makeChatMetaNode(type.equals("prefix"), priority, value).withExtraContext(context).build());
|
holder.setTransientPermission(NodeFactory.makeChatMetaNode(type, priority, value).withExtraContext(context).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user