Remove usage of the now-redundant ExtractedContexts class, other misc cleanup

This commit is contained in:
Luck
2017-10-15 14:23:51 +01:00
Unverified
parent 28961b1cfa
commit b26fc69e73
56 changed files with 443 additions and 487 deletions
@@ -151,7 +151,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public Set<User> getUsers() {
return plugin.getUserManager().getAll().values().stream().map(u -> u.getDelegate()).collect(Collectors.toSet());
return plugin.getUserManager().getAll().values().stream().map(me.lucko.luckperms.common.model.User::getDelegate).collect(Collectors.toSet());
}
@Override
@@ -177,7 +177,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public Set<Group> getGroups() {
return plugin.getGroupManager().getAll().values().stream().map(g -> g.getDelegate()).collect(Collectors.toSet());
return plugin.getGroupManager().getAll().values().stream().map(me.lucko.luckperms.common.model.Group::getDelegate).collect(Collectors.toSet());
}
@Override
@@ -198,7 +198,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public Set<Track> getTracks() {
return plugin.getTrackManager().getAll().values().stream().map(t -> t.getDelegate()).collect(Collectors.toSet());
return plugin.getTrackManager().getAll().values().stream().map(me.lucko.luckperms.common.model.Track::getDelegate).collect(Collectors.toSet());
}
@Override
@@ -52,7 +52,7 @@ public class NodeFactoryDelegate implements me.lucko.luckperms.api.NodeFactory {
@Override
public Node.Builder newBuilderFromSerialisedNode(@NonNull String serialisedPermission, boolean value) {
return NodeFactory.builderFromSerializedNode(serialisedPermission, value);
return NodeFactory.builderFromLegacyString(serialisedPermission, value);
}
@Override
@@ -41,7 +41,6 @@ import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.contexts.ExtractedContexts;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.MetaType;
import me.lucko.luckperms.common.node.NodeFactory;
@@ -108,7 +107,7 @@ public class PermissionHolderDelegate implements PermissionHolder {
@Override
public SortedSet<LocalizedNode> getAllNodes(@NonNull Contexts contexts) {
return new TreeSet<>(handle.resolveInheritancesAlmostEqual(ExtractedContexts.generate(contexts)));
return new TreeSet<>(handle.resolveInheritancesAlmostEqual(contexts));
}
@Override
@@ -118,12 +117,12 @@ public class PermissionHolderDelegate implements PermissionHolder {
@Override
public Set<LocalizedNode> getAllNodesFiltered(@NonNull Contexts contexts) {
return new HashSet<>(handle.getAllNodes(ExtractedContexts.generate(contexts)));
return new HashSet<>(handle.getAllNodes(contexts));
}
@Override
public Map<String, Boolean> exportNodes(Contexts contexts, boolean lowerCase) {
return new HashMap<>(handle.exportNodesAndShorthand(ExtractedContexts.generate(contexts), lowerCase));
return new HashMap<>(handle.exportNodesAndShorthand(contexts, lowerCase));
}
@Override
@@ -438,7 +437,7 @@ public class PermissionHolderDelegate implements PermissionHolder {
@Override
public List<LocalizedNode> resolveInheritances(Contexts contexts) {
return handle.resolveInheritances(ExtractedContexts.generate(contexts));
return handle.resolveInheritances(contexts);
}
@Override
@@ -49,7 +49,7 @@ public abstract class BufferedRequest<T> {
private final Executor executor;
private WeakReference<Processor<T>> processor = null;
private ReentrantLock lock = new ReentrantLock();
private final ReentrantLock lock = new ReentrantLock();
public CompletableFuture<T> request() {
lock.lock();
@@ -37,7 +37,6 @@ import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.caching.MetaContexts;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.contexts.ExtractedContexts;
import me.lucko.luckperms.common.metastacking.SimpleMetaStack;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@@ -89,7 +88,7 @@ public class UserCache implements UserData {
if (contexts == Contexts.allowAll()) {
data.setPermissions(user.exportNodesAndShorthand(true));
} else {
data.setPermissions(user.exportNodesAndShorthand(ExtractedContexts.generate(contexts), true));
data.setPermissions(user.exportNodesAndShorthand(contexts, true));
}
return data;
@@ -102,7 +101,7 @@ public class UserCache implements UserData {
if (contexts.getContexts() == Contexts.allowAll()) {
data.loadMeta(user.accumulateMeta(newAccumulator(contexts), null));
} else {
data.loadMeta(user.accumulateMeta(newAccumulator(contexts), null, ExtractedContexts.generate(contexts.getContexts())));
data.loadMeta(user.accumulateMeta(newAccumulator(contexts), null, contexts.getContexts()));
}
return data;
@@ -180,7 +179,7 @@ public class UserCache implements UserData {
if (contexts == Contexts.allowAll()) {
oldData.comparePermissions(user.exportNodesAndShorthand(true));
} else {
oldData.comparePermissions(user.exportNodesAndShorthand(ExtractedContexts.generate(contexts), true));
oldData.comparePermissions(user.exportNodesAndShorthand(contexts, true));
}
return oldData;
@@ -198,7 +197,7 @@ public class UserCache implements UserData {
if (contexts.getContexts() == Contexts.allowAll()) {
oldData.loadMeta(user.accumulateMeta(newAccumulator(contexts), null));
} else {
oldData.loadMeta(user.accumulateMeta(newAccumulator(contexts), null, ExtractedContexts.generate(contexts.getContexts())));
oldData.loadMeta(user.accumulateMeta(newAccumulator(contexts), null, contexts.getContexts()));
}
return oldData;
@@ -27,6 +27,7 @@ package me.lucko.luckperms.common.calculators;
import lombok.RequiredArgsConstructor;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
@@ -42,14 +43,13 @@ import java.util.Map;
* Calculates and caches permissions
*/
@RequiredArgsConstructor
public class PermissionCalculator {
public class PermissionCalculator implements CacheLoader<String, Tristate> {
private final LuckPermsPlugin plugin;
private final PermissionCalculatorMetadata metadata;
private final List<PermissionProcessor> processors;
// caches lookup calls.
private final LoadingCache<String, Tristate> lookupCache = Caffeine.newBuilder()
.build(this::lookupPermissionValue);
private final LoadingCache<String, Tristate> lookupCache = Caffeine.newBuilder().build(this);
public void invalidateCache() {
lookupCache.invalidateAll();
@@ -71,6 +71,11 @@ public class PermissionCalculator {
return result;
}
@Override
public Tristate load(String s) {
return lookupPermissionValue(s);
}
private Tristate lookupPermissionValue(String permission) {
// offer the permission to the permission vault
@@ -54,7 +54,7 @@ public class SharedMainCommand<T extends PermissionHolder> extends SubCommand<T>
/**
* If this instance of the shared command is targeting a user. Otherwise, it targets a group.
*/
private boolean user;
private final boolean user;
public SharedMainCommand(LocalizedSpec spec, String name, boolean user, List<SharedSubCommand> secondaryCommands) {
super(spec, name, null, Predicates.alwaysFalse());
@@ -116,7 +116,7 @@ public abstract class SubCommand<T> extends Command<T, Void> {
if (args.isEmpty() || args.get(0).equals("")) {
return cache.getRootNode().getChildren()
.map(Map::keySet)
.map(s -> s.stream().collect(Collectors.toList()))
.map(s -> (List<String>) new ArrayList<>(s))
.orElse(Collections.emptyList());
}
@@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.impl.group;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.cause.CreationCause;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.commands.CommandResult;
@@ -69,7 +70,7 @@ public class CreateGroup extends SingleCommand {
}
Message.CREATE_SUCCESS.send(sender, groupName);
ExtendedLogEntry.build().actor(sender).actedName(groupName).type('G').action("create").build().submit(plugin, sender);
ExtendedLogEntry.build().actor(sender).actedName(groupName).entryType(LogEntry.Type.GROUP).action("create").build().submit(plugin, sender);
return CommandResult.SUCCESS;
}
}
@@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.impl.group;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.commands.CommandResult;
@@ -78,7 +79,7 @@ public class DeleteGroup extends SingleCommand {
}
Message.DELETE_SUCCESS.send(sender, group.getDisplayName());
ExtendedLogEntry.build().actor(sender).actedName(groupName).type('G').action("delete").build().submit(plugin, sender);
ExtendedLogEntry.build().actor(sender).actedName(groupName).entryType(LogEntry.Type.GROUP).action("delete").build().submit(plugin, sender);
plugin.getUpdateTaskBuffer().request();
return CommandResult.SUCCESS;
}
@@ -141,10 +141,7 @@ public class BulkUpdateCommand extends SingleCommand {
bulkUpdateBuilder.constraint(Constraint.of(field, comparison, expr));
}
String id = "" + ThreadLocalRandom.current().nextInt(9) +
ThreadLocalRandom.current().nextInt(9) +
ThreadLocalRandom.current().nextInt(9) +
ThreadLocalRandom.current().nextInt(9);
String id = String.format("%04d", ThreadLocalRandom.current().nextInt(10000));
BulkUpdate bulkUpdate = bulkUpdateBuilder.build();
@@ -44,7 +44,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class ExportCommand extends SingleCommand {
private AtomicBoolean running = new AtomicBoolean(false);
private final AtomicBoolean running = new AtomicBoolean(false);
public ExportCommand(LocaleManager locale) {
super(CommandSpec.EXPORT.spec(locale), "Export", CommandPermission.EXPORT, Predicates.not(1));
@@ -45,7 +45,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class ImportCommand extends SingleCommand {
private AtomicBoolean running = new AtomicBoolean(false);
private final AtomicBoolean running = new AtomicBoolean(false);
public ImportCommand(LocaleManager locale) {
super(CommandSpec.IMPORT.spec(locale), "Import", CommandPermission.IMPORT, Predicates.not(1));
@@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.impl.track;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.cause.CreationCause;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.commands.CommandResult;
@@ -69,7 +70,7 @@ public class CreateTrack extends SingleCommand {
}
Message.CREATE_SUCCESS.send(sender, trackName);
ExtendedLogEntry.build().actor(sender).actedName(trackName).type('T').action("create").build().submit(plugin, sender);
ExtendedLogEntry.build().actor(sender).actedName(trackName).entryType(LogEntry.Type.TRACK).action("create").build().submit(plugin, sender);
return CommandResult.SUCCESS;
}
}
@@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.impl.track;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.commands.CommandResult;
@@ -71,7 +72,7 @@ public class DeleteTrack extends SingleCommand {
}
Message.DELETE_SUCCESS.send(sender, trackName);
ExtendedLogEntry.build().actor(sender).actedName(trackName).type('T').action("delete").build().submit(plugin, sender);
ExtendedLogEntry.build().actor(sender).actedName(trackName).entryType(LogEntry.Type.TRACK).action("delete").build().submit(plugin, sender);
plugin.getUpdateTaskBuffer().request();
return CommandResult.SUCCESS;
}
@@ -169,7 +169,7 @@ public enum CommandPermission {
public static final String ROOT = "luckperms.";
private String node;
private final String node;
@Getter
private Type type;
@@ -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.contexts;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
@Getter
@EqualsAndHashCode
@ToString
public final class ExtractedContexts {
public static ExtractedContexts generate(Contexts contexts) {
return new ExtractedContexts(contexts);
}
public static ExtractedContexts generate(ContextSet contexts) {
return new ExtractedContexts(contexts);
}
private final Contexts contexts;
private final ImmutableContextSet contextSet;
private String server;
private String world;
private ExtractedContexts(Contexts context) {
this.contexts = context;
this.contextSet = context.getContexts().makeImmutable();
setup(context.getContexts());
}
private ExtractedContexts(ContextSet contexts) {
this.contexts = null;
this.contextSet = contexts.makeImmutable();
setup(contexts);
}
private void setup(ContextSet contexts) {
server = contexts.getAnyValue("server").orElse(null);
world = contexts.getAnyValue("world").orElse(null);
}
public Contexts getContexts() {
if (contexts == null) {
throw new NullPointerException("contexts");
}
return contexts;
}
}
@@ -68,7 +68,7 @@ public class LogicParser {
String match = input.substring(i, i2 + 1);
String matchContent = match.substring(1, match.length() - 1);
String matchReplacement = ("" + checker.apply(matchContent)).toLowerCase();
String matchReplacement = (Boolean.toString(checker.apply(matchContent))).toLowerCase();
input = input.replaceFirst(Pattern.quote(match), matchReplacement);
}
@@ -438,8 +438,8 @@ public enum Message {
}
@Getter
private String message;
private boolean showPrefix;
private final String message;
private final boolean showPrefix;
Message(String message, boolean showPrefix) {
// rewrite hardcoded placeholders according to their position
@@ -73,9 +73,9 @@ public class ProgressLogger {
public void logAllProgress(String msg, int amount) {
if (pluginName == null) {
listeners.forEach(s -> logProgressMessage.send(s, msg.replace("{}", "" + amount)));
listeners.forEach(s -> logProgressMessage.send(s, msg.replace("{}", Integer.toString(amount))));
} else {
listeners.forEach(s -> logProgressMessage.send(s, pluginName, msg.replace("{}", "" + amount)));
listeners.forEach(s -> logProgressMessage.send(s, pluginName, msg.replace("{}", Integer.toString(amount))));
}
}
@@ -25,7 +25,6 @@
package me.lucko.luckperms.common.metastacking;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import lombok.ToString;
@@ -38,7 +37,6 @@ import me.lucko.luckperms.api.metastacking.MetaStackElement;
import java.util.List;
@Getter
@EqualsAndHashCode
@ToString
public final class SimpleMetaStackDefinition implements MetaStackDefinition {
@@ -47,10 +45,41 @@ public final class SimpleMetaStackDefinition implements MetaStackDefinition {
private final String middleSpacer;
private final String endSpacer;
// cache hashcode - this class is immutable, and used an index in MetaContexts
private final int hashCode;
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;
this.hashCode = calculateHashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof SimpleMetaStackDefinition)) return false;
final SimpleMetaStackDefinition other = (SimpleMetaStackDefinition) o;
return this.getElements().equals(other.getElements()) &&
this.getStartSpacer().equals(other.getStartSpacer()) &&
this.getMiddleSpacer().equals(other.getMiddleSpacer()) &&
this.getEndSpacer().equals(other.getEndSpacer());
}
private int calculateHashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.getElements().hashCode();
result = result * PRIME + this.getStartSpacer().hashCode();
result = result * PRIME + this.getMiddleSpacer().hashCode();
result = result * PRIME + this.getEndSpacer().hashCode();
return result;
}
@Override
public int hashCode() {
return hashCode;
}
}
@@ -51,7 +51,6 @@ import me.lucko.luckperms.common.caching.MetaAccumulator;
import me.lucko.luckperms.common.caching.handlers.StateListener;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.contexts.ContextSetComparator;
import me.lucko.luckperms.common.contexts.ExtractedContexts;
import me.lucko.luckperms.common.node.ImmutableLocalizedNode;
import me.lucko.luckperms.common.node.InheritanceInfo;
import me.lucko.luckperms.common.node.MetaType;
@@ -480,7 +479,7 @@ public abstract class PermissionHolder {
public boolean removeIf(Predicate<Node> predicate) {
boolean result;
ImmutableCollection<Node> before = getEnduringNodes().values();;
ImmutableCollection<Node> before = getEnduringNodes().values();
nodesLock.lock();
try {
@@ -524,7 +523,7 @@ public abstract class PermissionHolder {
* @param context context to decide if groups should be applied
* @return a set of nodes
*/
public List<LocalizedNode> resolveInheritances(List<LocalizedNode> accumulator, Set<String> excludedGroups, ExtractedContexts context) {
public List<LocalizedNode> resolveInheritances(List<LocalizedNode> accumulator, Set<String> excludedGroups, Contexts context) {
if (accumulator == null) {
accumulator = new ArrayList<>();
}
@@ -538,14 +537,12 @@ public abstract class PermissionHolder {
}
// get and add the objects own nodes
List<Node> nodes = filterNodes(context.getContextSet());
List<Node> nodes = filterNodes(context.getContexts());
for (Node node : nodes) {
ImmutableLocalizedNode localizedNode = ImmutableLocalizedNode.of(node, getObjectName());
accumulator.add(localizedNode);
}
Contexts contexts = context.getContexts();
// resolve and process the objects parents
List<Group> resolvedGroups = new ArrayList<>();
Set<String> processedGroups = new HashSet<>();
@@ -556,7 +553,7 @@ public abstract class PermissionHolder {
if (!processedGroups.add(groupName) || excludedGroups.contains(groupName) || !n.getValuePrimitive()) continue;
if (!((contexts.isApplyGlobalGroups() || n.isServerSpecific()) && (contexts.isApplyGlobalWorldGroups() || n.isWorldSpecific()))) {
if (!((context.isApplyGlobalGroups() || n.isServerSpecific()) && (context.isApplyGlobalWorldGroups() || n.isWorldSpecific()))) {
continue;
}
@@ -576,11 +573,11 @@ public abstract class PermissionHolder {
return accumulator;
}
public List<LocalizedNode> resolveInheritances(ExtractedContexts context) {
public List<LocalizedNode> resolveInheritances(Contexts context) {
return resolveInheritances(null, null, context);
}
public SortedSet<LocalizedNode> resolveInheritancesAlmostEqual(ExtractedContexts contexts) {
public SortedSet<LocalizedNode> resolveInheritancesAlmostEqual(Contexts contexts) {
List<LocalizedNode> nodes = resolveInheritances(new LinkedList<>(), null, contexts);
NodeTools.removeAlmostEqual(nodes.iterator());
SortedSet<LocalizedNode> ret = new TreeSet<>(NodeWithContextComparator.reverse());
@@ -588,7 +585,7 @@ public abstract class PermissionHolder {
return ret;
}
public SortedSet<LocalizedNode> resolveInheritancesMergeTemp(ExtractedContexts contexts) {
public SortedSet<LocalizedNode> resolveInheritancesMergeTemp(Contexts contexts) {
List<LocalizedNode> nodes = resolveInheritances(new LinkedList<>(), null, contexts);
NodeTools.removeIgnoreValueOrTemp(nodes.iterator());
SortedSet<LocalizedNode> ret = new TreeSet<>(NodeWithContextComparator.reverse());
@@ -668,24 +665,22 @@ public abstract class PermissionHolder {
return ret;
}
public SortedSet<LocalizedNode> getAllNodes(ExtractedContexts context) {
Contexts contexts = context.getContexts();
public SortedSet<LocalizedNode> getAllNodes(Contexts context) {
List<LocalizedNode> entries;
if (contexts.isApplyGroups()) {
if (context.isApplyGroups()) {
entries = resolveInheritances(new LinkedList<>(), null, context);
} else {
entries = new LinkedList<>();
for (Node n : filterNodes(context.getContextSet())) {
for (Node n : filterNodes(context.getContexts())) {
ImmutableLocalizedNode localizedNode = ImmutableLocalizedNode.of(n, getObjectName());
entries.add(localizedNode);
}
}
if (!contexts.isIncludeGlobal()) {
if (!context.isIncludeGlobal()) {
entries.removeIf(n -> !n.isGroupNode() && !n.isServerSpecific());
}
if (!contexts.isApplyGlobalWorldGroups()) {
if (!context.isApplyGlobalWorldGroups()) {
entries.removeIf(n -> !n.isGroupNode() && !n.isWorldSpecific());
}
@@ -695,24 +690,22 @@ public abstract class PermissionHolder {
return ret;
}
public Map<String, Boolean> exportNodesAndShorthand(ExtractedContexts context, boolean lowerCase) {
Contexts contexts = context.getContexts();
public Map<String, Boolean> exportNodesAndShorthand(Contexts context, boolean lowerCase) {
List<LocalizedNode> entries;
if (contexts.isApplyGroups()) {
if (context.isApplyGroups()) {
entries = resolveInheritances(new LinkedList<>(), null, context);
} else {
entries = new LinkedList<>();
for (Node n : filterNodes(context.getContextSet())) {
for (Node n : filterNodes(context.getContexts())) {
ImmutableLocalizedNode localizedNode = ImmutableLocalizedNode.of(n, getObjectName());
entries.add(localizedNode);
}
}
if (!contexts.isIncludeGlobal()) {
if (!context.isIncludeGlobal()) {
entries.removeIf(n -> !n.isGroupNode() && !n.isServerSpecific());
}
if (!contexts.isApplyGlobalWorldGroups()) {
if (!context.isApplyGlobalWorldGroups()) {
entries.removeIf(n -> !n.isGroupNode() && !n.isWorldSpecific());
}
@@ -755,7 +748,7 @@ public abstract class PermissionHolder {
return ImmutableMap.copyOf(perms);
}
public MetaAccumulator accumulateMeta(MetaAccumulator accumulator, Set<String> excludedGroups, ExtractedContexts context) {
public MetaAccumulator accumulateMeta(MetaAccumulator accumulator, Set<String> excludedGroups, Contexts context) {
if (accumulator == null) {
accumulator = MetaAccumulator.makeFromConfig(plugin);
}
@@ -768,16 +761,14 @@ public abstract class PermissionHolder {
excludedGroups.add(getObjectName().toLowerCase());
}
Contexts contexts = context.getContexts();
// get and add the objects own nodes
List<Node> nodes = filterNodes(context.getContextSet());
List<Node> nodes = filterNodes(context.getContexts());
for (Node node : nodes) {
if (!node.getValuePrimitive()) continue;
if (!node.isMeta() && !node.isPrefix() && !node.isSuffix()) continue;
if (!((contexts.isIncludeGlobal() || node.isServerSpecific()) && (contexts.isIncludeGlobalWorld() || node.isWorldSpecific()))) {
if (!((context.isIncludeGlobal() || node.isServerSpecific()) && (context.isIncludeGlobalWorld() || node.isWorldSpecific()))) {
continue;
}
@@ -799,7 +790,7 @@ public abstract class PermissionHolder {
if (!processedGroups.add(groupName) || excludedGroups.contains(groupName) || !n.getValuePrimitive()) continue;
if (!((contexts.isApplyGlobalGroups() || n.isServerSpecific()) && (contexts.isApplyGlobalWorldGroups() || n.isWorldSpecific()))) {
if (!((context.isApplyGlobalGroups() || n.isServerSpecific()) && (context.isApplyGlobalWorldGroups() || n.isWorldSpecific()))) {
continue;
}
@@ -1049,7 +1040,7 @@ public abstract class PermissionHolder {
return DataMutateResult.ALREADY_HAS;
}
ImmutableCollection<Node> before = getEnduringNodes().values();;
ImmutableCollection<Node> before = getEnduringNodes().values();
nodesLock.lock();
try {
@@ -28,11 +28,8 @@ package me.lucko.luckperms.common.node;
import lombok.Getter;
import lombok.ToString;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
@@ -56,11 +53,21 @@ import static com.google.common.base.Preconditions.checkState;
*/
@ToString(of = {"permission", "value", "override", "server", "world", "expireAt", "contexts"})
public final class ImmutableNode implements Node {
/**
* The character which separates each part of a permission node
*/
private static final int NODE_SEPARATOR_CHAR = Character.getNumericValue('.');
private static final String[] PERMISSION_DELIMS = new String[]{"/", "-", "$", "(", ")", "=", ","};
private static final String[] SERVER_WORLD_DELIMS = new String[]{"/", "-"};
private static final Splitter META_SPLITTER = Splitter.on(PatternCache.compileDelimitedMatcher(".", "\\")).limit(2);
/**
* The characters which are delimited when serializing a permission string
*/
private static final String[] PERMISSION_DELIMITERS = new String[]{"/", "-", "$", "(", ")", "=", ","};
/**
* The characters which are delimited when serializing a server or world string
*/
private static final String[] SERVER_WORLD_DELIMITERS = new String[]{"/", "-"};
/*
@@ -114,19 +121,11 @@ public final class ImmutableNode implements Node {
private final int hashCode;
private final boolean isGroup;
// all nullable
private String groupName;
private final boolean isWildcard;
private final int wildcardLevel;
private final boolean isMeta;
private Map.Entry<String, String> meta;
private final boolean isPrefix;
private Map.Entry<Integer, String> prefix;
private final boolean isSuffix;
private Map.Entry<Integer, String> suffix;
private final List<String> resolvedShorthand;
@@ -145,65 +144,34 @@ public final class ImmutableNode implements Node {
*/
@SuppressWarnings("deprecation")
ImmutableNode(String permission, boolean value, boolean override, long expireAt, String server, String world, ContextSet contexts) {
if (permission == null || permission.equals("")) {
if (permission == null || permission.isEmpty()) {
throw new IllegalArgumentException("Empty permission");
}
// standardize server/world values.
if (server != null) {
server = server.toLowerCase();
}
if (world != null) {
world = world.toLowerCase();
}
if (server != null && (server.equals("global") || server.equals(""))) {
server = null;
}
if (world != null && (world.equals("global") || world.equals(""))) {
world = null;
}
server = standardizeServerWorld(server);
world = standardizeServerWorld(world);
this.permission = NodeFactory.unescapeDelimiters(permission, PERMISSION_DELIMS).intern();
// define core attributes
this.permission = NodeFactory.unescapeDelimiters(permission, PERMISSION_DELIMITERS).intern();
this.value = value;
this.override = override;
this.expireAt = expireAt;
this.server = internString(NodeFactory.unescapeDelimiters(server, SERVER_WORLD_DELIMS));
this.world = internString(NodeFactory.unescapeDelimiters(world, SERVER_WORLD_DELIMS));
this.server = internString(NodeFactory.unescapeDelimiters(server, SERVER_WORLD_DELIMITERS));
this.world = internString(NodeFactory.unescapeDelimiters(world, SERVER_WORLD_DELIMITERS));
this.contexts = contexts == null ? ContextSet.empty() : contexts.makeImmutable();
String lowerCasePermission = this.permission.toLowerCase();
// Setup state
isGroup = lowerCasePermission.startsWith("group.");
if (isGroup) {
groupName = lowerCasePermission.substring("group.".length()).intern();
}
isWildcard = this.permission.endsWith(".*");
wildcardLevel = this.permission.chars().filter(num -> num == NODE_SEPARATOR_CHAR).sum();
isMeta = NodeFactory.isMetaNode(this.permission);
if (isMeta) {
List<String> metaPart = META_SPLITTER.splitToList(this.permission.substring("meta.".length()));
meta = Maps.immutableEntry(MetaUtils.unescapeCharacters(metaPart.get(0)).intern(), MetaUtils.unescapeCharacters(metaPart.get(1)).intern());
}
isPrefix = NodeFactory.isPrefixNode(this.permission);
if (isPrefix) {
List<String> prefixPart = META_SPLITTER.splitToList(this.permission.substring("prefix.".length()));
Integer i = Integer.parseInt(prefixPart.get(0));
prefix = Maps.immutableEntry(i, MetaUtils.unescapeCharacters(prefixPart.get(1)).intern());
}
isSuffix = NodeFactory.isSuffixNode(this.permission);
if (isSuffix) {
List<String> suffixPart = META_SPLITTER.splitToList(this.permission.substring("suffix.".length()));
Integer i = Integer.parseInt(suffixPart.get(0));
suffix = Maps.immutableEntry(i, MetaUtils.unescapeCharacters(suffixPart.get(1)).intern());
}
// define cached state
groupName = NodeFactory.parseGroupNode(this.permission);
wildcardLevel = this.permission.endsWith(".*") ? this.permission.chars().filter(num -> num == NODE_SEPARATOR_CHAR).sum() : -1;
meta = NodeFactory.parseMetaNode(this.permission);
prefix = NodeFactory.parsePrefixNode(this.permission);
suffix = NodeFactory.parseSuffixNode(this.permission);
resolvedShorthand = ImmutableList.copyOf(ShorthandParser.parseShorthand(getPermission()));
optServer = Optional.ofNullable(this.server);
optWorld = Optional.ofNullable(this.world);
// calculate the "full" context set
if (this.server != null || this.world != null) {
MutableContextSet fullContexts = this.contexts.mutableCopy();
if (this.server != null) {
@@ -218,8 +186,6 @@ public final class ImmutableNode implements Node {
this.fullContexts = this.contexts;
}
this.optServer = Optional.ofNullable(this.server);
this.optWorld = Optional.ofNullable(this.world);
this.hashCode = calculateHashCode();
}
@@ -288,7 +254,7 @@ public final class ImmutableNode implements Node {
@Override
public boolean isGroupNode() {
return isGroup;
return groupName != null;
}
@Override
@@ -299,17 +265,18 @@ public final class ImmutableNode implements Node {
@Override
public boolean isWildcard() {
return isWildcard;
return wildcardLevel != -1;
}
@Override
public int getWildcardLevel() {
checkState(isWildcard(), "Node is not a wildcard");
return wildcardLevel;
}
@Override
public boolean isMeta() {
return isMeta;
return meta != null;
}
@Override
@@ -320,7 +287,7 @@ public final class ImmutableNode implements Node {
@Override
public boolean isPrefix() {
return isPrefix;
return prefix != null;
}
@Override
@@ -331,7 +298,7 @@ public final class ImmutableNode implements Node {
@Override
public boolean isSuffix() {
return isSuffix;
return suffix != null;
}
@Override
@@ -446,11 +413,11 @@ public final class ImmutableNode implements Node {
StringBuilder builder = new StringBuilder();
if (server != null) {
builder.append(NodeFactory.escapeDelimiters(server, SERVER_WORLD_DELIMS));
if (world != null) builder.append("-").append(NodeFactory.escapeDelimiters(world, SERVER_WORLD_DELIMS));
builder.append(NodeFactory.escapeDelimiters(server, SERVER_WORLD_DELIMITERS));
if (world != null) builder.append("-").append(NodeFactory.escapeDelimiters(world, SERVER_WORLD_DELIMITERS));
builder.append("/");
} else {
if (world != null) builder.append("global-").append(NodeFactory.escapeDelimiters(world, SERVER_WORLD_DELIMS)).append("/");
if (world != null) builder.append("global-").append(NodeFactory.escapeDelimiters(world, SERVER_WORLD_DELIMITERS)).append("/");
}
if (!contexts.isEmpty()) {
@@ -618,4 +585,16 @@ public final class ImmutableNode implements Node {
return s == null ? null : s.intern();
}
private static String standardizeServerWorld(String s) {
if (s != null) {
s = s.toLowerCase();
if (s.equals("global") || s.isEmpty()) {
s = null;
}
}
return s;
}
}
@@ -30,6 +30,7 @@ import lombok.experimental.UtilityClass;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.MetaUtils;
@@ -38,23 +39,41 @@ import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.utils.PatternCache;
import java.util.List;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
/**
* Utility class to make Node(Builder) instances from serialised strings or existing Nodes
*/
@SuppressWarnings("deprecation")
@UtilityClass
public class NodeFactory {
private static final LoadingCache<String, Node> CACHE = Caffeine.newBuilder()
.build(s -> builderFromSerializedNode(s, true).build());
private static final LoadingCache<String, Node> CACHE_NEGATED = Caffeine.newBuilder()
.build(s -> builderFromSerializedNode(s, false).build());
// used to split prefix/suffix/meta nodes
private static final Splitter META_SPLITTER = Splitter.on(PatternCache.compileDelimitedMatcher(".", "\\")).limit(2);
// legacy node format delimiters
private static final Pattern LEGACY_SERVER_DELIM = PatternCache.compileDelimitedMatcher("/", "\\");
private static final Splitter LEGACY_SERVER_SPLITTER = Splitter.on(LEGACY_SERVER_DELIM).limit(2);
private static final Pattern LEGACY_WORLD_DELIM = PatternCache.compileDelimitedMatcher("-", "\\");
private static final Splitter LEGACY_WORLD_SPLITTER = Splitter.on(LEGACY_WORLD_DELIM).limit(2);
private static final Pattern LEGACY_EXPIRY_DELIM = PatternCache.compileDelimitedMatcher("$", "\\");
private static final Splitter LEGACY_EXPIRY_SPLITTER = Splitter.on(LEGACY_EXPIRY_DELIM).limit(2);
// caches the conversion between legacy node strings --> node instances
private static final LoadingCache<String, Node> LEGACY_SERIALIZATION_CACHE = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.build(s -> builderFromLegacyString(s, true).build());
private static final LoadingCache<String, Node> LEGACY_SERIALIZATION_CACHE_NEGATED = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.build(s -> builderFromLegacyString(s, false).build());
public static Node fromSerializedNode(String s, Boolean b) {
try {
return b ? CACHE.get(s) : CACHE_NEGATED.get(s);
return b ? LEGACY_SERIALIZATION_CACHE.get(s) : LEGACY_SERIALIZATION_CACHE_NEGATED.get(s);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
@@ -64,44 +83,59 @@ public class NodeFactory {
return new NodeBuilder(s, false);
}
public static Node.Builder builderFromSerializedNode(String s, Boolean b) {
public static Node.Builder builderFromLegacyString(String s, Boolean b) {
// if contains /
if (PatternCache.compileDelimitedMatcher("/", "\\").matcher(s).find()) {
List<String> parts = Splitter.on(PatternCache.compileDelimitedMatcher("/", "\\")).limit(2).splitToList(s);
if (LEGACY_SERVER_DELIM.matcher(s).find()) {
// 0=server(+world) 1=node
Iterator<String> parts = LEGACY_SERVER_SPLITTER.split(s).iterator();
String parts0 = parts.next();
String parts1 = parts.next();
// WORLD SPECIFIC
// if parts[0] contains -
if (PatternCache.compileDelimitedMatcher("-", "\\").matcher(parts.get(0)).find()) {
List<String> serverParts = Splitter.on(PatternCache.compileDelimitedMatcher("-", "\\")).limit(2).splitToList(parts.get(0));
if (LEGACY_WORLD_DELIM.matcher(parts0).find()) {
// 0=server 1=world
Iterator<String> serverParts = LEGACY_WORLD_SPLITTER.split(parts0).iterator();
String serverParts0 = serverParts.next();
String serverParts1 = serverParts.next();
// if parts[1] contains $
if (PatternCache.compileDelimitedMatcher("$", "\\").matcher(parts.get(1)).find()) {
List<String> tempParts = Splitter.on('$').limit(2).splitToList(parts.get(1));
return new NodeBuilder(tempParts.get(0), true).setServer(serverParts.get(0)).setWorld(serverParts.get(1))
.setExpiry(Long.parseLong(tempParts.get(1))).setValue(b);
if (LEGACY_EXPIRY_DELIM.matcher(parts1).find()) {
// 0=node 1=expiry
Iterator<String> tempParts = LEGACY_EXPIRY_SPLITTER.split(parts1).iterator();
String tempParts0 = tempParts.next();
String tempParts1 = tempParts.next();
return new NodeBuilder(tempParts0, true).setServer(serverParts0).setWorld(serverParts1).setExpiry(Long.parseLong(tempParts1)).setValue(b);
} else {
return new NodeBuilder(parts.get(1), true).setServer(serverParts.get(0)).setWorld(serverParts.get(1)).setValue(b);
return new NodeBuilder(parts1, true).setServer(serverParts0).setWorld(serverParts1).setValue(b);
}
} else {
// SERVER BUT NOT WORLD SPECIFIC
// if parts[1] contains $
if (PatternCache.compileDelimitedMatcher("$", "\\").matcher(parts.get(1)).find()) {
List<String> tempParts = Splitter.on(PatternCache.compileDelimitedMatcher("$", "\\")).limit(2).splitToList(parts.get(1));
return new NodeBuilder(tempParts.get(0), true).setServer(parts.get(0)).setExpiry(Long.parseLong(tempParts.get(1))).setValue(b);
if (LEGACY_EXPIRY_DELIM.matcher(parts1).find()) {
// 0=node 1=expiry
Iterator<String> tempParts = LEGACY_EXPIRY_SPLITTER.split(parts1).iterator();
String tempParts0 = tempParts.next();
String tempParts1 = tempParts.next();
return new NodeBuilder(tempParts0, true).setServer(parts0).setExpiry(Long.parseLong(tempParts1)).setValue(b);
} else {
return new NodeBuilder(parts.get(1), true).setServer(parts.get(0)).setValue(b);
return new NodeBuilder(parts1, true).setServer(parts0).setValue(b);
}
}
} else {
// NOT SERVER SPECIFIC
// if s contains $
if (PatternCache.compileDelimitedMatcher("$", "\\").matcher(s).find()) {
List<String> tempParts = Splitter.on(PatternCache.compileDelimitedMatcher("$", "\\")).limit(2).splitToList(s);
return new NodeBuilder(tempParts.get(0), true).setExpiry(Long.parseLong(tempParts.get(1))).setValue(b);
if (LEGACY_EXPIRY_DELIM.matcher(s).find()) {
// 0=node 1=expiry
Iterator<String> tempParts = LEGACY_EXPIRY_SPLITTER.split(s).iterator();
String tempParts0 = tempParts.next();
String tempParts1 = tempParts.next();
return new NodeBuilder(tempParts0, true).setExpiry(Long.parseLong(tempParts1)).setValue(b);
} else {
return new NodeBuilder(s, true).setValue(b);
}
@@ -250,40 +284,58 @@ public class NodeFactory {
return s;
}
public static boolean isMetaNode(String s) {
public static String parseGroupNode(String s) {
String lower = s.toLowerCase();
if (!lower.startsWith("group.")) {
return null;
}
return lower.substring("group.".length()).intern();
}
public static Map.Entry<String, String> parseMetaNode(String s) {
if (!s.startsWith("meta.")) {
return false;
return null;
}
String parts = s.substring("meta.".length());
return PatternCache.compileDelimitedMatcher(".", "\\").matcher(parts).find();
Iterator<String> metaParts = META_SPLITTER.split(s.substring("meta.".length())).iterator();
if (!metaParts.hasNext()) return null;
String key = metaParts.next();
if (!metaParts.hasNext()) return null;
String value = metaParts.next();
return Maps.immutableEntry(MetaUtils.unescapeCharacters(key).intern(), MetaUtils.unescapeCharacters(value).intern());
}
private static boolean isChatMetaNode(String type, String s) {
private static Map.Entry<Integer, String> parseChatMetaNode(String type, String s) {
if (!s.startsWith(type + ".")) {
return false;
}
String parts = s.substring((type + ".").length());
if (!PatternCache.compileDelimitedMatcher(".", "\\").matcher(parts).find()) {
return false;
return null;
}
List<String> metaParts = Splitter.on(PatternCache.compileDelimitedMatcher(".", "\\")).limit(2).splitToList(parts);
String priority = metaParts.get(0);
Iterator<String> metaParts = META_SPLITTER.split(s.substring((type + ".").length())).iterator();
if (!metaParts.hasNext()) return null;
String priority = metaParts.next();
if (!metaParts.hasNext()) return null;
String value = metaParts.next();
try {
Integer.parseInt(priority);
return true;
int p = Integer.parseInt(priority);
String v = MetaUtils.unescapeCharacters(value).intern();
return Maps.immutableEntry(p, v);
} catch (NumberFormatException e) {
return false;
return null;
}
}
public static boolean isPrefixNode(String s) {
return isChatMetaNode("prefix", s);
public static Map.Entry<Integer, String> parsePrefixNode(String s) {
return parseChatMetaNode("prefix", s);
}
public static boolean isSuffixNode(String s) {
return isChatMetaNode("suffix", s);
public static Map.Entry<Integer, String> parseSuffixNode(String s) {
return parseChatMetaNode("suffix", s);
}
public static Node make(String node) {
@@ -26,7 +26,6 @@
package me.lucko.luckperms.common.primarygroup;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.contexts.ExtractedContexts;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.User;
@@ -50,7 +49,7 @@ public class AllParentsByWeightHolder extends CachedPrimaryGroupHolder {
// hack to get a list of groups the holder is inheriting from
Set<String> groupNames = new LinkedHashSet<>();
user.resolveInheritances(new NoopList<>(), groupNames, ExtractedContexts.generate(contexts));
user.resolveInheritances(new NoopList<>(), groupNames, contexts);
List<Group> groups = new ArrayList<>();
for (String groupName : groupNames) {
@@ -33,7 +33,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
public class RegexProcessor implements PermissionProcessor {
private Map<Pattern, Boolean> regexPermissions = new ConcurrentHashMap<>();
private final Map<Pattern, Boolean> regexPermissions = new ConcurrentHashMap<>();
@Override
public Tristate hasPermission(String permission) {
@@ -33,7 +33,7 @@ import java.util.function.Consumer;
/**
* A reference to a specific {@link PermissionHolder}.
*
* @param <I> the holder type
* @param <S> the holder type
* @param <I> the holder identifier type
*/
public interface HolderReference<S, I> extends Identifiable<I> {
@@ -60,7 +60,7 @@ public abstract class FlatfileBacking extends AbstractBacking {
private static final String LOG_FORMAT = "%s(%s): [%s] %s(%s) --> %s";
private final Logger actionLogger = Logger.getLogger("luckperms_actions");
private FileUuidCache uuidCache = new FileUuidCache();
private final FileUuidCache uuidCache = new FileUuidCache();
private final File pluginDir;
@@ -218,6 +218,7 @@ public abstract class FlatfileBacking extends AbstractBacking {
@Override
public boolean logAction(LogEntry entry) {
//noinspection deprecation
actionLogger.info(String.format(LOG_FORMAT,
(entry.getActor().equals(Constants.CONSOLE_UUID) ? "" : entry.getActor() + " "),
entry.getActorName(),
@@ -165,6 +165,7 @@ public class MongoDBBacking extends AbstractBacking {
return call(() -> {
MongoCollection<Document> c = database.getCollection(prefix + "action");
//noinspection deprecation
Document doc = new Document()
.append("timestamp", entry.getTimestamp())
.append("actor", entry.getActor())
@@ -750,6 +751,7 @@ public class MongoDBBacking extends AbstractBacking {
public static Map<String, Boolean> exportToLegacy(Iterable<Node> nodes) {
Map<String, Boolean> m = new HashMap<>();
for (Node node : nodes) {
//noinspection deprecation
m.put(node.toSerializedNode(), node.getValuePrimitive());
}
return m;
@@ -221,6 +221,7 @@ public class SQLBacking extends AbstractBacking {
ps.setLong(1, entry.getTimestamp());
ps.setString(2, entry.getActor().toString());
ps.setString(3, entry.getActorName());
//noinspection deprecation
ps.setString(4, Character.toString(entry.getType()));
ps.setString(5, entry.getActed() == null ? "null" : entry.getActed().toString());
ps.setString(6, entry.getActedName());
@@ -50,7 +50,7 @@ abstract class FlatfileProvider extends SQLProvider {
protected abstract String getDriverId();
@Override
public void init() throws Exception {
public void init() {
}
@@ -51,7 +51,7 @@ public class MySQLProvider extends SQLProvider {
}
@Override
public void init() throws Exception {
public void init() {
HikariConfig config = new HikariConfig();
String address = configuration.getAddress();
@@ -49,7 +49,7 @@ public class PostgreSQLProvider extends SQLProvider {
}
@Override
public void init() throws Exception {
public void init() {
HikariConfig config = new HikariConfig();
String address = configuration.getAddress();
@@ -40,7 +40,7 @@ public abstract class SQLProvider {
@Getter
private final String name;
public abstract void init() throws Exception;
public abstract void init();
public abstract void shutdown() throws Exception;