Separate prefix/suffix/meta nodes into their own section within yaml/json/hocon storage files

This commit is contained in:
Luck 2018-02-23 15:59:12 +00:00
parent 966bf8bf51
commit 2889c28815
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
3 changed files with 174 additions and 82 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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<NodeModel> readAttributes(ConfigurationNode entry, String permission) {
Map<Object, ? extends ConfigurationNode> attributes = entry.getChildrenMap();
private static NodeModel readAttributes(ConfigurationNode attributes, Function<ConfigurationNode, String> 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<NodeModel> 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<NodeModel> 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<String, ConfigurationNode> parseEntry(ConfigurationNode appended) {
if (!appended.hasMapChildren()) {
return null;
}
Map.Entry<Object, ? extends ConfigurationNode> 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<NodeModel> readNodes(ConfigurationNode data) {
Set<NodeModel> nodes = new HashSet<>();
if (data.getNode("permissions").hasListChildren()) {
List<? extends ConfigurationNode> 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<? extends ConfigurationNode> 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<String, ConfigurationNode> entry = parseEntry(appended);
if (entry == null) {
continue;
}
Map.Entry<Object, ? extends ConfigurationNode> 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<? extends ConfigurationNode> parts = data.getNode("parents").getChildrenList();
for (ConfigurationNode ent : parts) {
String stringValue = ent.getValue(Types::strictAsString);
List<? extends ConfigurationNode> 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<String, ConfigurationNode> entry = parseEntry(appended);
if (entry == null) {
continue;
}
nodes.add(readAttributes(entry.getValue(), c -> NodeFactory.groupNode(entry.getKey())));
}
}
Map.Entry<Object, ? extends ConfigurationNode> 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<? extends ConfigurationNode> children = data.getNode(keyName).getChildrenList();
for (ConfigurationNode appended : children) {
Map.Entry<String, ConfigurationNode> 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<? extends ConfigurationNode> children = data.getNode("meta").getChildrenList();
for (ConfigurationNode appended : children) {
Map.Entry<String, ConfigurationNode> 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<NodeModel> 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<Integer, String> 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<String, String> 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);
}
}
}