Move Track methods away from checked exceptions, refactor ContextManager & primary group holders

This commit is contained in:
Luck 2017-10-12 19:43:42 +01:00
parent de4c6b384c
commit 9c505e4402
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
23 changed files with 301 additions and 180 deletions

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.bukkit.contexts;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
@ -35,9 +33,10 @@ import me.lucko.luckperms.common.contexts.AbstractContextManager;
import org.bukkit.entity.Player;
@RequiredArgsConstructor
public class BukkitContextManager extends AbstractContextManager<Player> {
private final LPBukkitPlugin plugin;
public BukkitContextManager(LPBukkitPlugin plugin) {
super(plugin);
}
@Override
public Contexts formContexts(Player subject, ImmutableContextSet contextSet) {

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.bungee.contexts;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.bungee.LPBungeePlugin;
@ -35,9 +33,10 @@ import me.lucko.luckperms.common.contexts.AbstractContextManager;
import net.md_5.bungee.api.connection.ProxiedPlayer;
@RequiredArgsConstructor
public class BungeeContextManager extends AbstractContextManager<ProxiedPlayer> {
private final LPBungeePlugin plugin;
public BungeeContextManager(LPBungeePlugin plugin) {
super(plugin);
}
@Override
public Contexts formContexts(ProxiedPlayer subject, ImmutableContextSet contextSet) {

View File

@ -188,10 +188,10 @@ public final class GroupDelegate extends PermissionHolderDelegate implements Gro
if (!(o instanceof GroupDelegate)) return false;
GroupDelegate other = (GroupDelegate) o;
return this.getName().equals(other.getName());
return handle.equals(other.handle);
}
public int hashCode() {
return this.getName().hashCode();
return handle.hashCode();
}
}

View File

@ -438,12 +438,12 @@ public class PermissionHolderDelegate implements PermissionHolder {
@Override
public List<LocalizedNode> resolveInheritances(Contexts contexts) {
return null;
return handle.resolveInheritances(ExtractedContexts.generate(contexts));
}
@Override
public List<LocalizedNode> resolveInheritances() {
return null;
return handle.resolveInheritances();
}
@Override

View File

@ -69,32 +69,40 @@ public final class TrackDelegate implements Track {
@Override
public String getNext(@NonNull Group current) throws ObjectLacksException {
return handle.getNext(GroupDelegate.cast(current));
try {
return handle.getNext(GroupDelegate.cast(current));
} catch (IllegalArgumentException e) {
throw new ObjectLacksException();
}
}
@Override
public String getPrevious(@NonNull Group current) throws ObjectLacksException {
return handle.getPrevious(GroupDelegate.cast(current));
try {
return handle.getPrevious(GroupDelegate.cast(current));
} catch (IllegalArgumentException e) {
throw new ObjectLacksException();
}
}
@Override
public void appendGroup(@NonNull Group group) throws ObjectAlreadyHasException {
handle.appendGroup(GroupDelegate.cast(group));
handle.appendGroup(GroupDelegate.cast(group)).throwException();
}
@Override
public void insertGroup(@NonNull Group group, @NonNull int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException {
handle.insertGroup(GroupDelegate.cast(group), position);
handle.insertGroup(GroupDelegate.cast(group), position).throwException();
}
@Override
public void removeGroup(@NonNull Group group) throws ObjectLacksException {
handle.removeGroup(GroupDelegate.cast(group));
handle.removeGroup(GroupDelegate.cast(group)).throwException();
}
@Override
public void removeGroup(@NonNull String group) throws ObjectLacksException {
handle.removeGroup(group);
handle.removeGroup(group).throwException();
}
@Override
@ -117,10 +125,10 @@ public final class TrackDelegate implements Track {
if (!(o instanceof TrackDelegate)) return false;
TrackDelegate other = (TrackDelegate) o;
return this.getName().equals(other.getName());
return handle.equals(other.handle);
}
public int hashCode() {
return this.getName().hashCode();
return handle.hashCode();
}
}

View File

@ -228,10 +228,10 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
if (!(o instanceof UserDelegate)) return false;
UserDelegate other = (UserDelegate) o;
return this.getUuid().equals(other.getUuid());
return handle.equals(other.handle);
}
public int hashCode() {
return this.getUuid().hashCode();
return handle.hashCode();
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.caching.handlers;
import me.lucko.luckperms.common.model.PermissionHolder;
/**
* Represents an object which is notified when the state of a {@link PermissionHolder} changes.
*/
public interface StateListener {
void onStateChange();
}

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.impl.track;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
@ -40,7 +41,6 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
@ -68,8 +68,9 @@ public class TrackAppend extends SubCommand<Track> {
return CommandResult.LOADING_ERROR;
}
try {
track.appendGroup(group);
DataMutateResult result = track.appendGroup(group);
if (result.asBoolean()) {
Message.TRACK_APPEND_SUCCESS.send(sender, group.getName(), track.getName());
if (track.getGroups().size() > 1) {
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), group.getName()));
@ -79,7 +80,7 @@ public class TrackAppend extends SubCommand<Track> {
.build().submit(plugin, sender);
save(track, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
} else {
Message.TRACK_ALREADY_CONTAINS.send(sender, track.getName(), group.getName());
return CommandResult.STATE_ERROR;
}

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.impl.track;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
@ -40,7 +41,6 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.List;
@ -77,19 +77,23 @@ public class TrackInsert extends SubCommand<Track> {
}
try {
track.insertGroup(group, pos - 1);
Message.TRACK_INSERT_SUCCESS.send(sender, group.getName(), track.getName(), pos);
if (track.getGroups().size() > 1) {
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), group.getName()));
DataMutateResult result = track.insertGroup(group, pos - 1);
if (result.asBoolean()) {
Message.TRACK_INSERT_SUCCESS.send(sender, group.getName(), track.getName(), pos);
if (track.getGroups().size() > 1) {
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups(), group.getName()));
}
ExtendedLogEntry.build().actor(sender).acted(track)
.action("insert " + group.getName() + " " + pos)
.build().submit(plugin, sender);
save(track, sender, plugin);
return CommandResult.SUCCESS;
} else {
Message.TRACK_ALREADY_CONTAINS.send(sender, track.getName(), group.getName());
return CommandResult.STATE_ERROR;
}
ExtendedLogEntry.build().actor(sender).acted(track)
.action("insert " + group.getName() + " " + pos)
.build().submit(plugin, sender);
save(track, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
Message.TRACK_ALREADY_CONTAINS.send(sender, track.getName(), group.getName());
return CommandResult.STATE_ERROR;
} catch (IndexOutOfBoundsException e) {
Message.TRACK_INSERT_ERROR_INVALID_POS.send(sender, pos);
return CommandResult.INVALID_ARGS;

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.commands.impl.track;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
@ -39,7 +40,6 @@ import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
@ -56,8 +56,9 @@ public class TrackRemove extends SubCommand<Track> {
return CommandResult.INVALID_ARGS;
}
try {
track.removeGroup(groupName);
DataMutateResult result = track.removeGroup(groupName);
if (result.asBoolean()) {
Message.TRACK_REMOVE_SUCCESS.send(sender, groupName, track.getName());
if (track.getGroups().size() > 1) {
Message.EMPTY.send(sender, Util.listToArrowSep(track.getGroups()));
@ -67,7 +68,7 @@ public class TrackRemove extends SubCommand<Track> {
.build().submit(plugin, sender);
save(track, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectLacksException e) {
} else {
Message.TRACK_DOES_NOT_CONTAIN.send(sender, track.getName(), groupName);
return CommandResult.STATE_ERROR;
}

View File

@ -48,7 +48,6 @@ import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import java.util.Set;
@ -120,7 +119,7 @@ public class UserDemote extends SubCommand<User> {
final String previous;
try {
previous = track.getPrevious(old);
} catch (ObjectLacksException e) {
} catch (IllegalArgumentException e) {
Message.TRACK_DOES_NOT_CONTAIN.send(sender, track.getName(), old);
return CommandResult.STATE_ERROR;
}
@ -131,17 +130,15 @@ public class UserDemote extends SubCommand<User> {
}
if (previous == null) {
user.unsetPermission(oldNode);
Message.USER_DEMOTE_ENDOFTRACK.send(sender, track.getName(), user.getFriendlyName(), old);
ExtendedLogEntry.build().actor(sender).acted(user)
.action("demote " + args.stream().collect(Collectors.joining(" ")))
.build().submit(plugin, sender);
save(user, sender, plugin);
plugin.getApiProvider().getEventFactory().handleUserDemote(user, track, old, null);
return CommandResult.SUCCESS;
}

View File

@ -46,7 +46,6 @@ import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import java.util.Set;
@ -123,6 +122,7 @@ public class UserPromote extends SubCommand<User> {
ExtendedLogEntry.build().actor(sender).acted(user)
.action("promote " + args.stream().collect(Collectors.joining(" ")))
.build().submit(plugin, sender);
save(user, sender, plugin);
plugin.getApiProvider().getEventFactory().handleUserPromote(user, track, null, first);
return CommandResult.SUCCESS;
@ -138,7 +138,7 @@ public class UserPromote extends SubCommand<User> {
final String next;
try {
next = track.getNext(old);
} catch (ObjectLacksException e) {
} catch (IllegalArgumentException e) {
Message.TRACK_DOES_NOT_CONTAIN.send(sender, track.getName(), old);
return CommandResult.STATE_ERROR;
}

View File

@ -35,6 +35,8 @@ import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@ -47,6 +49,7 @@ import java.util.concurrent.TimeUnit;
*/
public abstract class AbstractContextManager<T> implements ContextManager<T> {
protected final LuckPermsPlugin plugin;
private final List<ContextCalculator<T>> calculators = new CopyOnWriteArrayList<>();
private final List<ContextCalculator<?>> staticCalculators = new CopyOnWriteArrayList<>();
@ -56,9 +59,14 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
.expireAfterWrite(50L, TimeUnit.MILLISECONDS) // expire roughly every tick
.build(new Loader());
protected AbstractContextManager(LuckPermsPlugin plugin) {
this.plugin = plugin;
}
@Override
public ImmutableContextSet getApplicableContext(@NonNull T subject) {
// this is actually already immutable, but the Contexts method signature returns the interface.
// using the makeImmutable method is faster than casting
return getApplicableContexts(subject).getContexts().makeImmutable();
}
@ -68,8 +76,30 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
}
@Override
public void registerCalculator(ContextCalculator<T> calculator) {
registerCalculator(calculator, false);
public ImmutableContextSet getStaticContext() {
MutableContextSet accumulator = MutableContextSet.create();
for (ContextCalculator<?> calculator : staticCalculators) {
calculator.giveApplicableContext(null, accumulator);
}
return accumulator.makeImmutable();
}
@Override
public Contexts getStaticContexts() {
return formContexts(getStaticContext());
}
@Override
public Contexts formContexts(ImmutableContextSet contextSet) {
return new Contexts(
contextSet,
plugin.getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_PERMS),
plugin.getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_WORLD_PERMS),
true,
plugin.getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_GROUPS),
plugin.getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_WORLD_GROUPS),
false
);
}
@Override
@ -82,15 +112,6 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
}
}
@Override
public ImmutableContextSet getStaticContexts() {
MutableContextSet accumulator = MutableContextSet.create();
for (ContextCalculator<?> calculator : staticCalculators) {
calculator.giveApplicableContext(null, accumulator);
}
return accumulator.makeImmutable();
}
@Override
public void invalidateCache(@NonNull T subject){
lookupCache.invalidate(subject);

View File

@ -55,6 +55,20 @@ public interface ContextManager<T> {
*/
Contexts getApplicableContexts(@NonNull T subject);
/**
* Gets the contexts from the static calculators in this manager.
*
* @return the current active static contexts
*/
ImmutableContextSet getStaticContext();
/**
* Gets the contexts from the static calculators in this manager.
*
* @return the current active static contexts
*/
Contexts getStaticContexts();
/**
* Forms a {@link Contexts} instance from an {@link ImmutableContextSet}.
*
@ -64,12 +78,22 @@ public interface ContextManager<T> {
*/
Contexts formContexts(T subject, ImmutableContextSet contextSet);
/**
* Forms a {@link Contexts} instance from an {@link ImmutableContextSet}.
*
* @param contextSet the context set
* @return a contexts instance
*/
Contexts formContexts(ImmutableContextSet contextSet);
/**
* Registers a context calculator with the manager.
*
* @param calculator the calculator
*/
void registerCalculator(ContextCalculator<T> calculator);
default void registerCalculator(ContextCalculator<T> calculator) {
registerCalculator(calculator, false);
}
/**
* Registers a context calculator with the manager.
@ -79,13 +103,6 @@ public interface ContextManager<T> {
*/
void registerCalculator(ContextCalculator<T> calculator, boolean isStatic);
/**
* Gets the contexts from the static calculators in this manager.
*
* @return the current active static contexts
*/
ImmutableContextSet getStaticContexts();
/**
* Invalidates the lookup cache for a given subject
*

View File

@ -48,6 +48,7 @@ import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.api.delegates.PermissionHolderDelegate;
import me.lucko.luckperms.common.buffers.Cache;
import me.lucko.luckperms.common.caching.MetaAccumulator;
import me.lucko.luckperms.common.caching.handlers.StateListener;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.contexts.ContextSetComparator;
import me.lucko.luckperms.common.contexts.ExtractedContexts;
@ -208,7 +209,7 @@ public abstract class PermissionHolder {
* A set of runnables which are called when this objects state changes.
*/
@Getter
private final Set<Runnable> stateListeners = ConcurrentHashMap.newKeySet();
private final Set<StateListener> stateListeners = ConcurrentHashMap.newKeySet();
private void invalidateCache() {
nodesCopy.invalidate();
@ -216,9 +217,9 @@ public abstract class PermissionHolder {
weightCache.invalidate();
// Invalidate listeners
for (Runnable r : stateListeners) {
for (StateListener listener : stateListeners) {
try {
r.run();
listener.onStateChange();
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -32,11 +32,10 @@ import lombok.ToString;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.common.api.delegates.TrackDelegate;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.references.Identifiable;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.ArrayList;
import java.util.Collections;
@ -101,9 +100,9 @@ public class Track implements Identifiable<String> {
*
* @param current the group before the group being requested
* @return the group name, or null if the end of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
* @throws IllegalArgumentException if the track does not contain the group given
*/
public String getNext(Group current) throws ObjectLacksException {
public String getNext(Group current) throws IllegalArgumentException {
return getNext(current.getName());
}
@ -112,9 +111,9 @@ public class Track implements Identifiable<String> {
*
* @param current the group after the group being requested
* @return the group name, or null if the start of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
* @throws IllegalArgumentException if the track does not contain the group given
*/
public String getPrevious(Group current) throws ObjectLacksException {
public String getPrevious(Group current) throws IllegalArgumentException {
return getPrevious(current.getName());
}
@ -123,10 +122,12 @@ public class Track implements Identifiable<String> {
*
* @param current the group before the group being requested
* @return the group name, or null if the end of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
* @throws IllegalArgumentException if the track does not contain the group given
*/
public String getNext(String current) throws ObjectLacksException {
assertContains(current);
public String getNext(String current) throws IllegalArgumentException {
if (!containsGroup(current)) {
throw new IllegalArgumentException();
}
if (groups.indexOf(current) == groups.size() - 1) {
return null;
@ -140,10 +141,12 @@ public class Track implements Identifiable<String> {
*
* @param current the group after the group being requested
* @return the group name, or null if the start of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
* @throws IllegalArgumentException if the track does not contain the group given
*/
public String getPrevious(String current) throws ObjectLacksException {
assertContains(current);
public String getPrevious(String current) throws IllegalArgumentException {
if (!containsGroup(current)) {
throw new IllegalArgumentException();
}
if (groups.indexOf(current) == 0) {
return null;
@ -156,16 +159,19 @@ public class Track implements Identifiable<String> {
* Appends a group to the end of this track
*
* @param group the group to append
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
* @return the result of the operation
*/
public void appendGroup(Group group) throws ObjectAlreadyHasException {
public DataMutateResult appendGroup(Group group) {
if (containsGroup(group)) {
return DataMutateResult.ALREADY_HAS;
}
List<String> before = ImmutableList.copyOf(groups);
assertNotContains(group);
groups.add(group.getName());
List<String> after = ImmutableList.copyOf(groups);
plugin.getApiProvider().getEventFactory().handleTrackAddGroup(this, group.getName(), before, after);
return DataMutateResult.SUCCESS;
}
/**
@ -173,42 +179,49 @@ public class Track implements Identifiable<String> {
*
* @param group the group to be inserted
* @param position the index position (a value of 0 inserts at the start)
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
* @throws IndexOutOfBoundsException if the position is less than 0 or greater than the size of the track
* @return the result of the operation
*/
public void insertGroup(Group group, int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException {
List<String> before = ImmutableList.copyOf(groups);
public DataMutateResult insertGroup(Group group, int position) throws IndexOutOfBoundsException {
if (containsGroup(group)) {
return DataMutateResult.ALREADY_HAS;
}
assertNotContains(group);
List<String> before = ImmutableList.copyOf(groups);
groups.add(position, group.getName());
List<String> after = ImmutableList.copyOf(groups);
plugin.getApiProvider().getEventFactory().handleTrackAddGroup(this, group.getName(), before, after);
return DataMutateResult.SUCCESS;
}
/**
* Removes a group from this track
*
* @param group the group to remove
* @throws ObjectLacksException if the group is not on this track
* @return the result of the operation
*/
public void removeGroup(Group group) throws ObjectLacksException {
removeGroup(group.getName());
public DataMutateResult removeGroup(Group group) {
return removeGroup(group.getName());
}
/**
* Removes a group from this track
*
* @param group the group to remove
* @throws ObjectLacksException if the group is not on this track
* @return the result of the operation
*/
public void removeGroup(String group) throws ObjectLacksException {
public DataMutateResult removeGroup(String group) {
if (!containsGroup(group)) {
return DataMutateResult.LACKS;
}
List<String> before = ImmutableList.copyOf(groups);
assertContains(group);
groups.remove(group);
List<String> after = ImmutableList.copyOf(groups);
plugin.getApiProvider().getEventFactory().handleTrackRemoveGroup(this, group, before, after);
return DataMutateResult.SUCCESS;
}
/**
@ -239,16 +252,4 @@ public class Track implements Identifiable<String> {
groups.clear();
plugin.getApiProvider().getEventFactory().handleTrackClear(this, before);
}
private void assertNotContains(Group g) throws ObjectAlreadyHasException {
if (containsGroup(g)) {
throw new ObjectAlreadyHasException();
}
}
private void assertContains(String g) throws ObjectLacksException {
if (!containsGroup(g)) {
throw new ObjectLacksException();
}
}
}

View File

@ -25,51 +25,31 @@
package me.lucko.luckperms.common.primarygroup;
import lombok.NonNull;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.contexts.ExtractedContexts;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.User;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class AllParentsByWeightHolder extends StoredHolder {
private String cachedValue = null;
private boolean useCached = false;
public AllParentsByWeightHolder(@NonNull User user) {
public class AllParentsByWeightHolder extends CachedPrimaryGroupHolder {
public AllParentsByWeightHolder(User user) {
super(user);
user.getStateListeners().add(() -> useCached = false);
}
@Override
public String getValue() {
if (useCached) {
return cachedValue;
}
protected String calculateValue() {
Contexts contexts = user.getPlugin().getContextForUser(user);
if (contexts == null) {
contexts = new Contexts(
user.getPlugin().getContextManager().getStaticContexts(),
user.getPlugin().getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_PERMS),
user.getPlugin().getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_WORLD_PERMS),
true,
user.getPlugin().getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_GROUPS),
user.getPlugin().getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_WORLD_GROUPS),
false
);
contexts = user.getPlugin().getContextManager().getStaticContexts();
}
// hack to get a list of groups the holder is inheriting from
Set<String> groupNames = new HashSet<>();
Set<String> groupNames = new LinkedHashSet<>();
user.resolveInheritances(new NoopList<>(), groupNames, ExtractedContexts.generate(contexts));
List<Group> groups = new ArrayList<>();
@ -93,9 +73,7 @@ public class AllParentsByWeightHolder extends StoredHolder {
}
}
cachedValue = bestGroup == null ? null : bestGroup.getName();
useCached = true;
return cachedValue;
return bestGroup == null ? null : bestGroup.getName();
}
private static final class NoopList<E> extends AbstractList<E> implements List<E> {

View File

@ -0,0 +1,63 @@
/*
* 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.primarygroup;
import me.lucko.luckperms.common.buffers.Cache;
import me.lucko.luckperms.common.caching.handlers.StateListener;
import me.lucko.luckperms.common.model.User;
/**
* Abstract implementation of {@link StateListener} which caches all lookups.
*/
public abstract class CachedPrimaryGroupHolder extends StoredHolder implements StateListener {
// cache lookups
private final Cache<String> cache = new Cache<String>() {
@Override
protected String supply() {
return calculateValue();
}
};
public CachedPrimaryGroupHolder(User user) {
super(user);
user.getStateListeners().add(this);
}
protected abstract String calculateValue();
@Override
public String getValue() {
String s = cache.get();
return s != null ? s : getStoredValue();
}
@Override
public void onStateChange() {
cache.invalidate();
}
}

View File

@ -25,38 +25,28 @@
package me.lucko.luckperms.common.primarygroup;
import lombok.NonNull;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.User;
import java.util.ArrayList;
import java.util.List;
import java.util.LinkedHashSet;
import java.util.Set;
public class ParentsByWeightHolder extends StoredHolder {
private String cachedValue = null;
private boolean useCached = false;
public ParentsByWeightHolder(@NonNull User user) {
public class ParentsByWeightHolder extends CachedPrimaryGroupHolder {
public ParentsByWeightHolder(User user) {
super(user);
user.getStateListeners().add(() -> useCached = false);
}
@Override
public String getValue() {
if (useCached) {
return cachedValue;
protected String calculateValue() {
Contexts contexts = user.getPlugin().getContextForUser(user);
if (contexts == null) {
contexts = user.getPlugin().getContextManager().getStaticContexts();
}
Contexts contexts = user.getPlugin().getContextForUser(user);
ContextSet contextSet = contexts != null ? contexts.getContexts() : user.getPlugin().getContextManager().getStaticContexts();
List<Group> groups = new ArrayList<>();
for (Node node : user.filterNodes(contextSet)) {
Set<Group> groups = new LinkedHashSet<>();
for (Node node : user.filterNodes(contexts.getContexts())) {
if (!node.getValuePrimitive() || !node.isGroupNode()) {
continue;
}
@ -80,8 +70,6 @@ public class ParentsByWeightHolder extends StoredHolder {
}
}
cachedValue = bestGroup == null ? null : bestGroup.getName();
useCached = true;
return cachedValue;
return bestGroup == null ? null : bestGroup.getName();
}
}

View File

@ -26,12 +26,14 @@
package me.lucko.luckperms.common.primarygroup;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.NonNull;
import lombok.Setter;
import me.lucko.luckperms.common.model.User;
@RequiredArgsConstructor
/**
* Simple implementation of {@link PrimaryGroupHolder}, which just returns the stored value.
*/
public class StoredHolder implements PrimaryGroupHolder {
protected final User user;
@ -40,6 +42,10 @@ public class StoredHolder implements PrimaryGroupHolder {
@Setter
private String storedValue = null;
public StoredHolder(@NonNull User user) {
this.user = user;
}
public String getValue() {
return storedValue;
}

View File

@ -52,25 +52,29 @@ public class UuidCache {
private final UuidCacheDelegate delegate = new UuidCacheDelegate(this);
public UUID getUUID(UUID external) {
return plugin.getConfiguration().get(ConfigKeys.USE_SERVER_UUIDS) ? external : cache.getOrDefault(external, external);
return inUse() ? external : cache.getOrDefault(external, external);
}
public UUID getExternalUUID(UUID internal) {
return plugin.getConfiguration().get(ConfigKeys.USE_SERVER_UUIDS) ? internal : cache.inverse().getOrDefault(internal, internal);
return inUse() ? internal : cache.inverse().getOrDefault(internal, internal);
}
public void addToCache(UUID external, UUID internal) {
if (plugin.getConfiguration().get(ConfigKeys.USE_SERVER_UUIDS)) return;
if (inUse()) return;
cache.forcePut(external, internal);
}
public void clearCache(UUID external) {
if (plugin.getConfiguration().get(ConfigKeys.USE_SERVER_UUIDS)) return;
if (inUse()) return;
cache.remove(external);
}
public int getSize() {
return plugin.getConfiguration().get(ConfigKeys.USE_SERVER_UUIDS) ? 0 : cache.size();
return inUse() ? 0 : cache.size();
}
private boolean inUse() {
return plugin.getConfiguration().get(ConfigKeys.USE_SERVER_UUIDS);
}
}

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.sponge.contexts;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.config.ConfigKeys;
@ -35,9 +33,10 @@ import me.lucko.luckperms.sponge.LPSpongePlugin;
import org.spongepowered.api.service.permission.Subject;
@RequiredArgsConstructor
public class SpongeContextManager extends AbstractContextManager<Subject> {
private final LPSpongePlugin plugin;
public SpongeContextManager(LPSpongePlugin plugin) {
super(plugin);
}
@Override
public Contexts formContexts(Subject subject, ImmutableContextSet contextSet) {

View File

@ -41,7 +41,6 @@ import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.service.LuckPermsService;
@ -161,9 +160,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
for (String groupName : e.getValue().values()) {
Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group != null) {
try {
track.appendGroup(group);
} catch (ObjectAlreadyHasException ignored) {}
track.appendGroup(group);
}
}
}