Implement Sponge timings

This commit is contained in:
Luck 2016-10-30 19:35:11 +00:00
parent 17b06c39e9
commit 36bc1553c0
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
13 changed files with 818 additions and 603 deletions

View File

@ -53,6 +53,7 @@ import me.lucko.luckperms.common.utils.LocaleManager;
import me.lucko.luckperms.common.utils.LogFactory; import me.lucko.luckperms.common.utils.LogFactory;
import me.lucko.luckperms.sponge.contexts.WorldCalculator; import me.lucko.luckperms.sponge.contexts.WorldCalculator;
import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.timings.LPTimings;
import me.lucko.luckperms.sponge.utils.VersionData; import me.lucko.luckperms.sponge.utils.VersionData;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.spongepowered.api.Game; import org.spongepowered.api.Game;
@ -102,6 +103,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
private Path configDir; private Path configDir;
private Scheduler scheduler = Sponge.getScheduler(); private Scheduler scheduler = Sponge.getScheduler();
private LPTimings timings;
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet(); private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
private LPConfiguration configuration; private LPConfiguration configuration;
@ -126,6 +128,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
public void onEnable(GamePreInitializationEvent event) { public void onEnable(GamePreInitializationEvent event) {
log = LogFactory.wrap(logger); log = LogFactory.wrap(logger);
debugHandler = new DebugHandler(); debugHandler = new DebugHandler();
timings = new LPTimings(this);
getLog().info("Loading configuration..."); getLog().info("Loading configuration...");
configuration = new SpongeConfig(this); configuration = new SpongeConfig(this);

View File

@ -22,12 +22,13 @@
package me.lucko.luckperms.sponge; package me.lucko.luckperms.sponge;
import co.aikar.timings.Timing;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import me.lucko.luckperms.api.data.Callback; import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.CommandManager; import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.Util; import me.lucko.luckperms.common.commands.Util;
import me.lucko.luckperms.common.constants.Patterns; import me.lucko.luckperms.common.constants.Patterns;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.command.CommandCallable; import org.spongepowered.api.command.CommandCallable;
import org.spongepowered.api.command.CommandException; import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.command.CommandResult; import org.spongepowered.api.command.CommandResult;
@ -42,28 +43,37 @@ import java.util.Optional;
@SuppressWarnings("NullableProblems") @SuppressWarnings("NullableProblems")
class SpongeCommand extends CommandManager implements CommandCallable { class SpongeCommand extends CommandManager implements CommandCallable {
SpongeCommand(LuckPermsPlugin plugin) { private final LPSpongePlugin plugin;
SpongeCommand(LPSpongePlugin plugin) {
super(plugin); super(plugin);
this.plugin = plugin;
} }
@Override @Override
public CommandResult process(CommandSource source, String s) throws CommandException { public CommandResult process(CommandSource source, String s) throws CommandException {
onCommand( try (Timing ignored = plugin.getTimings().time(LPTiming.ON_COMMAND)) {
SpongeSenderFactory.get(getPlugin()).wrap(source), onCommand(
"perms", SpongeSenderFactory.get(getPlugin()).wrap(source),
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(s)), "perms",
Callback.empty() Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(s)),
); Callback.empty()
return CommandResult.success(); );
return CommandResult.success();
}
} }
@Override @Override
public List<String> getSuggestions(CommandSource source, String s, @Nullable Location<World> location) throws CommandException { public List<String> getSuggestions(CommandSource source, String s, @Nullable Location<World> location) throws CommandException {
return onTabComplete(SpongeSenderFactory.get(getPlugin()).wrap(source), Splitter.on(' ').splitToList(s)); try (Timing ignored = plugin.getTimings().time(LPTiming.COMMAND_TAB_COMPLETE)) {
return onTabComplete(SpongeSenderFactory.get(getPlugin()).wrap(source), Splitter.on(' ').splitToList(s));
}
} }
public List<String> getSuggestions(CommandSource source, String s) throws CommandException { public List<String> getSuggestions(CommandSource source, String s) throws CommandException {
return onTabComplete(SpongeSenderFactory.get(getPlugin()).wrap(source), Splitter.on(' ').splitToList(s)); try (Timing ignored = plugin.getTimings().time(LPTiming.COMMAND_TAB_COMPLETE)) {
return onTabComplete(SpongeSenderFactory.get(getPlugin()).wrap(source), Splitter.on(' ').splitToList(s));
}
} }
@Override @Override

View File

@ -22,11 +22,13 @@
package me.lucko.luckperms.sponge; package me.lucko.luckperms.sponge;
import co.aikar.timings.Timing;
import me.lucko.luckperms.api.caching.UserData; import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.context.MutableContextSet; import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.constants.Message; import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.users.User; import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.AbstractListener; import me.lucko.luckperms.common.utils.AbstractListener;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order; import org.spongepowered.api.event.Order;
@ -63,36 +65,38 @@ public class SpongeListener extends AbstractListener {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Listener(order = Order.EARLY) @Listener(order = Order.EARLY)
public void onClientLogin(ClientConnectionEvent.Login e) { public void onClientLogin(ClientConnectionEvent.Login e) {
final GameProfile player = e.getProfile(); try (Timing ignored = plugin.getTimings().time(LPTiming.ON_CLIENT_LOGIN)) {
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId())); final GameProfile player = e.getProfile();
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
// Check if the user was loaded successfully. // Check if the user was loaded successfully.
if (user == null) { if (user == null) {
e.setCancelled(true); e.setCancelled(true);
e.setMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(Message.LOADING_ERROR.toString())); e.setMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(Message.LOADING_ERROR.toString()));
return; return;
} }
// Attempt to pre-process some permissions for the user to save time later. Might not work, but it's better than nothing. // Attempt to pre-process some permissions for the user to save time later. Might not work, but it's better than nothing.
Optional<Player> p = e.getCause().first(Player.class); Optional<Player> p = e.getCause().first(Player.class);
if (p.isPresent()) { if (p.isPresent()) {
MutableContextSet context = MutableContextSet.fromSet(plugin.getContextManager().getApplicableContext(p.get())); MutableContextSet context = MutableContextSet.fromSet(plugin.getContextManager().getApplicableContext(p.get()));
List<String> worlds = plugin.getGame().getServer().getWorlds().stream() List<String> worlds = plugin.getGame().getServer().getWorlds().stream()
.map(World::getName) .map(World::getName)
.collect(Collectors.toList()); .collect(Collectors.toList());
plugin.doAsync(() -> { plugin.doAsync(() -> {
UserData data = user.getUserData(); UserData data = user.getUserData();
data.preCalculate(plugin.getService().calculateContexts(context)); data.preCalculate(plugin.getService().calculateContexts(context));
for (String world : worlds) { for (String world : worlds) {
MutableContextSet modified = MutableContextSet.fromSet(context); MutableContextSet modified = MutableContextSet.fromSet(context);
modified.removeAll("world"); modified.removeAll("world");
modified.add("world", world); modified.add("world", world);
data.preCalculate(plugin.getService().calculateContexts(modified)); data.preCalculate(plugin.getService().calculateContexts(modified));
} }
}); });
}
} }
} }
@ -104,7 +108,9 @@ public class SpongeListener extends AbstractListener {
@Listener(order = Order.LAST) @Listener(order = Order.LAST)
public void onClientLeave(ClientConnectionEvent.Disconnect e) { public void onClientLeave(ClientConnectionEvent.Disconnect e) {
onLeave(e.getTargetEntity().getUniqueId()); try (Timing ignored = plugin.getTimings().time(LPTiming.ON_CLIENT_LEAVE)) {
plugin.getService().getUserSubjects().unload(plugin.getUuidCache().getUUID(e.getTargetEntity().getUniqueId())); onLeave(e.getTargetEntity().getUniqueId());
plugin.getService().getUserSubjects().unload(plugin.getUuidCache().getUUID(e.getTargetEntity().getUniqueId()));
}
} }
} }

View File

@ -22,6 +22,7 @@
package me.lucko.luckperms.sponge.service; package me.lucko.luckperms.sponge.service;
import co.aikar.timings.Timing;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -30,6 +31,7 @@ import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.groups.Group; import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.service.permission.NodeTree; import org.spongepowered.api.service.permission.NodeTree;
import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.Subject;
@ -81,72 +83,82 @@ public class LuckPermsGroupSubject extends LuckPermsSubject {
@Override @Override
public Tristate getPermissionValue(ContextSet contexts, String permission) { public Tristate getPermissionValue(ContextSet contexts, String permission) {
Map<String, Boolean> permissions = group.getAllNodesFiltered(service.calculateContexts(contexts)).stream() try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_GET_PERMISSION_VALUE)) {
.map(LocalizedNode::getNode) Map<String, Boolean> permissions = group.getAllNodesFiltered(service.calculateContexts(contexts)).stream()
.collect(Collectors.toMap(Node::getPermission, Node::getValue)); .map(LocalizedNode::getNode)
.collect(Collectors.toMap(Node::getPermission, Node::getValue));
Tristate t = NodeTree.of(permissions).get(permission); Tristate t = NodeTree.of(permissions).get(permission);
if (t != Tristate.UNDEFINED) { if (t != Tristate.UNDEFINED) {
return t;
}
t = service.getGroupSubjects().getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
if (t != Tristate.UNDEFINED) {
return t;
}
t = service.getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
return t; return t;
} }
t = service.getGroupSubjects().getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
if (t != Tristate.UNDEFINED) {
return t;
}
t = service.getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
return t;
} }
@Override @Override
public boolean isChildOf(ContextSet contexts, Subject parent) { public boolean isChildOf(ContextSet contexts, Subject parent) {
return parent instanceof LuckPermsGroupSubject && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean(); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_IS_CHILD_OF)) {
return parent instanceof LuckPermsGroupSubject && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
}
} }
@Override @Override
public List<Subject> getParents(ContextSet contexts) { public List<Subject> getParents(ContextSet contexts) {
List<Subject> subjects = group.getAllNodesFiltered(service.calculateContexts(contexts)).stream() try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_GET_PARENTS)) {
.map(LocalizedNode::getNode) List<Subject> subjects = group.getAllNodesFiltered(service.calculateContexts(contexts)).stream()
.filter(Node::isGroupNode) .map(LocalizedNode::getNode)
.map(Node::getGroupName) .filter(Node::isGroupNode)
.map(s -> service.getGroupSubjects().get(s)) .map(Node::getGroupName)
.collect(Collectors.toList()); .map(s -> service.getGroupSubjects().get(s))
.collect(Collectors.toList());
subjects.addAll(service.getGroupSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts))); subjects.addAll(service.getGroupSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
subjects.addAll(service.getDefaults().getParents(LuckPermsService.convertContexts(contexts))); subjects.addAll(service.getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
return ImmutableList.copyOf(subjects); return ImmutableList.copyOf(subjects);
}
} }
@Override @Override
public Optional<String> getOption(ContextSet contexts, String s) { public Optional<String> getOption(ContextSet contexts, String s) {
Optional<String> option; try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_GET_OPTION)) {
if (s.equalsIgnoreCase("prefix")) { Optional<String> option;
option = getChatMeta(contexts, true); if (s.equalsIgnoreCase("prefix")) {
option = getChatMeta(contexts, true);
} else if (s.equalsIgnoreCase("suffix")) { } else if (s.equalsIgnoreCase("suffix")) {
option = getChatMeta(contexts, false); option = getChatMeta(contexts, false);
} else { } else {
option = getMeta(contexts, s); option = getMeta(contexts, s);
}
if (option.isPresent()) {
return option;
}
option = service.getGroupSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
if (option.isPresent()) {
return option;
}
return service.getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
} }
if (option.isPresent()) {
return option;
}
option = service.getGroupSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
if (option.isPresent()) {
return option;
}
return service.getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
} }
@Override @Override
public ContextSet getActiveContextSet() { public ContextSet getActiveContextSet() {
return service.getPlugin().getContextManager().getApplicableContext(this); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_GET_ACTIVE_CONTEXTS)) {
return service.getPlugin().getContextManager().getApplicableContext(this);
}
} }
private Optional<String> getChatMeta(ContextSet contexts, boolean prefix) { private Optional<String> getChatMeta(ContextSet contexts, boolean prefix) {

View File

@ -22,6 +22,7 @@
package me.lucko.luckperms.sponge.service; package me.lucko.luckperms.sponge.service;
import co.aikar.timings.Timing;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
@ -38,6 +39,7 @@ import me.lucko.luckperms.sponge.service.collections.UserCollection;
import me.lucko.luckperms.sponge.service.persisted.PersistedCollection; import me.lucko.luckperms.sponge.service.persisted.PersistedCollection;
import me.lucko.luckperms.sponge.service.persisted.SubjectStorage; import me.lucko.luckperms.sponge.service.persisted.SubjectStorage;
import me.lucko.luckperms.sponge.service.simple.SimpleCollection; import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.context.ContextCalculator; import org.spongepowered.api.service.context.ContextCalculator;
@ -101,7 +103,9 @@ public class LuckPermsService implements PermissionService {
@Override @Override
public SubjectCollection getSubjects(String s) { public SubjectCollection getSubjects(String s) {
return collections.getUnchecked(s.toLowerCase()); try (Timing ignored = plugin.getTimings().time(LPTiming.GET_SUBJECTS)) {
return collections.getUnchecked(s.toLowerCase());
}
} }
@Override @Override

View File

@ -22,6 +22,7 @@
package me.lucko.luckperms.sponge.service; package me.lucko.luckperms.sponge.service;
import co.aikar.timings.Timing;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -34,6 +35,7 @@ import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.users.User; import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException; import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException; import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.service.permission.SubjectData; import org.spongepowered.api.service.permission.SubjectData;
@ -63,437 +65,448 @@ public class LuckPermsSubjectData implements SubjectData {
@Override @Override
public Map<Set<Context>, Map<String, Boolean>> getAllPermissions() { public Map<Set<Context>, Map<String, Boolean>> getAllPermissions() {
Map<Set<Context>, Map<String, Boolean>> perms = new HashMap<>(); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PERMISSIONS)) {
Map<Set<Context>, Map<String, Boolean>> perms = new HashMap<>();
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) { for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts()); Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
if (n.isServerSpecific()) { if (n.isServerSpecific()) {
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get())); contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
}
if (n.isWorldSpecific()) {
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
}
if (!perms.containsKey(contexts)) {
perms.put(contexts, new HashMap<>());
}
perms.get(contexts).put(n.getPermission(), n.getValue());
} }
if (n.isWorldSpecific()) { ImmutableMap.Builder<Set<Context>, Map<String, Boolean>> map = ImmutableMap.builder();
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get())); for (Map.Entry<Set<Context>, Map<String, Boolean>> e : perms.entrySet()) {
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
} }
return map.build();
if (!perms.containsKey(contexts)) {
perms.put(contexts, new HashMap<>());
}
perms.get(contexts).put(n.getPermission(), n.getValue());
} }
ImmutableMap.Builder<Set<Context>, Map<String, Boolean>> map = ImmutableMap.builder();
for (Map.Entry<Set<Context>, Map<String, Boolean>> e : perms.entrySet()) {
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
}
return map.build();
} }
@Override @Override
public Map<String, Boolean> getPermissions(Set<Context> contexts) { public Map<String, Boolean> getPermissions(Set<Context> contexts) {
ImmutableMap.Builder<String, Boolean> permissions = ImmutableMap.builder(); return getAllPermissions().getOrDefault(contexts, ImmutableMap.of());
(enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
.filter(n -> n.shouldApplyWithContext(LuckPermsService.convertContexts(contexts), true))
.forEach(n -> permissions.put(n.getKey(), n.getValue()));
return permissions.build();
} }
@Override @Override
public boolean setPermission(Set<Context> set, String s, Tristate tristate) { public boolean setPermission(Set<Context> contexts, String permission, Tristate tristate) {
if (tristate == Tristate.UNDEFINED) { try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_SET_PERMISSION)) {
// Unset if (tristate == Tristate.UNDEFINED) {
Node.Builder builder = new me.lucko.luckperms.common.core.Node.Builder(s); // Unset
Node.Builder builder = new me.lucko.luckperms.common.core.Node.Builder(permission);
for (Context ct : set) { for (Context ct : contexts) {
builder.withExtraContext(ct.getKey(), ct.getValue());
}
try {
if (enduring) {
holder.unsetPermission(builder.build());
} else {
holder.unsetTransientPermission(builder.build());
}
} catch (ObjectLacksException ignored) {}
objectSave(holder);
return true;
}
Node.Builder builder = new me.lucko.luckperms.common.core.Node.Builder(permission)
.setValue(tristate.asBoolean());
for (Context ct : contexts) {
builder.withExtraContext(ct.getKey(), ct.getValue()); builder.withExtraContext(ct.getKey(), ct.getValue());
} }
try { try {
if (enduring) { if (enduring) {
holder.unsetPermission(builder.build()); holder.setPermission(builder.build());
} else { } else {
holder.unsetTransientPermission(builder.build()); holder.setTransientPermission(builder.build());
}
} catch (ObjectLacksException ignored) {}
objectSave(holder);
return true;
}
Node.Builder builder = new me.lucko.luckperms.common.core.Node.Builder(s)
.setValue(tristate.asBoolean());
for (Context ct : set) {
builder.withExtraContext(ct.getKey(), ct.getValue());
}
try {
if (enduring) {
holder.setPermission(builder.build());
} else {
holder.setTransientPermission(builder.build());
}
} catch (ObjectAlreadyHasException ignored) {}
objectSave(holder);
return true;
}
@Override
public boolean clearPermissions() {
if (enduring) {
holder.clearNodes();
} else {
holder.clearTransientNodes();
}
objectSave(holder);
return true;
}
@Override
public boolean clearPermissions(Set<Context> contexts) {
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
.filter(node -> node.shouldApplyWithContext(LuckPermsService.convertContexts(contexts)))
.collect(Collectors.toList());
toRemove.forEach(n -> {
try {
if (enduring) {
holder.unsetPermission(n);
} else {
holder.unsetTransientPermission(n);
}
} catch (ObjectLacksException ignored) {}
});
if (holder instanceof User) {
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
}
objectSave(holder);
return !toRemove.isEmpty();
}
@Override
public Map<Set<Context>, List<Subject>> getAllParents() {
Map<Set<Context>, List<Subject>> parents = new HashMap<>();
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
if (!n.isGroupNode()) {
continue;
}
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
if (n.isServerSpecific()) {
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
}
if (n.isWorldSpecific()) {
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
}
if (!parents.containsKey(contexts)) {
parents.put(contexts, new ArrayList<>());
}
parents.get(contexts).add(service.getGroupSubjects().get(n.getGroupName()));
}
ImmutableMap.Builder<Set<Context>, List<Subject>> map = ImmutableMap.builder();
for (Map.Entry<Set<Context>, List<Subject>> e : parents.entrySet()) {
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableList.copyOf(e.getValue()));
}
return map.build();
}
@Override
public List<Subject> getParents(Set<Context> contexts) {
ImmutableList.Builder<Subject> parents = ImmutableList.builder();
(enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
.filter(Node::isGroupNode)
.filter(n -> n.shouldApplyWithContext(LuckPermsService.convertContexts(contexts), true))
.forEach(n -> parents.add(service.getGroupSubjects().get(n.getGroupName())));
return parents.build();
}
@Override
public boolean addParent(Set<Context> set, Subject subject) {
if (subject instanceof LuckPermsGroupSubject) {
LuckPermsGroupSubject permsSubject = ((LuckPermsGroupSubject) subject);
ContextSet contexts = LuckPermsService.convertContexts(set);
try {
if (enduring) {
holder.setPermission(new me.lucko.luckperms.common.core.Node.Builder("group." + permsSubject.getIdentifier())
.withExtraContext(contexts)
.build());
} else {
holder.setTransientPermission(new me.lucko.luckperms.common.core.Node.Builder("group." + permsSubject.getIdentifier())
.withExtraContext(contexts)
.build());
} }
} catch (ObjectAlreadyHasException ignored) {} } catch (ObjectAlreadyHasException ignored) {}
objectSave(holder); objectSave(holder);
return true; return true;
} }
return false; }
@Override
public boolean clearPermissions() {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_PERMISSIONS)) {
if (enduring) {
holder.clearNodes();
} else {
holder.clearTransientNodes();
}
objectSave(holder);
return true;
}
}
@Override
public boolean clearPermissions(Set<Context> c) {
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_PERMISSIONS)) {
List<Node> toRemove = new ArrayList<>();
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
if (n.isServerSpecific()) {
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
}
if (n.isWorldSpecific()) {
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
}
if (contexts.equals(c)) {
toRemove.add(n);
}
}
toRemove.forEach(n -> {
try {
if (enduring) {
holder.unsetPermission(n);
} else {
holder.unsetTransientPermission(n);
}
} catch (ObjectLacksException ignored) {}
});
if (holder instanceof User) {
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
}
objectSave(holder);
return !toRemove.isEmpty();
}
}
@Override
public Map<Set<Context>, List<Subject>> getAllParents() {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_PARENTS)) {
Map<Set<Context>, List<Subject>> parents = new HashMap<>();
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
if (!n.isGroupNode()) {
continue;
}
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
if (n.isServerSpecific()) {
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
}
if (n.isWorldSpecific()) {
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
}
if (!parents.containsKey(contexts)) {
parents.put(contexts, new ArrayList<>());
}
parents.get(contexts).add(service.getGroupSubjects().get(n.getGroupName()));
}
ImmutableMap.Builder<Set<Context>, List<Subject>> map = ImmutableMap.builder();
for (Map.Entry<Set<Context>, List<Subject>> e : parents.entrySet()) {
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableList.copyOf(e.getValue()));
}
return map.build();
}
}
@Override
public List<Subject> getParents(Set<Context> contexts) {
return getAllParents().getOrDefault(contexts, ImmutableList.of());
}
@Override
public boolean addParent(Set<Context> set, Subject subject) {
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_ADD_PARENT)) {
if (subject instanceof LuckPermsGroupSubject) {
LuckPermsGroupSubject permsSubject = ((LuckPermsGroupSubject) subject);
ContextSet contexts = LuckPermsService.convertContexts(set);
try {
if (enduring) {
holder.setPermission(new me.lucko.luckperms.common.core.Node.Builder("group." + permsSubject.getIdentifier())
.withExtraContext(contexts)
.build());
} else {
holder.setTransientPermission(new me.lucko.luckperms.common.core.Node.Builder("group." + permsSubject.getIdentifier())
.withExtraContext(contexts)
.build());
}
} catch (ObjectAlreadyHasException ignored) {}
objectSave(holder);
return true;
}
return false;
}
} }
@Override @Override
public boolean removeParent(Set<Context> set, Subject subject) { public boolean removeParent(Set<Context> set, Subject subject) {
if (subject instanceof LuckPermsGroupSubject) { try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_REMOVE_PARENT)) {
LuckPermsGroupSubject permsSubject = ((LuckPermsGroupSubject) subject); if (subject instanceof LuckPermsGroupSubject) {
ContextSet contexts = LuckPermsService.convertContexts(set); LuckPermsGroupSubject permsSubject = ((LuckPermsGroupSubject) subject);
ContextSet contexts = LuckPermsService.convertContexts(set);
try { try {
if (enduring) { if (enduring) {
holder.unsetPermission(new me.lucko.luckperms.common.core.Node.Builder("group." + permsSubject.getIdentifier()) holder.unsetPermission(new me.lucko.luckperms.common.core.Node.Builder("group." + permsSubject.getIdentifier())
.withExtraContext(contexts) .withExtraContext(contexts)
.build()); .build());
} else { } else {
holder.unsetTransientPermission(new me.lucko.luckperms.common.core.Node.Builder("group." + permsSubject.getIdentifier()) holder.unsetTransientPermission(new me.lucko.luckperms.common.core.Node.Builder("group." + permsSubject.getIdentifier())
.withExtraContext(contexts) .withExtraContext(contexts)
.build()); .build());
} }
} catch (ObjectLacksException ignored) {} } catch (ObjectLacksException ignored) {}
objectSave(holder); objectSave(holder);
return true; return true;
}
return false;
} }
return false;
} }
@Override @Override
public boolean clearParents() { public boolean clearParents() {
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream() try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_PARENTS)) {
.filter(Node::isGroupNode) List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
.collect(Collectors.toList()); .filter(Node::isGroupNode)
.collect(Collectors.toList());
toRemove.forEach(n -> { toRemove.forEach(n -> {
try { try {
if (enduring) { if (enduring) {
holder.unsetPermission(n); holder.unsetPermission(n);
} else { } else {
holder.unsetTransientPermission(n); holder.unsetTransientPermission(n);
} }
} catch (ObjectLacksException ignored) {} } catch (ObjectLacksException ignored) {}
}); });
if (holder instanceof User) { if (holder instanceof User) {
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false); service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
}
objectSave(holder);
return !toRemove.isEmpty();
} }
objectSave(holder);
return !toRemove.isEmpty();
} }
@Override @Override
public boolean clearParents(Set<Context> set) { public boolean clearParents(Set<Context> set) {
ContextSet context = LuckPermsService.convertContexts(set); try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_PARENTS)) {
List<Node> toRemove = new ArrayList<>();
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream() for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
.filter(Node::isGroupNode) if (!n.isGroupNode()) {
.filter(node -> node.shouldApplyWithContext(context)) continue;
.collect(Collectors.toList());
toRemove.forEach(n -> {
try {
if (enduring) {
holder.unsetPermission(n);
} else {
holder.unsetTransientPermission(n);
} }
} catch (ObjectLacksException ignored) {}
});
if (holder instanceof User) { Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
if (n.isServerSpecific()) {
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
}
if (n.isWorldSpecific()) {
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
}
if (contexts.equals(set)) {
toRemove.add(n);
}
}
toRemove.forEach(n -> {
try {
if (enduring) {
holder.unsetPermission(n);
} else {
holder.unsetTransientPermission(n);
}
} catch (ObjectLacksException ignored) {}
});
if (holder instanceof User) {
service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) holder), false);
}
objectSave(holder);
return !toRemove.isEmpty();
} }
objectSave(holder);
return !toRemove.isEmpty();
} }
@Override @Override
public Map<Set<Context>, Map<String, String>> getAllOptions() { public Map<Set<Context>, Map<String, String>> getAllOptions() {
Map<Set<Context>, Map<String, String>> options = new HashMap<>(); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_GET_OPTIONS)) {
Map<Set<Context>, Map<String, String>> options = new HashMap<>();
int prefixPriority = Integer.MIN_VALUE; int prefixPriority = Integer.MIN_VALUE;
int suffixPriority = Integer.MIN_VALUE; int suffixPriority = Integer.MIN_VALUE;
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) { for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
if (!n.getValue()) { if (!n.getValue()) {
continue; continue;
}
if (!n.isMeta() || !n.isPrefix() || n.isSuffix()) {
continue;
}
Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
if (n.isServerSpecific()) {
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
}
if (n.isWorldSpecific()) {
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
}
if (!options.containsKey(contexts)) {
options.put(contexts, new HashMap<>());
}
if (n.isPrefix()) {
Map.Entry<Integer, String> value = n.getPrefix();
if (value.getKey() > prefixPriority) {
options.get(contexts).put("prefix", value.getValue());
prefixPriority = value.getKey();
} }
continue;
}
if (n.isSuffix()) { if (!n.isMeta() || !n.isPrefix() || n.isSuffix()) {
Map.Entry<Integer, String> value = n.getSuffix(); continue;
if (value.getKey() > suffixPriority) { }
options.get(contexts).put("suffix", value.getValue());
suffixPriority = value.getKey(); Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
if (n.isServerSpecific()) {
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
}
if (n.isWorldSpecific()) {
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
}
if (!options.containsKey(contexts)) {
options.put(contexts, new HashMap<>());
}
if (n.isPrefix()) {
Map.Entry<Integer, String> value = n.getPrefix();
if (value.getKey() > prefixPriority) {
options.get(contexts).put("prefix", value.getValue());
prefixPriority = value.getKey();
}
continue;
}
if (n.isSuffix()) {
Map.Entry<Integer, String> value = n.getSuffix();
if (value.getKey() > suffixPriority) {
options.get(contexts).put("suffix", value.getValue());
suffixPriority = value.getKey();
}
continue;
}
if (n.isMeta()) {
Map.Entry<String, String> meta = n.getMeta();
options.get(contexts).put(meta.getKey(), meta.getValue());
} }
continue;
} }
if (n.isMeta()) { ImmutableMap.Builder<Set<Context>, Map<String, String>> map = ImmutableMap.builder();
Map.Entry<String, String> meta = n.getMeta(); for (Map.Entry<Set<Context>, Map<String, String>> e : options.entrySet()) {
options.get(contexts).put(meta.getKey(), meta.getValue()); map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
} }
return map.build();
} }
ImmutableMap.Builder<Set<Context>, Map<String, String>> map = ImmutableMap.builder();
for (Map.Entry<Set<Context>, Map<String, String>> e : options.entrySet()) {
map.put(ImmutableSet.copyOf(e.getKey()), ImmutableMap.copyOf(e.getValue()));
}
return map.build();
} }
@Override @Override
public Map<String, String> getOptions(Set<Context> set) { public Map<String, String> getOptions(Set<Context> set) {
ImmutableMap.Builder<String, String> options = ImmutableMap.builder(); return getAllOptions().getOrDefault(set, ImmutableMap.of());
ContextSet contexts = LuckPermsService.convertContexts(set);
int prefixPriority = Integer.MIN_VALUE;
int suffixPriority = Integer.MIN_VALUE;
for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
if (!n.getValue()) {
continue;
}
if (!n.isMeta() || !n.isPrefix() || n.isSuffix()) {
continue;
}
if (!n.shouldApplyWithContext(contexts, true)) {
continue;
}
if (n.isPrefix()) {
Map.Entry<Integer, String> value = n.getPrefix();
if (value.getKey() > prefixPriority) {
options.put("prefix", value.getValue());
prefixPriority = value.getKey();
}
continue;
}
if (n.isSuffix()) {
Map.Entry<Integer, String> value = n.getSuffix();
if (value.getKey() > suffixPriority) {
options.put("suffix", value.getValue());
suffixPriority = value.getKey();
}
continue;
}
if (n.isMeta()) {
Map.Entry<String, String> meta = n.getMeta();
options.put(meta.getKey(), meta.getValue());
}
}
return options.build();
} }
@Override @Override
public boolean setOption(Set<Context> set, String key, String value) { public boolean setOption(Set<Context> set, String key, String value) {
ContextSet context = LuckPermsService.convertContexts(set); try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_SET_OPTION)) {
ContextSet context = LuckPermsService.convertContexts(set);
key = escapeCharacters(key); key = escapeCharacters(key);
value = escapeCharacters(value); value = escapeCharacters(value);
try { try {
if (enduring) { if (enduring) {
holder.setPermission(new me.lucko.luckperms.common.core.Node.Builder("meta." + key + "." + value) holder.setPermission(new me.lucko.luckperms.common.core.Node.Builder("meta." + key + "." + value)
.withExtraContext(context) .withExtraContext(context)
.build() .build()
); );
} else { } else {
holder.setTransientPermission(new me.lucko.luckperms.common.core.Node.Builder("meta." + key + "." + value) holder.setTransientPermission(new me.lucko.luckperms.common.core.Node.Builder("meta." + key + "." + value)
.withExtraContext(context) .withExtraContext(context)
.build() .build()
); );
} }
} catch (ObjectAlreadyHasException ignored) {} } catch (ObjectAlreadyHasException ignored) {}
objectSave(holder); objectSave(holder);
return true; return true;
}
} }
@Override @Override
public boolean clearOptions(Set<Context> set) { public boolean clearOptions(Set<Context> set) {
ContextSet context = LuckPermsService.convertContexts(set); try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_OPTIONS)) {
List<Node> toRemove = new ArrayList<>();
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream() for (Node n : enduring ? holder.getNodes() : holder.getTransientNodes()) {
.filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix()) if (!n.isMeta() && !n.isPrefix() && !n.isSuffix()) {
.filter(node -> node.shouldApplyWithContext(context)) continue;
.collect(Collectors.toList());
toRemove.forEach(n -> {
try {
if (enduring) {
holder.unsetPermission(n);
} else {
holder.unsetTransientPermission(n);
} }
} catch (ObjectLacksException ignored) {}
});
objectSave(holder); Set<Context> contexts = LuckPermsService.convertContexts(n.getContexts());
return !toRemove.isEmpty();
if (n.isServerSpecific()) {
contexts.add(new Context(LuckPermsService.SERVER_CONTEXT, n.getServer().get()));
}
if (n.isWorldSpecific()) {
contexts.add(new Context(Context.WORLD_KEY, n.getWorld().get()));
}
if (contexts.equals(set)) {
toRemove.add(n);
}
}
toRemove.forEach(n -> {
try {
if (enduring) {
holder.unsetPermission(n);
} else {
holder.unsetTransientPermission(n);
}
} catch (ObjectLacksException ignored) {}
});
objectSave(holder);
return !toRemove.isEmpty();
}
} }
@Override @Override
public boolean clearOptions() { public boolean clearOptions() {
List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream() try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_CLEAR_OPTIONS)) {
.filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix()) List<Node> toRemove = (enduring ? holder.getNodes() : holder.getTransientNodes()).stream()
.collect(Collectors.toList()); .filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix())
.collect(Collectors.toList());
toRemove.forEach(n -> { toRemove.forEach(n -> {
try { try {
if (enduring) { if (enduring) {
holder.unsetPermission(n); holder.unsetPermission(n);
} else { } else {
holder.unsetTransientPermission(n); holder.unsetTransientPermission(n);
} }
} catch (ObjectLacksException ignored) {} } catch (ObjectLacksException ignored) {}
}); });
objectSave(holder); objectSave(holder);
return !toRemove.isEmpty(); return !toRemove.isEmpty();
}
} }
} }

View File

@ -22,6 +22,7 @@
package me.lucko.luckperms.sponge.service; package me.lucko.luckperms.sponge.service;
import co.aikar.timings.Timing;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -29,6 +30,7 @@ import lombok.Getter;
import me.lucko.luckperms.api.caching.MetaData; import me.lucko.luckperms.api.caching.MetaData;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.users.User; import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.entity.living.player.Player;
@ -61,15 +63,6 @@ public class LuckPermsUserSubject extends LuckPermsSubject {
this.transientSubjectData = new LuckPermsSubjectData(false, service, user); this.transientSubjectData = new LuckPermsSubjectData(false, service, user);
} }
public void deprovision() {
/* For some reason, Sponge holds onto User instances in a cache, which in turn, prevents LuckPerms data from being GCed.
As well as unloading, we also remove all references to the User instances. */
user = null;
service = null;
subjectData = null;
transientSubjectData = null;
}
private boolean hasData() { private boolean hasData() {
return user.getUserData() != null; return user.getUserData() != null;
} }
@ -98,70 +91,82 @@ public class LuckPermsUserSubject extends LuckPermsSubject {
@Override @Override
public Tristate getPermissionValue(ContextSet contexts, String permission) { public Tristate getPermissionValue(ContextSet contexts, String permission) {
return !hasData() ? try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_GET_PERMISSION_VALUE)) {
Tristate.UNDEFINED : return !hasData() ?
LuckPermsService.convertTristate(user.getUserData().getPermissionData(service.calculateContexts(contexts)).getPermissionValue(permission)); Tristate.UNDEFINED :
LuckPermsService.convertTristate(
user.getUserData().getPermissionData(service.calculateContexts(contexts)).getPermissionValue(permission)
);
}
} }
@Override @Override
public boolean isChildOf(ContextSet contexts, Subject parent) { public boolean isChildOf(ContextSet contexts, Subject parent) {
return parent instanceof LuckPermsGroupSubject && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean(); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_IS_CHILD_OF)) {
return parent instanceof LuckPermsGroupSubject && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
}
} }
@Override @Override
public List<Subject> getParents(ContextSet contexts) { public List<Subject> getParents(ContextSet contexts) {
ImmutableList.Builder<Subject> subjects = ImmutableList.builder(); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_GET_PARENTS)) {
ImmutableList.Builder<Subject> subjects = ImmutableList.builder();
if (hasData()) { if (hasData()) {
for (String perm : user.getUserData().getPermissionData(service.calculateContexts(contexts)).getImmutableBacking().keySet()) { for (String perm : user.getUserData().getPermissionData(service.calculateContexts(contexts)).getImmutableBacking().keySet()) {
if (!perm.startsWith("group.")) { if (!perm.startsWith("group.")) {
continue; continue;
} }
String groupName = perm.substring("group.".length()); String groupName = perm.substring("group.".length());
if (service.getPlugin().getGroupManager().isLoaded(groupName)) { if (service.getPlugin().getGroupManager().isLoaded(groupName)) {
subjects.add(service.getGroupSubjects().get(groupName)); subjects.add(service.getGroupSubjects().get(groupName));
}
} }
} }
subjects.addAll(service.getUserSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
subjects.addAll(service.getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
return subjects.build();
} }
subjects.addAll(service.getUserSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
subjects.addAll(service.getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
return subjects.build();
} }
@Override @Override
public Optional<String> getOption(ContextSet contexts, String s) { public Optional<String> getOption(ContextSet contexts, String s) {
if (hasData()) { try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_GET_OPTION)) {
MetaData data = user.getUserData().getMetaData(service.calculateContexts(contexts)); if (hasData()) {
if (s.equalsIgnoreCase("prefix")) { MetaData data = user.getUserData().getMetaData(service.calculateContexts(contexts));
if (data.getPrefix() != null) { if (s.equalsIgnoreCase("prefix")) {
return Optional.of(data.getPrefix()); if (data.getPrefix() != null) {
return Optional.of(data.getPrefix());
}
}
if (s.equalsIgnoreCase("suffix")) {
if (data.getSuffix() != null) {
return Optional.of(data.getSuffix());
}
}
if (data.getMeta().containsKey(s)) {
return Optional.of(data.getMeta().get(s));
} }
} }
if (s.equalsIgnoreCase("suffix")) { Optional<String> v = service.getUserSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
if (data.getSuffix() != null) { if (v.isPresent()) {
return Optional.of(data.getSuffix()); return v;
}
} }
if (data.getMeta().containsKey(s)) { return service.getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
return Optional.of(data.getMeta().get(s));
}
} }
Optional<String> v = service.getUserSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
if (v.isPresent()) {
return v;
}
return service.getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
} }
@Override @Override
public ContextSet getActiveContextSet() { public ContextSet getActiveContextSet() {
return service.getPlugin().getContextManager().getApplicableContext(this); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_GET_ACTIVE_CONTEXTS)) {
return service.getPlugin().getContextManager().getApplicableContext(this);
}
} }
} }

View File

@ -22,6 +22,7 @@
package me.lucko.luckperms.sponge.service.collections; package me.lucko.luckperms.sponge.service.collections;
import co.aikar.timings.Timing;
import lombok.NonNull; import lombok.NonNull;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.groups.GroupManager; import me.lucko.luckperms.common.groups.GroupManager;
@ -29,6 +30,7 @@ import me.lucko.luckperms.common.utils.ImmutableCollectors;
import me.lucko.luckperms.sponge.service.LuckPermsGroupSubject; import me.lucko.luckperms.sponge.service.LuckPermsGroupSubject;
import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.simple.SimpleCollection; import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.PermissionService;
import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.Subject;
@ -58,11 +60,13 @@ public class GroupCollection implements SubjectCollection {
@Override @Override
public Subject get(@NonNull String id) { public Subject get(@NonNull String id) {
if (manager.isLoaded(id)) { try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_COLLECTION_GET)) {
return LuckPermsGroupSubject.wrapGroup(manager.get(id), service); if (manager.isLoaded(id)) {
} return LuckPermsGroupSubject.wrapGroup(manager.get(id), service);
}
return fallback.get(id); return fallback.get(id);
}
} }
@Override @Override

View File

@ -22,11 +22,13 @@
package me.lucko.luckperms.sponge.service.collections; package me.lucko.luckperms.sponge.service.collections;
import co.aikar.timings.Timing;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
import lombok.NonNull; import lombok.NonNull;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.commands.Util; import me.lucko.luckperms.common.commands.Util;
@ -36,6 +38,7 @@ import me.lucko.luckperms.common.utils.ImmutableCollectors;
import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.LuckPermsUserSubject; import me.lucko.luckperms.sponge.service.LuckPermsUserSubject;
import me.lucko.luckperms.sponge.service.simple.SimpleCollection; import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.PermissionService;
import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.Subject;
@ -71,7 +74,7 @@ public class UserCollection implements SubjectCollection {
public LuckPermsUserSubject load(UUID uuid) throws Exception { public LuckPermsUserSubject load(UUID uuid) throws Exception {
User user = manager.get(uuid); User user = manager.get(uuid);
if (user == null) { if (user == null) {
throw new IllegalStateException("user not loaded"); throw new IllegalStateException("User not loaded");
} }
return LuckPermsUserSubject.wrapUser(user, service); return LuckPermsUserSubject.wrapUser(user, service);
@ -100,13 +103,15 @@ public class UserCollection implements SubjectCollection {
@Override @Override
public Subject get(@NonNull String id) { public Subject get(@NonNull String id) {
Optional<Subject> s = getIfLoaded(id); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_COLLECTION_GET)) {
if (s.isPresent()) { Optional<Subject> s = getIfLoaded(id);
return s.get(); if (s.isPresent()) {
} return s.get();
}
// Fallback to the other collection. This Subject instance will never be persisted. // Fallback to the other collection. This Subject instance will never be persisted.
return fallback.get(id); return fallback.get(id);
}
} }
private Optional<Subject> getIfLoaded(String id) { private Optional<Subject> getIfLoaded(String id) {
@ -135,7 +140,7 @@ public class UserCollection implements SubjectCollection {
UUID internal = service.getPlugin().getUuidCache().getUUID(uuid); UUID internal = service.getPlugin().getUuidCache().getUUID(uuid);
try { try {
return Optional.of(users.get(internal)); return Optional.of(users.get(internal));
} catch (ExecutionException e) { } catch (ExecutionException | UncheckedExecutionException e) {
return Optional.empty(); return Optional.empty();
} }
} }

View File

@ -22,11 +22,13 @@
package me.lucko.luckperms.sponge.service.persisted; package me.lucko.luckperms.sponge.service.persisted;
import co.aikar.timings.Timing;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import me.lucko.luckperms.common.utils.BufferedRequest; import me.lucko.luckperms.common.utils.BufferedRequest;
import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.permission.MemorySubjectData; import org.spongepowered.api.service.permission.MemorySubjectData;
@ -95,96 +97,106 @@ public class PersistedSubject implements Subject {
@Override @Override
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) { public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
Tristate res = subjectData.getNodeTree(contexts).get(node); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_PERMISSION_VALUE)) {
if (res != Tristate.UNDEFINED) { Tristate res = subjectData.getNodeTree(contexts).get(node);
return res; if (res != Tristate.UNDEFINED) {
} return res;
res = transientSubjectData.getNodeTree(contexts).get(node);
if (res != Tristate.UNDEFINED) {
return res;
}
for (Subject parent : getParents(contexts)) {
Tristate tempRes = parent.getPermissionValue(contexts, node);
if (tempRes != Tristate.UNDEFINED) {
return tempRes;
} }
}
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) { res = transientSubjectData.getNodeTree(contexts).get(node);
return Tristate.UNDEFINED; if (res != Tristate.UNDEFINED) {
} return res;
}
res = service.getGroupSubjects().getDefaults().getPermissionValue(contexts, node); for (Subject parent : getParents(contexts)) {
if (res != Tristate.UNDEFINED) { Tristate tempRes = parent.getPermissionValue(contexts, node);
if (tempRes != Tristate.UNDEFINED) {
return tempRes;
}
}
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
return Tristate.UNDEFINED;
}
res = service.getGroupSubjects().getDefaults().getPermissionValue(contexts, node);
if (res != Tristate.UNDEFINED) {
return res;
}
res = service.getDefaults().getPermissionValue(contexts, node);
return res; return res;
} }
res = service.getDefaults().getPermissionValue(contexts, node);
return res;
} }
@Override @Override
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject subject) { public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject subject) {
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) { try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_IS_CHILD_OF)) {
return subjectData.getParents(contexts).contains(subject) || if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
transientSubjectData.getParents(contexts).contains(subject); return subjectData.getParents(contexts).contains(subject) ||
} else { transientSubjectData.getParents(contexts).contains(subject);
return subjectData.getParents(contexts).contains(subject) || } else {
transientSubjectData.getParents(contexts).contains(subject) || return subjectData.getParents(contexts).contains(subject) ||
getContainingCollection().getDefaults().getParents(contexts).contains(subject) || transientSubjectData.getParents(contexts).contains(subject) ||
service.getDefaults().getParents(contexts).contains(subject); getContainingCollection().getDefaults().getParents(contexts).contains(subject) ||
service.getDefaults().getParents(contexts).contains(subject);
}
} }
} }
@Override @Override
public List<Subject> getParents(@NonNull Set<Context> contexts) { public List<Subject> getParents(@NonNull Set<Context> contexts) {
List<Subject> s = new ArrayList<>(); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_PARENTS)) {
s.addAll(subjectData.getParents(contexts)); List<Subject> s = new ArrayList<>();
s.addAll(transientSubjectData.getParents(contexts)); s.addAll(subjectData.getParents(contexts));
s.addAll(transientSubjectData.getParents(contexts));
if (!getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) { if (!getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
s.addAll(getContainingCollection().getDefaults().getParents(contexts)); s.addAll(getContainingCollection().getDefaults().getParents(contexts));
s.addAll(service.getDefaults().getParents(contexts)); s.addAll(service.getDefaults().getParents(contexts));
}
return ImmutableList.copyOf(s);
} }
return ImmutableList.copyOf(s);
} }
@Override @Override
public Optional<String> getOption(Set<Context> set, String key) { public Optional<String> getOption(Set<Context> set, String key) {
Optional<String> res = Optional.ofNullable(subjectData.getOptions(getActiveContexts()).get(key)); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_OPTION)) {
if (res.isPresent()) { Optional<String> res = Optional.ofNullable(subjectData.getOptions(getActiveContexts()).get(key));
return res; if (res.isPresent()) {
} return res;
res = Optional.ofNullable(transientSubjectData.getOptions(getActiveContexts()).get(key));
if (res.isPresent()) {
return res;
}
for (Subject parent : getParents(getActiveContexts())) {
Optional<String> tempRes = parent.getOption(getActiveContexts(), key);
if (tempRes.isPresent()) {
return tempRes;
} }
}
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) { res = Optional.ofNullable(transientSubjectData.getOptions(getActiveContexts()).get(key));
return Optional.empty(); if (res.isPresent()) {
} return res;
}
res = getContainingCollection().getDefaults().getOption(set, key); for (Subject parent : getParents(getActiveContexts())) {
if (res.isPresent()) { Optional<String> tempRes = parent.getOption(getActiveContexts(), key);
return res; if (tempRes.isPresent()) {
} return tempRes;
}
}
return service.getDefaults().getOption(set, key); if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
return Optional.empty();
}
res = getContainingCollection().getDefaults().getOption(set, key);
if (res.isPresent()) {
return res;
}
return service.getDefaults().getOption(set, key);
}
} }
@Override @Override
public Set<Context> getActiveContexts() { public Set<Context> getActiveContexts() {
return LuckPermsService.convertContexts(service.getPlugin().getContextManager().getApplicableContext(this)); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.PERSISTED_SUBJECT_GET_ACTIVE_CONTEXTS)) {
return LuckPermsService.convertContexts(service.getPlugin().getContextManager().getApplicableContext(this));
}
} }
} }

View File

@ -22,10 +22,12 @@
package me.lucko.luckperms.sponge.service.simple; package me.lucko.luckperms.sponge.service.simple;
import co.aikar.timings.Timing;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.permission.MemorySubjectData; import org.spongepowered.api.service.permission.MemorySubjectData;
@ -74,83 +76,93 @@ public class SimpleSubject implements Subject {
@Override @Override
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) { public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
Tristate res = subjectData.getNodeTree(contexts).get(node); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_PERMISSION_VALUE)) {
if (res != Tristate.UNDEFINED) { Tristate res = subjectData.getNodeTree(contexts).get(node);
return res; if (res != Tristate.UNDEFINED) {
} return res;
for (Subject parent : getParents(contexts)) {
Tristate tempRes = parent.getPermissionValue(contexts, node);
if (tempRes != Tristate.UNDEFINED) {
return tempRes;
} }
}
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) { for (Subject parent : getParents(contexts)) {
return Tristate.UNDEFINED; Tristate tempRes = parent.getPermissionValue(contexts, node);
} if (tempRes != Tristate.UNDEFINED) {
return tempRes;
}
}
res = service.getGroupSubjects().getDefaults().getPermissionValue(contexts, node); if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
if (res != Tristate.UNDEFINED) { return Tristate.UNDEFINED;
}
res = service.getGroupSubjects().getDefaults().getPermissionValue(contexts, node);
if (res != Tristate.UNDEFINED) {
return res;
}
res = service.getDefaults().getPermissionValue(contexts, node);
return res; return res;
} }
res = service.getDefaults().getPermissionValue(contexts, node);
return res;
} }
@Override @Override
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject subject) { public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject subject) {
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) { try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_IS_CHILD_OF)) {
return subjectData.getParents(contexts).contains(subject); if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
} else { return subjectData.getParents(contexts).contains(subject);
return subjectData.getParents(contexts).contains(subject) || } else {
getContainingCollection().getDefaults().getParents(contexts).contains(subject) || return subjectData.getParents(contexts).contains(subject) ||
service.getDefaults().getParents(contexts).contains(subject); getContainingCollection().getDefaults().getParents(contexts).contains(subject) ||
service.getDefaults().getParents(contexts).contains(subject);
}
} }
} }
@Override @Override
public List<Subject> getParents(@NonNull Set<Context> contexts) { public List<Subject> getParents(@NonNull Set<Context> contexts) {
List<Subject> s = new ArrayList<>(); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_PARENTS)) {
s.addAll(subjectData.getParents(contexts)); List<Subject> s = new ArrayList<>();
s.addAll(subjectData.getParents(contexts));
if (!getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")){ if (!getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")){
s.addAll(getContainingCollection().getDefaults().getParents(contexts)); s.addAll(getContainingCollection().getDefaults().getParents(contexts));
s.addAll(service.getDefaults().getParents(contexts)); s.addAll(service.getDefaults().getParents(contexts));
}
return ImmutableList.copyOf(s);
} }
return ImmutableList.copyOf(s);
} }
@Override @Override
public Optional<String> getOption(Set<Context> set, String key) { public Optional<String> getOption(Set<Context> set, String key) {
Optional<String> res = Optional.ofNullable(subjectData.getOptions(getActiveContexts()).get(key)); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_OPTION)) {
if (res.isPresent()) { Optional<String> res = Optional.ofNullable(subjectData.getOptions(getActiveContexts()).get(key));
return res; if (res.isPresent()) {
} return res;
for (Subject parent : getParents(getActiveContexts())) {
Optional<String> tempRes = parent.getOption(getActiveContexts(), key);
if (tempRes.isPresent()) {
return tempRes;
} }
}
if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) { for (Subject parent : getParents(getActiveContexts())) {
return Optional.empty(); Optional<String> tempRes = parent.getOption(getActiveContexts(), key);
} if (tempRes.isPresent()) {
return tempRes;
}
}
res = getContainingCollection().getDefaults().getOption(set, key); if (getContainingCollection().getIdentifier().equalsIgnoreCase("defaults")) {
if (res.isPresent()) { return Optional.empty();
return res; }
}
return service.getDefaults().getOption(set, key); res = getContainingCollection().getDefaults().getOption(set, key);
if (res.isPresent()) {
return res;
}
return service.getDefaults().getOption(set, key);
}
} }
@Override @Override
public Set<Context> getActiveContexts() { public Set<Context> getActiveContexts() {
return LuckPermsService.convertContexts(service.getPlugin().getContextManager().getApplicableContext(this)); try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.SIMPLE_SUBJECT_GET_ACTIVE_CONTEXTS)) {
return LuckPermsService.convertContexts(service.getPlugin().getContextManager().getApplicableContext(this));
}
} }
} }

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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.sponge.timings;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum LPTiming {
GET_SUBJECTS("getSubjects"),
USER_COLLECTION_GET("userCollectionGet"),
GROUP_COLLECTION_GET("groupCollectionGet"),
USER_GET_PERMISSION_VALUE("userGetPermissionValue"),
USER_GET_PARENTS("userGetParents"),
USER_IS_CHILD_OF("userIsChildOf"),
USER_GET_OPTION("userGetOption"),
USER_GET_ACTIVE_CONTEXTS("userGetActiveContexts"),
GROUP_GET_PERMISSION_VALUE("groupGetPermissionValue"),
GROUP_GET_PARENTS("groupGetParents"),
GROUP_IS_CHILD_OF("groupIsChildOf"),
GROUP_GET_OPTION("groupGetOption"),
GROUP_GET_ACTIVE_CONTEXTS("groupGetActiveContexts"),
LP_SUBJECT_GET_PERMISSIONS("lpSubjectGetPermissions"),
LP_SUBJECT_SET_PERMISSION("lpSubjectSetPermission"),
LP_SUBJECT_CLEAR_PERMISSIONS("lpSubjectClearPermissions"),
LP_SUBJECT_GET_PARENTS("lpSubjectGetParents"),
LP_SUBJECT_ADD_PARENT("lpSubjectAddParent"),
LP_SUBJECT_REMOVE_PARENT("lpSubjectRemoveParent"),
LP_SUBJECT_CLEAR_PARENTS("lpSubjectClearParents"),
LP_SUBJECT_GET_OPTIONS("lpSubjectGetOptions"),
LP_SUBJECT_SET_OPTION("lpSubjectSetOption"),
LP_SUBJECT_CLEAR_OPTIONS("lpSubjectClearOptions"),
SIMPLE_SUBJECT_GET_PERMISSION_VALUE("simpleSubjectGetPermissionValue"),
SIMPLE_SUBJECT_IS_CHILD_OF("simpleSubjectIsChildOf"),
SIMPLE_SUBJECT_GET_PARENTS("simpleSubjectGetParents"),
SIMPLE_SUBJECT_GET_OPTION("simpleSubjectGetOption"),
SIMPLE_SUBJECT_GET_ACTIVE_CONTEXTS("simpleSubjectGetActiveContexts"),
PERSISTED_SUBJECT_GET_PERMISSION_VALUE("persistedSubjectGetPermissionValue"),
PERSISTED_SUBJECT_IS_CHILD_OF("persistedSubjectIsChildOf"),
PERSISTED_SUBJECT_GET_PARENTS("persistedSubjectGetParents"),
PERSISTED_SUBJECT_GET_OPTION("persistedSubjectGetOption"),
PERSISTED_SUBJECT_GET_ACTIVE_CONTEXTS("persistedSubjectGetActiveContexts"),
ON_COMMAND("onCommand"),
COMMAND_TAB_COMPLETE("commandTabComplete"),
ON_CLIENT_LOGIN("onClientLogin"),
ON_CLIENT_LEAVE("onClientLeave");
private final String id;
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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.sponge.timings;
import co.aikar.timings.Timing;
import co.aikar.timings.Timings;
import com.google.common.collect.ImmutableMap;
import lombok.NonNull;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import java.util.Map;
public class LPTimings {
private final Map<LPTiming, Timing> timings;
public LPTimings(LPSpongePlugin plugin) {
ImmutableMap.Builder<LPTiming, Timing> map = ImmutableMap.builder();
for (LPTiming t : LPTiming.values()) {
map.put(t, Timings.of(plugin, t.getId()));
}
timings = map.build();
}
public Timing time(@NonNull LPTiming timing) {
Timing t = timings.get(timing);
t.startTimingIfSync();
return t;
}
}