More work

This commit is contained in:
Luck 2019-10-13 15:04:03 +01:00
parent 9438df787a
commit 7764a04d46
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
15 changed files with 78 additions and 158 deletions

View File

@ -75,7 +75,7 @@ public interface ContextManager {
* @param user the user * @param user the user
* @return the applicable context for the subject * @return the applicable context for the subject
*/ */
@NonNull Optional<ImmutableContextSet> lookupContext(@NonNull User user); @NonNull Optional<ImmutableContextSet> getContext(@NonNull User user);
/** /**
* Gets the contexts from the static calculators in this manager. * Gets the contexts from the static calculators in this manager.
@ -115,7 +115,7 @@ public interface ContextManager {
* @param user the user * @param user the user
* @return the query options for the subject * @return the query options for the subject
*/ */
@NonNull Optional<QueryOptions> lookupQueryOptions(@NonNull User user); @NonNull Optional<QueryOptions> getQueryOptions(@NonNull User user);
/** /**
* Gets the static query options, using the registered static context calculators. * Gets the static query options, using the registered static context calculators.
@ -124,29 +124,6 @@ public interface ContextManager {
*/ */
@NonNull QueryOptions getStaticQueryOptions(); @NonNull QueryOptions getStaticQueryOptions();
/**
* Forms a {@link QueryOptions} instance from an {@link ImmutableContextSet}.
*
* <p>This method relies on the plugins configuration to form the
* {@link QueryOptions} instance.</p>
*
* @param subject the reference subject
* @param contextSet the context set
* @return a options instance
*/
@NonNull QueryOptions formQueryOptions(@NonNull Object subject, @NonNull ImmutableContextSet contextSet);
/**
* Forms a {@link QueryOptions} instance from an {@link ImmutableContextSet}.
*
* <p>This method relies on the plugins configuration to form the
* {@link QueryOptions} instance.</p>
*
* @param contextSet the context set
* @return a options instance
*/
@NonNull QueryOptions formQueryOptions(@NonNull ImmutableContextSet contextSet);
/** /**
* Registers a context calculator with the manager. * Registers a context calculator with the manager.
* *

View File

@ -52,7 +52,7 @@ public interface TrackMutateEvent extends LuckPermsEvent {
* @return the data before the change * @return the data before the change
*/ */
@Param(1) @Param(1)
@NonNull List<String> getDataBefore(); @NonNull List<String> getStateBefore();
/** /**
* Gets an immutable copy of the tracks data after the change * Gets an immutable copy of the tracks data after the change
@ -60,6 +60,6 @@ public interface TrackMutateEvent extends LuckPermsEvent {
* @return the data after the change * @return the data after the change
*/ */
@Param(2) @Param(2)
@NonNull List<String> getDataAfter(); @NonNull List<String> getStateAfter();
} }

View File

@ -53,19 +53,6 @@ public interface MetaStackFactory {
*/ */
@NonNull List<MetaStackElement> fromStrings(@NonNull List<String> definitions); @NonNull List<MetaStackElement> fromStrings(@NonNull List<String> definitions);
/**
* Creates a new {@link MetaStackDefinition} with the given properties.
*
* @param elements the elements to be included in the stack.
* @param startSpacer the spacer to be included at the start of the stacks output
* @param middleSpacer the spacer to be included between stack elements
* @param endSpacer the spacer to be included at the end of the stacks output
* @return the new stack definition instance
*/
default @NonNull MetaStackDefinition createDefinition(@NonNull List<MetaStackElement> elements, @NonNull String startSpacer, @NonNull String middleSpacer, @NonNull String endSpacer) {
return createDefinition(elements, DuplicateRemovalFunction.RETAIN_ALL, startSpacer, middleSpacer, endSpacer);
}
/** /**
* Creates a new {@link MetaStackDefinition} with the given properties. * Creates a new {@link MetaStackDefinition} with the given properties.
* *

View File

@ -48,7 +48,6 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
@ -127,16 +126,6 @@ public interface PermissionHolder {
*/ */
@NonNull CachedDataManager getCachedData(); @NonNull CachedDataManager getCachedData();
/**
* Refreshes and applies any changes to the cached holder data.
*
* <p>Calling this method is unnecessary in most cases. Cache updates are handled
* behind the scenes by the implementation.</p>
*
* @return the task future
*/
@NonNull CompletableFuture<Void> refreshCachedData();
/** /**
* Gets the {@link Data} of a particular type. * Gets the {@link Data} of a particular type.
* *

View File

@ -152,11 +152,11 @@ public interface UserManager {
/** /**
* Gets a loaded user. * Gets a loaded user.
* *
* @param name the username of the user to get * @param username the username of the user to get
* @return a {@link User} object, if one matching the uuid is loaded, or null if not * @return a {@link User} object, if one matching the uuid is loaded, or null if not
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
*/ */
@Nullable User getUser(@NonNull String name); @Nullable User getUser(@NonNull String username);
/** /**
* Gets a set of all loaded users. * Gets a set of all loaded users.

View File

@ -138,13 +138,11 @@ public class MinimalApiProvider implements LuckPerms {
} }
@Override public @NonNull ImmutableContextSet getContext(@NonNull Object subject) { throw exception(); } @Override public @NonNull ImmutableContextSet getContext(@NonNull Object subject) { throw exception(); }
@Override public @NonNull Optional<ImmutableContextSet> lookupContext(@NonNull User user) { throw exception(); } @Override public @NonNull Optional<ImmutableContextSet> getContext(@NonNull User user) { throw exception(); }
@Override public @NonNull ImmutableContextSet getStaticContext() { throw exception(); } @Override public @NonNull ImmutableContextSet getStaticContext() { throw exception(); }
@Override public @NonNull QueryOptions getQueryOptions(@NonNull Object subject) { throw exception(); } @Override public @NonNull QueryOptions getQueryOptions(@NonNull Object subject) { throw exception(); }
@Override public @NonNull Optional<QueryOptions> lookupQueryOptions(@NonNull User user) { throw exception(); } @Override public @NonNull Optional<QueryOptions> getQueryOptions(@NonNull User user) { throw exception(); }
@Override public @NonNull QueryOptions getStaticQueryOptions() { throw exception(); } @Override public @NonNull QueryOptions getStaticQueryOptions() { throw exception(); }
@Override public @NonNull QueryOptions formQueryOptions(@NonNull Object subject, @NonNull ImmutableContextSet contextSet) { throw exception(); }
@Override public @NonNull QueryOptions formQueryOptions(@NonNull ImmutableContextSet contextSet) { throw exception(); }
@Override public void registerCalculator(@NonNull ContextCalculator<?> calculator) { throw exception(); } @Override public void registerCalculator(@NonNull ContextCalculator<?> calculator) { throw exception(); }
@Override public void unregisterCalculator(@NonNull ContextCalculator<?> calculator) { throw exception(); } @Override public void unregisterCalculator(@NonNull ContextCalculator<?> calculator) { throw exception(); }
@Override public void invalidateCache(@NonNull Object subject) { throw exception(); } @Override public void invalidateCache(@NonNull Object subject) { throw exception(); }

View File

@ -65,7 +65,7 @@ public class ApiContextManager implements net.luckperms.api.context.ContextManag
} }
@Override @Override
public @NonNull Optional<ImmutableContextSet> lookupContext(@NonNull User user) { public @NonNull Optional<ImmutableContextSet> getContext(@NonNull User user) {
Objects.requireNonNull(user, "user"); Objects.requireNonNull(user, "user");
return this.plugin.getQueryOptionsForUser(ApiUser.cast(user)).map(QueryOptions::context); return this.plugin.getQueryOptionsForUser(ApiUser.cast(user)).map(QueryOptions::context);
} }
@ -88,7 +88,7 @@ public class ApiContextManager implements net.luckperms.api.context.ContextManag
} }
@Override @Override
public @NonNull Optional<QueryOptions> lookupQueryOptions(@NonNull User user) { public @NonNull Optional<QueryOptions> getQueryOptions(@NonNull User user) {
Objects.requireNonNull(user, "user"); Objects.requireNonNull(user, "user");
return this.plugin.getQueryOptionsForUser(ApiUser.cast(user)); return this.plugin.getQueryOptionsForUser(ApiUser.cast(user));
} }
@ -98,19 +98,6 @@ public class ApiContextManager implements net.luckperms.api.context.ContextManag
return this.handle.getStaticQueryOptions(); return this.handle.getStaticQueryOptions();
} }
@Override
public @NonNull QueryOptions formQueryOptions(@NonNull Object subject, @NonNull ImmutableContextSet contextSet) {
Objects.requireNonNull(subject, "subject");
Objects.requireNonNull(contextSet, "contextSet");
return this.handle.formQueryOptions(subject, contextSet);
}
@Override
public @NonNull QueryOptions formQueryOptions(@NonNull ImmutableContextSet contextSet) {
Objects.requireNonNull(contextSet, "contextSet");
return this.handle.formQueryOptions(contextSet);
}
@Override @Override
public void registerCalculator(@NonNull ContextCalculator<?> calculator) { public void registerCalculator(@NonNull ContextCalculator<?> calculator) {
Objects.requireNonNull(calculator, "calculator"); Objects.requireNonNull(calculator, "calculator");

View File

@ -25,10 +25,7 @@
package me.lucko.luckperms.common.api.implementation; package me.lucko.luckperms.common.api.implementation;
import com.google.common.collect.ImmutableSortedSet;
import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
import net.luckperms.api.cacheddata.CachedDataManager; import net.luckperms.api.cacheddata.CachedDataManager;
import net.luckperms.api.context.ContextSet; import net.luckperms.api.context.ContextSet;
@ -46,15 +43,11 @@ import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate; import java.util.function.Predicate;
public class ApiPermissionHolder implements net.luckperms.api.model.PermissionHolder { public class ApiPermissionHolder implements net.luckperms.api.model.PermissionHolder {
@ -88,11 +81,6 @@ public class ApiPermissionHolder implements net.luckperms.api.model.PermissionHo
return this.handle.getCachedData(); return this.handle.getCachedData();
} }
@Override
public @NonNull CompletableFuture<Void> refreshCachedData() {
return CompletableFuture.runAsync(() -> this.handle.getCachedData().invalidate());
}
@Override @Override
public Data getData(@NonNull DataType dataType) { public Data getData(@NonNull DataType dataType) {
switch (dataType) { switch (dataType) {
@ -127,28 +115,12 @@ public class ApiPermissionHolder implements net.luckperms.api.model.PermissionHo
@Override @Override
public @NonNull List<Node> resolveInheritedNodes(@NonNull QueryOptions queryOptions) { public @NonNull List<Node> resolveInheritedNodes(@NonNull QueryOptions queryOptions) {
return this.handle.resolveInheritances(queryOptions); return this.handle.resolveInheritedNodes(queryOptions);
} }
@Override @Override
public @NonNull SortedSet<Node> resolveDistinctInheritedNodes(@NonNull QueryOptions queryOptions) { public @NonNull SortedSet<Node> resolveDistinctInheritedNodes(@NonNull QueryOptions queryOptions) {
List<Node> entries = this.handle.getAllEntries(queryOptions); return this.handle.resolveInheritedNodesSorted(queryOptions);
removeSamePermission(entries.iterator());
SortedSet<Node> ret = new TreeSet<>(NodeWithContextComparator.reverse());
ret.addAll(entries);
return ImmutableSortedSet.copyOfSorted(ret);
}
private static <T extends Node> void removeSamePermission(Iterator<T> it) {
Set<String> alreadyIn = new HashSet<>();
while (it.hasNext()) {
T next = it.next();
if (!alreadyIn.add(next.getKey())) {
it.remove();
}
}
} }
@Override @Override

View File

@ -114,9 +114,9 @@ public class ApiUserManager extends ApiAbstractManager<User, net.luckperms.api.m
} }
@Override @Override
public net.luckperms.api.model.user.User getUser(@NonNull String name) { public net.luckperms.api.model.user.User getUser(@NonNull String username) {
Objects.requireNonNull(name, "name"); Objects.requireNonNull(username, "name");
return getDelegateFor(this.handle.getByUsername(name)); return getDelegateFor(this.handle.getByUsername(username));
} }
@Override @Override

View File

@ -89,7 +89,7 @@ public class MetaInfo extends SharedSubCommand {
Set<MetaNode> meta = new LinkedHashSet<>(); Set<MetaNode> meta = new LinkedHashSet<>();
// Collect data // Collect data
for (Node node : holder.resolveInheritances(QueryOptions.nonContextual())) { for (Node node : holder.resolveInheritedNodes(QueryOptions.nonContextual())) {
if (!NodeType.META_OR_CHAT_META.matches(node)) { if (!NodeType.META_OR_CHAT_META.matches(node)) {
continue; continue;
} }

View File

@ -66,7 +66,7 @@ public class PermissionCheckInherits extends SharedSubCommand {
String node = ArgumentParser.parseString(0, args); String node = ArgumentParser.parseString(0, args);
MutableContextSet context = ArgumentParser.parseContext(1, args, plugin); MutableContextSet context = ArgumentParser.parseContext(1, args, plugin);
Optional<Node> match = holder.resolveInheritances(QueryOptions.nonContextual()).stream() Optional<Node> match = holder.resolveInheritedNodes(QueryOptions.nonContextual()).stream()
.filter(n -> n.getKey().equalsIgnoreCase(node) && n.getContexts().equals(context)) .filter(n -> n.getKey().equalsIgnoreCase(node) && n.getContexts().equals(context))
.findFirst(); .findFirst();

View File

@ -81,6 +81,7 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
if (this.extensions.stream().anyMatch(e -> e.instance.equals(extension))) { if (this.extensions.stream().anyMatch(e -> e.instance.equals(extension))) {
return; return;
} }
this.plugin.getLogger().info("Loading extension: " + extension.getClass().getName());
this.extensions.add(new LoadedExtension(extension, null, null)); this.extensions.add(new LoadedExtension(extension, null, null));
extension.load(); extension.load();
this.plugin.getEventFactory().handleExtensionLoad(extension); this.plugin.getEventFactory().handleExtensionLoad(extension);
@ -93,10 +94,12 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
try (Stream<Path> stream = Files.list(directory)) { try (Stream<Path> stream = Files.list(directory)) {
stream.forEach(path -> { stream.forEach(path -> {
if (path.getFileName().toString().endsWith(".jar")) {
try { try {
loadExtension(path); loadExtension(path);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); new RuntimeException("Exception loading extension from " + path, e).printStackTrace();
}
} }
}); });
} catch (IOException e) { } catch (IOException e) {
@ -119,7 +122,7 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
try (InputStream in = classLoader.getResourceAsStream("extension.json")) { try (InputStream in = classLoader.getResourceAsStream("extension.json")) {
if (in == null) { if (in == null) {
throw new RuntimeException("extension.json not present in " + path.toString()); throw new IllegalStateException("extension.json not present");
} }
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
JsonElement parsed = GsonProvider.parser().parse(reader); JsonElement parsed = GsonProvider.parser().parse(reader);
@ -138,6 +141,8 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
this.plugin.getLogger().info("Loading extension: " + extensionClass.getName() + " (" + path.getFileName().toString() + ")");
Extension extension = null; Extension extension = null;
try { try {
@ -153,7 +158,9 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
try { try {
Constructor<? extends Extension> constructor = extensionClass.getConstructor(); Constructor<? extends Extension> constructor = extensionClass.getConstructor();
extension = constructor.newInstance(); extension = constructor.newInstance();
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { } catch (NoSuchMethodException e) {
throw new RuntimeException("Unable to find valid constructor in " + extensionClass.getName());
} catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

View File

@ -32,9 +32,7 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import net.luckperms.api.context.DefaultContextKeys;
import net.luckperms.api.node.types.InheritanceNode; import net.luckperms.api.node.types.InheritanceNode;
import net.luckperms.api.query.Flag;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList; import java.util.ArrayList;
@ -62,12 +60,6 @@ public class InheritanceGraph implements Graph<PermissionHolder> {
public Iterable<? extends PermissionHolder> successors(PermissionHolder holder) { public Iterable<? extends PermissionHolder> successors(PermissionHolder holder) {
Set<Group> successors = new LinkedHashSet<>(); Set<Group> successors = new LinkedHashSet<>();
for (InheritanceNode n : holder.getOwnInheritanceNodes(this.queryOptions)) { for (InheritanceNode n : holder.getOwnInheritanceNodes(this.queryOptions)) {
// effectively: if not (we're applying global groups or it's specific anyways)
if (!((this.queryOptions.flag(Flag.APPLY_INHERITANCE_NODES_WITHOUT_SERVER_CONTEXT) || n.getContexts().containsKey(DefaultContextKeys.SERVER_KEY)) &&
(this.queryOptions.flag(Flag.APPLY_INHERITANCE_NODES_WITHOUT_WORLD_CONTEXT) || n.getContexts().containsKey(DefaultContextKeys.WORLD_KEY)))) {
continue;
}
Group g = this.plugin.getGroupManager().getIfLoaded(n.getGroupName()); Group g = this.plugin.getGroupManager().getIfLoaded(n.getGroupName());
if (g != null) { if (g != null) {
successors.add(g); successors.add(g);

View File

@ -37,11 +37,13 @@ import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
import me.lucko.luckperms.common.node.model.InheritanceOrigin; import me.lucko.luckperms.common.node.model.InheritanceOrigin;
import net.luckperms.api.context.ContextSet; import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.DefaultContextKeys;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.node.Node; import net.luckperms.api.node.Node;
import net.luckperms.api.node.NodeEqualityPredicate; import net.luckperms.api.node.NodeEqualityPredicate;
import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata; import net.luckperms.api.node.metadata.types.InheritanceOriginMetadata;
import net.luckperms.api.node.types.InheritanceNode; import net.luckperms.api.node.types.InheritanceNode;
import net.luckperms.api.query.Flag;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
@ -135,18 +137,43 @@ public final class NodeMap {
public void copyTo(Collection<? super Node> collection, QueryOptions filter) { public void copyTo(Collection<? super Node> collection, QueryOptions filter) {
for (Map.Entry<ImmutableContextSet, SortedSet<Node>> e : this.map.entrySet()) { for (Map.Entry<ImmutableContextSet, SortedSet<Node>> e : this.map.entrySet()) {
if (filter.satisfies(e.getKey())) { if (filter.satisfies(e.getKey())) {
boolean serverMissing = !e.getKey().containsKey(DefaultContextKeys.SERVER_KEY);
boolean worldMissing = !e.getKey().containsKey(DefaultContextKeys.WORLD_KEY);
boolean excludeAsServerMissing = !filter.flag(Flag.INCLUDE_NODES_WITHOUT_SERVER_CONTEXT) && serverMissing;
boolean excludeAsWorldMissing = !filter.flag(Flag.INCLUDE_NODES_WITHOUT_WORLD_CONTEXT) && worldMissing;
if (excludeAsServerMissing || excludeAsWorldMissing) {
boolean excludeInheritanceAsServerMissing = !filter.flag(Flag.APPLY_INHERITANCE_NODES_WITHOUT_SERVER_CONTEXT) && serverMissing;
boolean excludeInheritanceAsWorldMissing = !filter.flag(Flag.APPLY_INHERITANCE_NODES_WITHOUT_WORLD_CONTEXT) && worldMissing;
if (!excludeInheritanceAsServerMissing && !excludeInheritanceAsWorldMissing) {
// only copy inheritance nodes.
SortedSet<InheritanceNode> inheritanceNodes = this.inheritanceMap.get(e.getKey());
if (inheritanceNodes != null) {
collection.addAll(inheritanceNodes);
}
}
} else {
collection.addAll(e.getValue()); collection.addAll(e.getValue());
} }
} }
} }
}
public void copyInheritanceNodesTo(Collection<? super InheritanceNode> collection, QueryOptions filter) { public void copyInheritanceNodesTo(Collection<? super InheritanceNode> collection, QueryOptions filter) {
for (Map.Entry<ImmutableContextSet, SortedSet<InheritanceNode>> e : this.inheritanceMap.entrySet()) { for (Map.Entry<ImmutableContextSet, SortedSet<InheritanceNode>> e : this.inheritanceMap.entrySet()) {
if (filter.satisfies(e.getKey())) { if (filter.satisfies(e.getKey())) {
boolean serverMissing = !e.getKey().containsKey(DefaultContextKeys.SERVER_KEY);
boolean worldMissing = !e.getKey().containsKey(DefaultContextKeys.WORLD_KEY);
boolean excludeInheritanceAsServerMissing = !filter.flag(Flag.APPLY_INHERITANCE_NODES_WITHOUT_SERVER_CONTEXT) && serverMissing;
boolean excludeInheritanceAsWorldMissing = !filter.flag(Flag.APPLY_INHERITANCE_NODES_WITHOUT_WORLD_CONTEXT) && worldMissing;
if (!excludeInheritanceAsServerMissing && !excludeInheritanceAsWorldMissing) {
collection.addAll(e.getValue()); collection.addAll(e.getValue());
} }
} }
} }
}
/** /**
* Returns an immutable representation of the maps current state. * Returns an immutable representation of the maps current state.

View File

@ -37,7 +37,6 @@ import me.lucko.luckperms.common.node.comparator.NodeWithContextComparator;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import net.luckperms.api.context.ContextSet; import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.DefaultContextKeys;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.DataMutateResult; import net.luckperms.api.model.DataMutateResult;
import net.luckperms.api.model.DataType; import net.luckperms.api.model.DataType;
@ -63,7 +62,6 @@ import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.OptionalInt; import java.util.OptionalInt;
@ -279,41 +277,33 @@ public abstract class PermissionHolder {
return ret; return ret;
} }
public void accumulateInheritancesTo(List<? super Node> accumulator, QueryOptions queryOptions) { private void accumulateInheritedNodesTo(Collection<Node> accumulator, QueryOptions queryOptions) {
if (queryOptions.flag(Flag.RESOLVE_INHERITANCE)) {
InheritanceGraph graph = this.plugin.getInheritanceHandler().getGraph(queryOptions); InheritanceGraph graph = this.plugin.getInheritanceHandler().getGraph(queryOptions);
Iterable<PermissionHolder> traversal = graph.traverse(this); Iterable<PermissionHolder> traversal = graph.traverse(this);
for (PermissionHolder holder : traversal) { for (PermissionHolder holder : traversal) {
List<? extends Node> nodes = holder.getOwnNodes(queryOptions); List<? extends Node> nodes = holder.getOwnNodes(queryOptions);
accumulator.addAll(nodes); accumulator.addAll(nodes);
} }
}
public List<Node> resolveInheritances(QueryOptions queryOptions) {
List<Node> accumulator = new ArrayList<>();
accumulateInheritancesTo(accumulator, queryOptions);
return accumulator;
}
public List<Node> getAllEntries(QueryOptions queryOptions) {
List<Node> entries = new LinkedList<>();
if (queryOptions.flag(Flag.RESOLVE_INHERITANCE)) {
accumulateInheritancesTo(entries, queryOptions);
} else { } else {
entries.addAll(getOwnNodes(queryOptions)); accumulator.addAll(getOwnNodes(queryOptions));
}
} }
if (!queryOptions.flag(Flag.INCLUDE_NODES_WITHOUT_SERVER_CONTEXT)) { public List<Node> resolveInheritedNodes(QueryOptions queryOptions) {
entries.removeIf(n -> !(n instanceof InheritanceNode) && !n.getContexts().containsKey(DefaultContextKeys.SERVER_KEY)); List<Node> ret = new ArrayList<>();
} accumulateInheritedNodesTo(ret, queryOptions);
if (!queryOptions.flag(Flag.INCLUDE_NODES_WITHOUT_WORLD_CONTEXT)) { return ret;
entries.removeIf(n -> !(n instanceof InheritanceNode) && !n.getContexts().containsKey(DefaultContextKeys.WORLD_KEY));
} }
return entries; public SortedSet<Node> resolveInheritedNodesSorted(QueryOptions queryOptions) {
SortedSet<Node> ret = new TreeSet<>(NodeWithContextComparator.reverse());
accumulateInheritedNodesTo(ret, queryOptions);
return ret;
} }
public Map<String, Boolean> exportPermissions(QueryOptions queryOptions, boolean convertToLowercase, boolean resolveShorthand) { public Map<String, Boolean> exportPermissions(QueryOptions queryOptions, boolean convertToLowercase, boolean resolveShorthand) {
List<Node> entries = getAllEntries(queryOptions); List<Node> entries = resolveInheritedNodes(queryOptions);
return processExportedPermissions(entries, convertToLowercase, resolveShorthand); return processExportedPermissions(entries, convertToLowercase, resolveShorthand);
} }
@ -356,12 +346,6 @@ public abstract class PermissionHolder {
if (!node.getValue()) continue; if (!node.getValue()) continue;
if (!NodeType.META_OR_CHAT_META.matches(node)) continue; if (!NodeType.META_OR_CHAT_META.matches(node)) continue;
// effectively: if not (we're applying global groups or it's specific anyways)
if (!((queryOptions.flag(Flag.APPLY_INHERITANCE_NODES_WITHOUT_SERVER_CONTEXT) || node.getContexts().containsKey(DefaultContextKeys.SERVER_KEY)) &&
(queryOptions.flag(Flag.APPLY_INHERITANCE_NODES_WITHOUT_WORLD_CONTEXT) || node.getContexts().containsKey(DefaultContextKeys.WORLD_KEY)))) {
continue;
}
accumulator.accumulateNode(node); accumulator.accumulateNode(node);
} }