Add /lp debug command

This commit is contained in:
Luck 2018-01-24 19:13:29 +00:00
parent 982254ff5e
commit 54dbede130
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
26 changed files with 493 additions and 87 deletions

View File

@ -102,6 +102,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* LuckPerms implementation for the Bukkit API.
*/
@ -505,6 +507,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}
}
@Nullable
@Override
public Contexts getContextForUser(User user) {
Player player = getPlayer(user);

View File

@ -41,8 +41,6 @@ import me.lucko.luckperms.common.processors.RegexProcessor;
import me.lucko.luckperms.common.processors.WildcardProcessor;
import me.lucko.luckperms.common.references.HolderType;
import java.util.List;
public class BukkitCalculatorFactory extends AbstractCalculatorFactory {
private final LPBukkitPlugin plugin;
@ -74,16 +72,4 @@ public class BukkitCalculatorFactory extends AbstractCalculatorFactory {
return registerCalculator(new PermissionCalculator(this.plugin, metadata, processors.build()));
}
@Override
public List<String> getActiveProcessors() {
ImmutableList.Builder<String> ret = ImmutableList.builder();
ret.add("Map");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_CHILD_PERMISSIONS)) ret.add("Child");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_ATTACHMENT_PERMISSIONS)) ret.add("Attachment");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) ret.add("Regex");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLYING_WILDCARDS)) ret.add("Wildcard");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) ret.add("Defaults");
return ret.build();
}
}

View File

@ -90,6 +90,8 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* LuckPerms implementation for the BungeeCord API.
*/
@ -335,6 +337,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
return Optional.empty();
}
@Nullable
@Override
public Contexts getContextForUser(User user) {
ProxiedPlayer player = getPlayer(user);

View File

@ -38,8 +38,6 @@ import me.lucko.luckperms.common.processors.PermissionProcessor;
import me.lucko.luckperms.common.processors.RegexProcessor;
import me.lucko.luckperms.common.processors.WildcardProcessor;
import java.util.List;
public class BungeeCalculatorFactory extends AbstractCalculatorFactory {
private final LPBungeePlugin plugin;
@ -63,13 +61,4 @@ public class BungeeCalculatorFactory extends AbstractCalculatorFactory {
return registerCalculator(new PermissionCalculator(this.plugin, metadata, processors.build()));
}
@Override
public List<String> getActiveProcessors() {
ImmutableList.Builder<String> ret = ImmutableList.builder();
ret.add("Map");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) ret.add("Regex");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLYING_WILDCARDS)) ret.add("Wildcards");
return ret.build();
}
}

View File

@ -37,10 +37,8 @@ import me.lucko.luckperms.common.caching.type.MetaAccumulator;
import me.lucko.luckperms.common.caching.type.MetaCache;
import me.lucko.luckperms.common.caching.type.PermissionCache;
import me.lucko.luckperms.common.calculators.PermissionCalculatorMetadata;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.metastacking.SimpleMetaStack;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.HashSet;
import java.util.Objects;
@ -149,7 +147,7 @@ public abstract class HolderCachedData<T extends PermissionHolder> implements Ca
@Override
public MetaCache getMetaData(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
return getMetaData(makeFromMetaContextsConfig(contexts, this.holder.getPlugin()));
return getMetaData(this.holder.getPlugin().getContextManager().formMetaContexts(contexts));
}
@Nonnull
@ -170,7 +168,7 @@ public abstract class HolderCachedData<T extends PermissionHolder> implements Ca
@Override
public MetaCache calculateMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
return calculateMeta(makeFromMetaContextsConfig(contexts, this.holder.getPlugin()));
return calculateMeta(this.holder.getPlugin().getContextManager().formMetaContexts(contexts));
}
@Override
@ -188,7 +186,7 @@ public abstract class HolderCachedData<T extends PermissionHolder> implements Ca
@Override
public void recalculateMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
recalculateMeta(makeFromMetaContextsConfig(contexts, this.holder.getPlugin()));
recalculateMeta(this.holder.getPlugin().getContextManager().formMetaContexts(contexts));
}
@Nonnull
@ -225,7 +223,7 @@ public abstract class HolderCachedData<T extends PermissionHolder> implements Ca
@Override
public CompletableFuture<MetaCache> reloadMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
return reloadMeta(makeFromMetaContextsConfig(contexts, this.holder.getPlugin()));
return reloadMeta(this.holder.getPlugin().getContextManager().formMetaContexts(contexts));
}
@Override
@ -279,7 +277,7 @@ public abstract class HolderCachedData<T extends PermissionHolder> implements Ca
@Override
public void invalidateMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
this.meta.invalidate(makeFromMetaContextsConfig(contexts, this.holder.getPlugin()));
this.meta.invalidate(this.holder.getPlugin().getContextManager().formMetaContexts(contexts));
}
@Override
@ -321,14 +319,6 @@ public abstract class HolderCachedData<T extends PermissionHolder> implements Ca
}
}
private static MetaContexts makeFromMetaContextsConfig(Contexts contexts, LuckPermsPlugin plugin) {
return new MetaContexts(
contexts,
plugin.getConfiguration().get(ConfigKeys.PREFIX_FORMATTING_OPTIONS),
plugin.getConfiguration().get(ConfigKeys.SUFFIX_FORMATTING_OPTIONS)
);
}
private static MetaAccumulator newAccumulator(MetaContexts contexts) {
return new MetaAccumulator(
new SimpleMetaStack(contexts.getPrefixStackDefinition(), ChatMetaType.PREFIX),

View File

@ -93,6 +93,10 @@ public class PermissionCache implements PermissionData {
}
}
public PermissionCalculator getCalculator() {
return this.calculator;
}
@Nonnull
@Override
public Map<String, Boolean> getImmutableBacking() {

View File

@ -27,8 +27,6 @@ package me.lucko.luckperms.common.calculators;
import me.lucko.luckperms.api.Contexts;
import java.util.List;
/**
* Creates a calculator instance given a set of contexts
*/
@ -43,13 +41,6 @@ public interface CalculatorFactory {
*/
PermissionCalculator build(Contexts contexts, PermissionCalculatorMetadata metadata);
/**
* Gets the processors which are currently being added to built calculators
*
* @return a list of processors
*/
List<String> getActiveProcessors();
/**
* Invalidates all calculators build by this factory
*/

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.common.calculators;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -45,17 +46,21 @@ import javax.annotation.Nonnull;
public class PermissionCalculator implements CacheLoader<String, Tristate> {
private final LuckPermsPlugin plugin;
private final PermissionCalculatorMetadata metadata;
private final List<PermissionProcessor> processors;
private final ImmutableList<PermissionProcessor> processors;
// caches lookup calls.
private final LoadingCache<String, Tristate> lookupCache = Caffeine.newBuilder().build(this);
public PermissionCalculator(LuckPermsPlugin plugin, PermissionCalculatorMetadata metadata, List<PermissionProcessor> processors) {
public PermissionCalculator(LuckPermsPlugin plugin, PermissionCalculatorMetadata metadata, ImmutableList<PermissionProcessor> processors) {
this.plugin = plugin;
this.metadata = metadata;
this.processors = processors;
}
public List<PermissionProcessor> getProcessors() {
return this.processors;
}
public void invalidateCache() {
this.lookupCache.invalidateAll();
}

View File

@ -37,6 +37,7 @@ import me.lucko.luckperms.common.commands.impl.migration.MigrationMainCommand;
import me.lucko.luckperms.common.commands.impl.misc.ApplyEditsCommand;
import me.lucko.luckperms.common.commands.impl.misc.BulkUpdateCommand;
import me.lucko.luckperms.common.commands.impl.misc.CheckCommand;
import me.lucko.luckperms.common.commands.impl.misc.DebugCommand;
import me.lucko.luckperms.common.commands.impl.misc.ExportCommand;
import me.lucko.luckperms.common.commands.impl.misc.ImportCommand;
import me.lucko.luckperms.common.commands.impl.misc.InfoCommand;
@ -108,6 +109,7 @@ public class CommandManager {
.add(new LogMainCommand(locale))
.add(new SyncCommand(locale))
.add(new InfoCommand(locale))
.add(new DebugCommand(locale))
.add(new VerboseCommand(locale))
.add(new TreeCommand(locale))
.add(new SearchCommand(locale))

View File

@ -41,6 +41,7 @@ public enum CommandPermission {
SYNC("sync", NONE),
INFO("info", NONE),
DEBUG("debug", NONE),
VERBOSE("verbose", NONE),
TREE("tree", NONE),
SEARCH("search", NONE),

View File

@ -0,0 +1,373 @@
/*
* 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.commands.impl.misc;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.caching.MetaContexts;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.StaticContextCalculator;
import me.lucko.luckperms.api.metastacking.MetaStackDefinition;
import me.lucko.luckperms.api.metastacking.MetaStackElement;
import me.lucko.luckperms.common.caching.type.MetaCache;
import me.lucko.luckperms.common.caching.type.PermissionCache;
import me.lucko.luckperms.common.commands.CommandPermission;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.abstraction.SingleCommand;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.contexts.ContextSetJsonSerializer;
import me.lucko.luckperms.common.contexts.ProxiedContextCalculator;
import me.lucko.luckperms.common.locale.CommandSpec;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.processors.PermissionProcessor;
import me.lucko.luckperms.common.utils.PasteUtils;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.common.utils.TextUtils;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Collectors;
public class DebugCommand extends SingleCommand {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
public DebugCommand(LocaleManager locale) {
super(CommandSpec.DEBUG.spec(locale), "Debug", CommandPermission.DEBUG, Predicates.alwaysFalse());
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
Message.DEBUG_START.send(sender);
Map<String, String> pages = new LinkedHashMap<>();
pages.put("__DEBUG__.md", TextUtils.joinNewline("# Debug Output", "The debugging data can be found in the files below."));
pages.put("platform.json", GSON.toJson(getPlatformData(plugin).toJson()));
pages.put("storage.json", GSON.toJson(getStorageData(plugin).toJson()));
pages.put("context.json", GSON.toJson(getContextData(plugin).toJson()));
pages.put("players.json", GSON.toJson(getPlayersData(plugin).toJson()));
String url = PasteUtils.paste("LuckPerms Debug Output", pages.entrySet());
Message.DEBUG_URL.send(sender);
Component message = TextComponent.builder(url).color(TextColor.AQUA)
.clickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, String.valueOf(url)))
.hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to open the debugging data.").color(TextColor.GRAY)))
.build();
sender.sendMessage(message);
return CommandResult.SUCCESS;
}
private static JObject getPlatformData(LuckPermsPlugin plugin) {
return new JObject()
.add("type", plugin.getServerType().name())
.add("version", new JObject()
.add("api", String.valueOf(plugin.getApiProvider().getPlatformInfo().getApiVersion()))
.add("plugin", plugin.getVersion())
)
.add("server", new JObject()
.add("brand", plugin.getServerBrand())
.add("version", plugin.getServerVersion())
);
}
private static JObject getStorageData(LuckPermsPlugin plugin) {
return new JObject()
.add("storage", new JObject()
.add("name", plugin.getStorage().getName())
.add("type", plugin.getStorage().getDao().getClass().getName())
.add("meta", () -> {
JObject metaObject = new JObject();
Map<String, String> meta = plugin.getStorage().getMeta();
for (Map.Entry<String, String> entry : meta.entrySet()) {
metaObject.add(entry.getKey(), entry.getValue());
}
return metaObject;
}))
.add("messaging", () -> {
JObject messaging = new JObject();
plugin.getMessagingService().ifPresent(ms -> {
messaging.add("name", ms.getName());
messaging.add("implementation", new JObject()
.add("messenger", ms.getMessenger().getClass().getName())
.add("provider", ms.getMessengerProvider().getClass().getName())
);
});
return messaging;
});
}
private static JObject getContextData(LuckPermsPlugin plugin) {
return new JObject()
.add("staticContext", ContextSetJsonSerializer.serializeContextSet(plugin.getContextManager().getStaticContext()))
.add("calculators", () -> {
JArray calculators = new JArray();
for (ContextCalculator<?> calculator : plugin.getContextManager().getCalculators()) {
String name = calculator.getClass().getName();
if (calculator instanceof ProxiedContextCalculator) {
name = ((ProxiedContextCalculator) calculator).getDelegate().getClass().getName();
}
calculators.add(name);
}
return calculators;
})
.add("staticCalculators", () -> {
JArray staticCalculators = new JArray();
for (StaticContextCalculator calculator : plugin.getContextManager().getStaticCalculators()) {
staticCalculators.add(calculator.getClass().getName());
}
return staticCalculators;
});
}
private static JObject getPlayersData(LuckPermsPlugin plugin) {
JObject ret = new JObject();
Set<UUID> onlinePlayers = plugin.getOnlinePlayers().collect(Collectors.toSet());
ret.add("count", onlinePlayers.size());
JArray playerArray = new JArray();
for (UUID uuid : onlinePlayers) {
User user = plugin.getUserManager().getIfLoaded(uuid);
if (user == null) {
playerArray.add(new JObject()
.add("uniqueId", uuid.toString())
.add("loaded", false)
);
continue;
}
playerArray.add(new JObject()
.add("uniqueId", uuid.toString())
.add("loaded", true)
.add("username", user.getName().orElse("null"))
.add("primaryGroup", new JObject()
.add("type", user.getPrimaryGroup().getClass().getName())
.add("value", user.getPrimaryGroup().getValue())
.add("storedValue", user.getPrimaryGroup().getStoredValue().orElse("null"))
)
.add("activeContext", () -> {
JObject obj = new JObject();
Contexts contexts = plugin.getContextForUser(user);
if (contexts != null) {
MetaContexts metaContexts = plugin.getContextManager().formMetaContexts(contexts);
obj.add("data", new JObject()
.add("permissions", serializePermissionsData(user.getCachedData().getPermissionData(contexts)))
.add("meta", serializeMetaData(user.getCachedData().getMetaData(metaContexts)))
)
.add("contextSet", ContextSetJsonSerializer.serializeContextSet(contexts.getContexts()))
.add("settings", serializeContextsSettings(contexts))
.add("metaSettings", serializeMetaContextsSettings(metaContexts));
}
return obj;
})
);
}
ret.add("players", playerArray);
return ret;
}
private static JObject serializeContextsSettings(Contexts contexts) {
return new JObject()
.add("op", contexts.isOp())
.add("includeGlobal", contexts.isIncludeGlobal())
.add("includeGlobalWorld", contexts.isIncludeGlobalWorld())
.add("applyGroups", contexts.isApplyGroups())
.add("applyGlobalGroups", contexts.isApplyGlobalGroups())
.add("applyGlobalWorldGroups", contexts.isApplyGlobalWorldGroups());
}
private static JObject serializeMetaContextsSettings(MetaContexts metaContexts) {
return new JObject()
.add("prefixStack", serializeMetaStackData(metaContexts.getPrefixStackDefinition()))
.add("suffixStack", serializeMetaStackData(metaContexts.getSuffixStackDefinition()));
}
private static JObject serializePermissionsData(PermissionCache permissionData) {
return new JObject()
.add("processors", () -> {
JArray processors = new JArray();
for (PermissionProcessor processor : permissionData.getCalculator().getProcessors()) {
processors.add(processor.getClass().getName());
}
return processors;
});
}
private static JObject serializeMetaData(MetaCache metaData) {
return new JObject()
.add("prefix", metaData.getPrefix())
.add("suffix", metaData.getSuffix())
.add("prefixes", () -> {
JArray prefixes = new JArray();
for (Map.Entry<Integer, String> entry : metaData.getPrefixes().entrySet()) {
prefixes.add(new JObject()
.add("weight", entry.getKey())
.add("value", entry.getValue())
);
}
return prefixes;
})
.add("suffixes", () -> {
JArray suffixes = new JArray();
for (Map.Entry<Integer, String> entry : metaData.getSuffixes().entrySet()) {
suffixes.add(new JObject()
.add("weight", entry.getKey())
.add("value", entry.getValue())
);
}
return suffixes;
})
.add("meta", () -> {
JObject metaMap = new JObject();
for (Map.Entry<String, String> entry : metaData.getMeta().entrySet()) {
metaMap.add(entry.getKey(), entry.getValue());
}
return metaMap;
})
.add("metaMap", () -> {
JObject metaMultimap = new JObject();
for (Map.Entry<String, Collection<String>> entry : metaData.getMetaMultimap().asMap().entrySet()) {
JArray values = new JArray();
for (String v : entry.getValue()) {
values.add(v);
}
metaMultimap.add(entry.getKey(), values);
}
return metaMultimap;
});
}
private static JObject serializeMetaStackData(MetaStackDefinition definition) {
return new JObject()
.add("type", definition.getClass().getName())
.add("startSpacer", definition.getStartSpacer())
.add("middleSpacer", definition.getMiddleSpacer())
.add("endSpacer", definition.getEndSpacer())
.add("elements", () -> {
JArray elements = new JArray();
for (MetaStackElement element : definition.getElements()) {
elements.add(new JObject()
.add("type", element.getClass().getName())
.add("info", element.toString())
);
}
return elements;
});
}
// stupidly simply fluent gson wrappers
private interface JElement {
JsonElement toJson();
}
private static final class JObject implements JElement {
private final JsonObject o = new JsonObject();
@Override
public JsonElement toJson() {
return this.o;
}
public JObject add(String key, String value) {
this.o.addProperty(key, value);
return this;
}
public JObject add(String key, Number value) {
this.o.addProperty(key, value);
return this;
}
public JObject add(String key, Boolean value) {
this.o.addProperty(key, value);
return this;
}
public JObject add(String key, JsonElement value) {
this.o.add(key, value);
return this;
}
public JObject add(String key, JElement value) {
return add(key, value.toJson());
}
public JObject add(String key, Supplier<? extends JElement> value) {
return add(key, value.get().toJson());
}
}
private static final class JArray implements JElement {
private final JsonArray o = new JsonArray();
@Override
public JsonElement toJson() {
return this.o;
}
public JArray add(String value) {
this.o.add(value);
return this;
}
public JArray add(JsonElement value) {
this.o.add(value);
return this;
}
public JArray add(JElement value) {
return add(value.toJson());
}
public JArray add(Supplier<? extends JElement> value) {
return add(value.get().toJson());
}
}
}

View File

@ -28,8 +28,10 @@ package me.lucko.luckperms.common.contexts;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.caching.MetaContexts;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
@ -80,6 +82,16 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
this.subjectClass = subjectClass;
}
@Override
public List<ContextCalculator<? super T>> getCalculators() {
return ImmutableList.copyOf(this.calculators);
}
@Override
public List<StaticContextCalculator> getStaticCalculators() {
return ImmutableList.copyOf(this.staticCalculators);
}
@Override
public Class<T> getSubjectClass() {
return this.subjectClass;
@ -146,6 +158,15 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
);
}
@Override
public MetaContexts formMetaContexts(Contexts contexts) {
return new MetaContexts(
contexts,
this.plugin.getConfiguration().get(ConfigKeys.PREFIX_FORMATTING_OPTIONS),
this.plugin.getConfiguration().get(ConfigKeys.SUFFIX_FORMATTING_OPTIONS)
);
}
@Override
public void registerCalculator(ContextCalculator<? super T> calculator) {
// calculators registered first should have priority (and be checked last.)
@ -167,11 +188,6 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
this.lookupCache.invalidate(subject);
}
@Override
public int getCalculatorsSize() {
return this.calculators.size();
}
private final class Loader implements CacheLoader<T, Contexts> {
@Override
public Contexts load(@Nonnull T subject) {

View File

@ -26,10 +26,12 @@
package me.lucko.luckperms.common.contexts;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.caching.MetaContexts;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.StaticContextCalculator;
import java.util.List;
import java.util.Optional;
/**
@ -103,6 +105,14 @@ public interface ContextManager<T> {
*/
Contexts formContexts(ImmutableContextSet contextSet);
/**
* Forms a "default" {@link MetaContexts} instance from {@link Contexts}.
*
* @param contexts the contexts
* @return a contexts instance
*/
MetaContexts formMetaContexts(Contexts contexts);
/**
* Registers a context calculator with the manager.
*
@ -125,10 +135,17 @@ public interface ContextManager<T> {
void invalidateCache(T subject);
/**
* Gets the number of calculators registered with the manager.
* Gets the calculators registered on the platform
*
* @return the number of calculators registered
* @return the registered calculators
*/
int getCalculatorsSize();
List<ContextCalculator<? super T>> getCalculators();
/**
* Gets the static calculators registered on the platform
*
* @return the registered static calculators
*/
List<StaticContextCalculator> getStaticCalculators();
}

View File

@ -49,6 +49,7 @@ public enum CommandSpec {
SYNC("Sync changes with the storage", "/%s sync"),
INFO("Print general plugin info", "/%s info"),
DEBUG("Produce debugging output", "/%s debug"),
VERBOSE("Manage verbose permission checking", "/%s verbose <true|false> [filter]",
Arg.list(
Arg.create("on|record|off|paste", true, "whether to enable/disable logging, or to paste the logged output"),

View File

@ -190,6 +190,9 @@ public enum Message {
false
),
DEBUG_START("&bGenerating debugging output...", true),
DEBUG_URL("&aDebug data URL:", true),
CREATE_ERROR("&cThere was an error whilst creating &4{}&c.", true),
DELETE_ERROR("&cThere was an error whilst deleting &4{}&c.", true),

View File

@ -26,6 +26,8 @@
package me.lucko.luckperms.common.messaging;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.messenger.Messenger;
import me.lucko.luckperms.api.messenger.MessengerProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.model.User;
@ -38,6 +40,10 @@ public interface InternalMessagingService {
*/
String getName();
Messenger getMessenger();
MessengerProvider getMessengerProvider();
/**
* Closes the messaging service
*/

View File

@ -74,6 +74,16 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
return this.messengerProvider.getName();
}
@Override
public Messenger getMessenger() {
return this.messenger;
}
@Override
public MessengerProvider getMessengerProvider() {
return this.messengerProvider;
}
@Override
public void close() {
this.messenger.close();

View File

@ -62,6 +62,8 @@ import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* Main internal interface for LuckPerms plugins, providing the base for
* abstraction throughout the project.
@ -322,6 +324,7 @@ public interface LuckPermsPlugin {
* @param user the user instance
* @return a contexts object, or null if one couldn't be generated
*/
@Nullable
Contexts getContextForUser(User user);
/**

View File

@ -72,6 +72,11 @@ public class AbstractStorage implements Storage {
this.delegate = new ApiStorage(plugin, this);
}
@Override
public AbstractDao getDao() {
return this.dao;
}
private <T> CompletableFuture<T> makeFuture(Callable<T> supplier) {
return CompletableFuture.supplyAsync(() -> {
try {

View File

@ -35,6 +35,7 @@ import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
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.storage.dao.AbstractDao;
import java.util.List;
import java.util.Map;
@ -50,6 +51,8 @@ public interface Storage {
ApiStorage getDelegate();
AbstractDao getDao();
String getName();
Storage noBuffer();

View File

@ -37,6 +37,7 @@ 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.storage.Storage;
import me.lucko.luckperms.common.storage.dao.AbstractDao;
import java.util.List;
import java.util.Map;
@ -106,6 +107,11 @@ public class BufferedOutputStorage implements Storage, Runnable {
// delegate
@Override
public AbstractDao getDao() {
return this.delegate.getDao();
}
@Override
public CompletableFuture<Set<UUID>> getUniqueUsers() {
return this.delegate.getUniqueUsers();

View File

@ -36,6 +36,7 @@ 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.storage.Storage;
import me.lucko.luckperms.common.storage.dao.AbstractDao;
import java.util.List;
import java.util.Map;
@ -62,6 +63,11 @@ public class PhasedStorage implements Storage {
this.delegate = delegate;
}
@Override
public AbstractDao getDao() {
return this.delegate.getDao();
}
@Override
public ApiStorage getDelegate() {
return this.delegate.getDelegate();

View File

@ -37,7 +37,6 @@ import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
/**
@ -54,7 +53,7 @@ public class PasteUtils {
* @param files the files to include in the gist (file name --> content)
* @return the url, or null
*/
public static String paste(String desc, List<Map.Entry<String, String>> files) {
public static String paste(String desc, Iterable<Map.Entry<String, String>> files) {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(GIST_API).openConnection();

View File

@ -121,6 +121,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* LuckPerms implementation for the Sponge API.
*/
@ -422,6 +424,7 @@ public class LPSpongePlugin implements LuckPermsSpongePlugin {
}
}
@Nullable
@Override
public Contexts getContextForUser(User user) {
Player player = getPlayer(user);

View File

@ -42,8 +42,6 @@ import me.lucko.luckperms.sponge.processors.GroupDefaultsProcessor;
import me.lucko.luckperms.sponge.processors.SpongeWildcardProcessor;
import me.lucko.luckperms.sponge.processors.UserDefaultsProcessor;
import java.util.List;
public class SpongeCalculatorFactory extends AbstractCalculatorFactory {
private final LPSpongePlugin plugin;
@ -79,15 +77,4 @@ public class SpongeCalculatorFactory extends AbstractCalculatorFactory {
return registerCalculator(new PermissionCalculator(this.plugin, metadata, processors.build()));
}
@Override
public List<String> getActiveProcessors() {
ImmutableList.Builder<String> ret = ImmutableList.builder();
ret.add("Map");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_SPONGE_IMPLICIT_WILDCARDS)) ret.add("SpongeWildcard");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) ret.add("Regex");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLYING_WILDCARDS)) ret.add("Wildcard");
if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_SPONGE_DEFAULT_SUBJECTS)) ret.add("Defaults");
return ret.build();
}
}

View File

@ -25,7 +25,6 @@
package me.lucko.luckperms.sponge.service.calculated;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
@ -57,8 +56,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
/**
* In-memory implementation of {@link LPSubjectData}.
*/
@ -75,18 +72,15 @@ public class CalculatedSubjectData implements LPSubjectData {
private final LoadingCache<ImmutableContextSet, CalculatorHolder> permissionCache = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.build(new CacheLoader<ImmutableContextSet, CalculatorHolder>() {
@Override
public CalculatorHolder load(@Nonnull ImmutableContextSet contexts) {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
processors.add(new MapProcessor());
processors.add(new SpongeWildcardProcessor());
.build(contexts -> {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
processors.add(new MapProcessor());
processors.add(new SpongeWildcardProcessor());
CalculatorHolder holder = new CalculatorHolder(new PermissionCalculator(CalculatedSubjectData.this.service.getPlugin(), PermissionCalculatorMetadata.of(HolderType.GROUP, CalculatedSubjectData.this.calculatorDisplayName, contexts), processors.build()));
holder.setPermissions(flattenMap(getRelevantEntries(contexts, CalculatedSubjectData.this.permissions)));
CalculatorHolder holder = new CalculatorHolder(new PermissionCalculator(CalculatedSubjectData.this.service.getPlugin(), PermissionCalculatorMetadata.of(HolderType.GROUP, CalculatedSubjectData.this.calculatorDisplayName, contexts), processors.build()));
holder.setPermissions(flattenMap(getRelevantEntries(contexts, CalculatedSubjectData.this.permissions)));
return holder;
}
return holder;
});
public CalculatedSubjectData(LPSubject parentSubject, LPPermissionService service, String calculatorDisplayName) {