From 2889c288151c510913aaa1bb614e165503edebf1 Mon Sep 17 00:00:00 2001 From: Luck Date: Fri, 23 Feb 2018 15:59:12 +0000 Subject: [PATCH] Separate prefix/suffix/meta nodes into their own section within yaml/json/hocon storage files --- .../luckperms/common/node/NodeFactory.java | 4 + .../luckperms/common/node/NodeModel.java | 4 + .../storage/dao/file/ConfigurateDao.java | 248 ++++++++++++------ 3 files changed, 174 insertions(+), 82 deletions(-) diff --git a/common/src/main/java/me/lucko/luckperms/common/node/NodeFactory.java b/common/src/main/java/me/lucko/luckperms/common/node/NodeFactory.java index 45428467..a55d7838 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/NodeFactory.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/NodeFactory.java @@ -98,6 +98,10 @@ public final class NodeFactory { return GROUP_NODE_MARKER + groupName; } + public static String chatMetaNode(ChatMetaType type, int priority, String value) { + return type == ChatMetaType.PREFIX ? prefixNode(priority, value) : suffixNode(priority, value); + } + public static String prefixNode(int priority, String prefix) { return PREFIX_NODE_MARKER + priority + "." + LegacyNodeFactory.escapeCharacters(prefix); } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/NodeModel.java b/common/src/main/java/me/lucko/luckperms/common/node/NodeModel.java index 96791fb1..11d09ca4 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/NodeModel.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/NodeModel.java @@ -55,6 +55,10 @@ public final class NodeModel { return new NodeModel(permission, value, server, world, expiry, contexts); } + public static NodeModel of(String permission) { + return of(permission, true, "global", "global", 0L, ImmutableContextSet.empty()); + } + private final String permission; private final boolean value; private final String server; diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/ConfigurateDao.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/ConfigurateDao.java index 0cfebd0a..8e0c8556 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/ConfigurateDao.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/ConfigurateDao.java @@ -26,7 +26,9 @@ package me.lucko.luckperms.common.storage.dao.file; import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import me.lucko.luckperms.api.ChatMetaType; import me.lucko.luckperms.api.HeldPermission; import me.lucko.luckperms.api.LogEntry; import me.lucko.luckperms.api.Node; @@ -39,6 +41,7 @@ import me.lucko.luckperms.common.managers.track.TrackManager; import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.User; +import me.lucko.luckperms.common.node.MetaType; import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.node.NodeHeldPermission; import me.lucko.luckperms.common.node.NodeModel; @@ -69,6 +72,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.function.Function; import java.util.stream.Collectors; public abstract class ConfigurateDao extends AbstractDao { @@ -680,35 +684,35 @@ public abstract class ConfigurateDao extends AbstractDao { return this.uuidCache.lookupUsername(uuid); } - private static Collection readAttributes(ConfigurationNode entry, String permission) { - Map attributes = entry.getChildrenMap(); + private static NodeModel readAttributes(ConfigurationNode attributes, Function permissionFunction) { + boolean value = attributes.getNode("value").getBoolean(true); + String server = attributes.getNode("server").getString("global"); + String world = attributes.getNode("world").getString("global"); + long expiry = attributes.getNode("expiry").getLong(0L); - boolean value = true; - String server = "global"; - String world = "global"; - long expiry = 0L; ImmutableContextSet context = ImmutableContextSet.empty(); - - if (attributes.containsKey("value")) { - value = attributes.get("value").getBoolean(); - } - if (attributes.containsKey("server")) { - server = attributes.get("server").getString(); - } - if (attributes.containsKey("world")) { - world = attributes.get("world").getString(); - } - if (attributes.containsKey("expiry")) { - expiry = attributes.get("expiry").getLong(); + ConfigurationNode contextMap = attributes.getNode("context"); + if (!contextMap.isVirtual() && contextMap.hasMapChildren()) { + context = ContextSetConfigurateSerializer.deserializeContextSet(contextMap).makeImmutable(); } - if (attributes.containsKey("context") && attributes.get("context").hasMapChildren()) { - ConfigurationNode contexts = attributes.get("context"); - context = ContextSetConfigurateSerializer.deserializeContextSet(contexts).makeImmutable(); + return NodeModel.of(permissionFunction.apply(attributes), value, server, world, expiry, context); + } + + private static Collection readAttributes(ConfigurationNode attributes, String permission) { + boolean value = attributes.getNode("value").getBoolean(true); + String server = attributes.getNode("server").getString("global"); + String world = attributes.getNode("world").getString("global"); + long expiry = attributes.getNode("expiry").getLong(0L); + + ImmutableContextSet context = ImmutableContextSet.empty(); + ConfigurationNode contextMap = attributes.getNode("context"); + if (!contextMap.isVirtual() && contextMap.hasMapChildren()) { + context = ContextSetConfigurateSerializer.deserializeContextSet(contextMap).makeImmutable(); } - ConfigurationNode batchAttribute = attributes.get("permissions"); - if (permission.startsWith("luckperms.batch") && batchAttribute != null && batchAttribute.hasListChildren()) { + ConfigurationNode batchAttribute = attributes.getNode("permissions"); + if (permission.startsWith("luckperms.batch") && !batchAttribute.isVirtual() && batchAttribute.hasListChildren()) { List nodes = new ArrayList<>(); for (ConfigurationNode element : batchAttribute.getChildrenList()) { nodes.add(NodeModel.of(element.getString(), value, server, world, expiry, context)); @@ -719,63 +723,87 @@ public abstract class ConfigurateDao extends AbstractDao { } } + private static Map.Entry parseEntry(ConfigurationNode appended) { + if (!appended.hasMapChildren()) { + return null; + } + Map.Entry entry = Iterables.getFirst(appended.getChildrenMap().entrySet(), null); + if (entry == null || !entry.getValue().hasMapChildren()) { + return null; + } + + return Maps.immutableEntry(entry.getKey().toString(), entry.getValue()); + } + private static Set readNodes(ConfigurationNode data) { Set nodes = new HashSet<>(); if (data.getNode("permissions").hasListChildren()) { - List parts = data.getNode("permissions").getChildrenList(); - - for (ConfigurationNode ent : parts) { - String stringValue = ent.getValue(Types::strictAsString); - if (stringValue != null) { - nodes.add(NodeModel.of(stringValue, true, "global", "global", 0L, ImmutableContextSet.empty())); + List children = data.getNode("permissions").getChildrenList(); + for (ConfigurationNode appended : children) { + String plainValue = appended.getValue(Types::strictAsString); + if (plainValue != null) { + nodes.add(NodeModel.of(plainValue)); continue; } - if (!ent.hasMapChildren()) { + Map.Entry entry = parseEntry(appended); + if (entry == null) { continue; } - - Map.Entry entry = Iterables.getFirst(ent.getChildrenMap().entrySet(), null); - if (entry == null || !entry.getValue().hasMapChildren()) { - continue; - } - - String permission = entry.getKey().toString(); - nodes.addAll(readAttributes(entry.getValue(), permission)); + nodes.addAll(readAttributes(entry.getValue(), entry.getKey())); } } if (data.getNode("parents").hasListChildren()) { - List parts = data.getNode("parents").getChildrenList(); - - for (ConfigurationNode ent : parts) { - String stringValue = ent.getValue(Types::strictAsString); + List children = data.getNode("parents").getChildrenList(); + for (ConfigurationNode appended : children) { + String stringValue = appended.getValue(Types::strictAsString); if (stringValue != null) { - nodes.add(NodeModel.of(NodeFactory.groupNode(stringValue), true, "global", "global", 0L, ImmutableContextSet.empty())); + nodes.add(NodeModel.of(NodeFactory.groupNode(stringValue))); continue; } - if (!ent.hasMapChildren()) { + Map.Entry entry = parseEntry(appended); + if (entry == null) { continue; } + nodes.add(readAttributes(entry.getValue(), c -> NodeFactory.groupNode(entry.getKey()))); + } + } - Map.Entry entry = Iterables.getFirst(ent.getChildrenMap().entrySet(), null); - if (entry == null || !entry.getValue().hasMapChildren()) { + for (ChatMetaType chatMetaType : ChatMetaType.values()) { + String keyName = chatMetaType.toString() + "es"; + if (data.getNode(keyName).hasListChildren()) { + List children = data.getNode(keyName).getChildrenList(); + for (ConfigurationNode appended : children) { + Map.Entry entry = parseEntry(appended); + if (entry == null) { + continue; + } + nodes.add(readAttributes(entry.getValue(), c -> NodeFactory.chatMetaNode(chatMetaType, c.getNode("priority").getInt(0), entry.getKey()))); + } + } + } + + if (data.getNode("meta").hasListChildren()) { + List children = data.getNode("meta").getChildrenList(); + for (ConfigurationNode appended : children) { + Map.Entry entry = parseEntry(appended); + if (entry == null) { continue; } - - String permission = NodeFactory.groupNode(entry.getKey().toString()); - nodes.addAll(readAttributes(entry.getValue(), permission)); + nodes.add(readAttributes(entry.getValue(), c -> NodeFactory.metaNode(entry.getKey(), entry.getValue().getNode("value").getString("null")))); } } return nodes; } - private static ConfigurationNode writeAttributes(NodeModel node) { - ConfigurationNode attributes = SimpleConfigurationNode.root(); - attributes.getNode("value").setValue(node.getValue()); + private static void writeAttributesTo(ConfigurationNode attributes, NodeModel node, boolean writeValue) { + if (writeValue) { + attributes.getNode("value").setValue(node.getValue()); + } if (!node.getServer().equals("global")) { attributes.getNode("server").setValue(node.getServer()); @@ -792,52 +820,108 @@ public abstract class ConfigurateDao extends AbstractDao { if (!node.getContexts().isEmpty()) { attributes.getNode("context").setValue(ContextSetConfigurateSerializer.serializeContextSet(node.getContexts())); } + } - return attributes; + private static boolean isPlain(NodeModel node) { + return node.getValue() && + node.getServer().equalsIgnoreCase("global") && + node.getWorld().equalsIgnoreCase("global") && + node.getExpiry() == 0L && + node.getContexts().isEmpty(); } private static void writeNodes(ConfigurationNode to, Set nodes) { - ConfigurationNode permsSection = SimpleConfigurationNode.root(); + ConfigurationNode permissionsSection = SimpleConfigurationNode.root(); ConfigurationNode parentsSection = SimpleConfigurationNode.root(); + ConfigurationNode prefixesSection = SimpleConfigurationNode.root(); + ConfigurationNode suffixesSection = SimpleConfigurationNode.root(); + ConfigurationNode metaSection = SimpleConfigurationNode.root(); for (NodeModel node : nodes) { - - // just a raw, default node. - boolean single = node.getValue() && - node.getServer().equalsIgnoreCase("global") && - node.getWorld().equalsIgnoreCase("global") && - node.getExpiry() == 0L && - node.getContexts().isEmpty(); - - // try to parse out the group - String group = node.toNode().isGroupNode() ? node.toNode().getGroupName() : null; + Node n = node.toNode(); // just add a string to the list. - if (single) { - - if (group != null) { - parentsSection.getAppendedNode().setValue(group); + if (isPlain(node)) { + if (n.isGroupNode()) { + parentsSection.getAppendedNode().setValue(n.getGroupName()); + continue; + } + if (!MetaType.ANY.matches(n)) { + permissionsSection.getAppendedNode().setValue(node.getPermission()); continue; } - - permsSection.getAppendedNode().setValue(node.getPermission()); - continue; } - if (group != null) { - ConfigurationNode ent = SimpleConfigurationNode.root(); - ent.getNode(group).setValue(writeAttributes(node)); - parentsSection.getAppendedNode().setValue(ent); - continue; - } + ChatMetaType chatMetaType = ChatMetaType.ofNode(n).orElse(null); + if (chatMetaType != null && n.getValuePrimitive()) { + // handle prefixes / suffixes + Map.Entry entry = chatMetaType.getEntry(n); - ConfigurationNode ent = SimpleConfigurationNode.root(); - ent.getNode(node.getPermission()).setValue(writeAttributes(node)); - permsSection.getAppendedNode().setValue(ent); + ConfigurationNode attributes = SimpleConfigurationNode.root(); + attributes.getNode("priority").setValue(entry.getKey()); + writeAttributesTo(attributes, node, false); + + ConfigurationNode appended = SimpleConfigurationNode.root(); + appended.getNode(entry.getValue()).setValue(attributes); + + switch (chatMetaType) { + case PREFIX: + prefixesSection.getAppendedNode().setValue(appended); + break; + case SUFFIX: + suffixesSection.getAppendedNode().setValue(appended); + break; + default: + throw new AssertionError(); + } + } else if (n.isMeta() && n.getValuePrimitive()) { + // handle meta nodes + Map.Entry meta = n.getMeta(); + + ConfigurationNode attributes = SimpleConfigurationNode.root(); + attributes.getNode("value").setValue(meta.getValue()); + writeAttributesTo(attributes, node, false); + + ConfigurationNode appended = SimpleConfigurationNode.root(); + appended.getNode(meta.getKey()).setValue(attributes); + + metaSection.getAppendedNode().setValue(appended); + } else if (n.isGroupNode() && n.getValuePrimitive()) { + // handle group nodes + ConfigurationNode attributes = SimpleConfigurationNode.root(); + writeAttributesTo(attributes, node, false); + + ConfigurationNode appended = SimpleConfigurationNode.root(); + appended.getNode(n.getGroupName()).setValue(attributes); + + parentsSection.getAppendedNode().setValue(appended); + } else { + // handle regular permissions and negated meta+prefixes+suffixes + ConfigurationNode attributes = SimpleConfigurationNode.root(); + writeAttributesTo(attributes, node, true); + + ConfigurationNode appended = SimpleConfigurationNode.root(); + appended.getNode(n.getPermission()).setValue(attributes); + + permissionsSection.getAppendedNode().setValue(appended); + } } - to.getNode("permissions").setValue(permsSection); - to.getNode("parents").setValue(parentsSection); + if (permissionsSection.hasListChildren()) { + to.getNode("permissions").setValue(permissionsSection); + } + if (parentsSection.hasListChildren()) { + to.getNode("parents").setValue(parentsSection); + } + if (prefixesSection.hasListChildren()) { + to.getNode("prefixes").setValue(prefixesSection); + } + if (suffixesSection.hasListChildren()) { + to.getNode("suffixes").setValue(suffixesSection); + } + if (metaSection.hasListChildren()) { + to.getNode("meta").setValue(metaSection); + } } }