Cleanup EventDispatcher and some other minor tidying

This commit is contained in:
Luck 2020-12-01 23:31:12 +00:00
parent 727c2f92c3
commit e183f520d6
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
6 changed files with 128 additions and 154 deletions

View File

@ -52,7 +52,8 @@ public class ApiPlatform implements Platform, PluginMetadata {
@Override
public @NonNull String getApiVersion() {
return "5.2";
String[] version = this.plugin.getBootstrap().getVersion().split("\\.");
return version[0] + '.' + version[1];
}
@Override

View File

@ -81,6 +81,7 @@ import net.luckperms.api.event.track.mutate.TrackAddGroupEvent;
import net.luckperms.api.event.track.mutate.TrackClearEvent;
import net.luckperms.api.event.track.mutate.TrackRemoveGroupEvent;
import net.luckperms.api.event.type.Cancellable;
import net.luckperms.api.event.type.ResultEvent;
import net.luckperms.api.event.user.UserCacheLoadEvent;
import net.luckperms.api.event.user.UserDataRecalculateEvent;
import net.luckperms.api.event.user.UserFirstLoginEvent;
@ -100,7 +101,6 @@ import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
public final class EventDispatcher {
private final AbstractEventBus<?> eventBus;
@ -113,27 +113,58 @@ public final class EventDispatcher {
return this.eventBus;
}
private boolean shouldPost(Class<? extends LuckPermsEvent> eventClass) {
return this.eventBus.shouldPost(eventClass);
}
private void post(LuckPermsEvent event) {
this.eventBus.post(event);
}
private <T extends LuckPermsEvent> void post(Class<T> eventClass, Supplier<T> supplier) {
private <T extends LuckPermsEvent> void postAsync(Class<T> eventClass, Object... params) {
// check against common mistakes - events with any sort of result shouldn't be posted async
if (Cancellable.class.isAssignableFrom(eventClass)) {
throw new RuntimeException("Cancellable event cannot be posted async (" + eventClass + ")");
}
if (ResultEvent.class.isAssignableFrom(eventClass)) {
throw new RuntimeException("ResultEvent event cannot be posted async (" + eventClass + ")");
}
// if there aren't any handlers registered for the event, don't bother trying to post it
if (!this.eventBus.shouldPost(eventClass)) {
return;
}
// async: generate an event class and post it
this.eventBus.getPlugin().getBootstrap().getScheduler().executeAsync(() -> {
if (!shouldPost(eventClass)) {
return;
}
T event = supplier.get();
post(event);
T event = generate(eventClass, params);
this.eventBus.post(event);
});
}
private <T extends LuckPermsEvent> void postSync(Class<T> eventClass, Object... params) {
// if there aren't any handlers registered for our event, don't bother trying to post it
if (!this.eventBus.shouldPost(eventClass)) {
return;
}
// generate an event class and post it
T event = generate(eventClass, params);
this.eventBus.post(event);
}
private <T extends LuckPermsEvent & Cancellable> boolean postCancellable(Class<T> eventClass, Object... params) {
// extract the initial state from the first parameter
boolean initialState = (boolean) params[0];
// if there aren't any handlers registered for the event, just return the initial state
if (!this.eventBus.shouldPost(eventClass)) {
return initialState;
}
// otherwise:
// - initialise an AtomicBoolean for the result with the initial state
// - replace the boolean with the AtomicBoolean in the params array
// - post the event
AtomicBoolean cancel = new AtomicBoolean(initialState);
params[0] = cancel;
postSync(eventClass, params);
// return the final status
return cancel.get();
}
@SuppressWarnings("unchecked")
private <T extends LuckPermsEvent> T generate(Class<T> eventClass, Object... params) {
@ -145,235 +176,171 @@ public final class EventDispatcher {
}
public void dispatchContextUpdate(Object subject) {
if (!shouldPost(ContextUpdateEvent.class)) {
return;
}
post(generate(ContextUpdateEvent.class, subject));
postSync(ContextUpdateEvent.class, subject);
}
public void dispatchExtensionLoad(Extension extension) {
post(ExtensionLoadEvent.class, () -> generate(ExtensionLoadEvent.class, extension));
postAsync(ExtensionLoadEvent.class, extension);
}
public void dispatchGroupCacheLoad(Group group, GroupCachedDataManager data) {
post(GroupCacheLoadEvent.class, () -> generate(GroupCacheLoadEvent.class, group.getApiProxy(), data));
postAsync(GroupCacheLoadEvent.class, group.getApiProxy(), data);
}
public void dispatchGroupCreate(Group group, CreationCause cause) {
post(GroupCreateEvent.class, () -> generate(GroupCreateEvent.class, group.getApiProxy(), cause));
postAsync(GroupCreateEvent.class, group.getApiProxy(), cause);
}
public void dispatchGroupDelete(Group group, DeletionCause cause) {
post(GroupDeleteEvent.class, () -> generate(GroupDeleteEvent.class, group.getName(), ImmutableSet.copyOf(group.normalData().asSet()), cause));
postAsync(GroupDeleteEvent.class, group.getName(), ImmutableSet.copyOf(group.normalData().asSet()), cause);
}
public void dispatchGroupLoadAll() {
post(GroupLoadAllEvent.class, () -> generate(GroupLoadAllEvent.class));
postAsync(GroupLoadAllEvent.class);
}
public void dispatchGroupLoad(Group group) {
post(GroupLoadEvent.class, () -> generate(GroupLoadEvent.class, group.getApiProxy()));
postAsync(GroupLoadEvent.class, group.getApiProxy());
}
public boolean dispatchLogBroadcast(boolean initialState, Action entry, LogBroadcastEvent.Origin origin) {
if (!shouldPost(LogBroadcastEvent.class)) {
return initialState;
}
AtomicBoolean cancel = new AtomicBoolean(initialState);
post(generate(LogBroadcastEvent.class, cancel, entry, origin));
return cancel.get();
return postCancellable(LogBroadcastEvent.class, initialState, entry, origin);
}
public boolean dispatchLogPublish(boolean initialState, Action entry) {
if (!shouldPost(LogPublishEvent.class)) {
return initialState;
}
AtomicBoolean cancel = new AtomicBoolean(initialState);
post(generate(LogPublishEvent.class, cancel, entry));
return cancel.get();
return postCancellable(LogPublishEvent.class, initialState, entry);
}
public boolean dispatchLogNetworkPublish(boolean initialState, UUID id, Action entry) {
if (!shouldPost(LogNetworkPublishEvent.class)) {
return initialState;
}
AtomicBoolean cancel = new AtomicBoolean(initialState);
post(generate(LogNetworkPublishEvent.class, cancel, id, entry));
return cancel.get();
return postCancellable(LogNetworkPublishEvent.class, initialState, id, entry);
}
public boolean dispatchLogNotify(boolean initialState, Action entry, LogNotifyEvent.Origin origin, Sender sender) {
if (!shouldPost(LogNotifyEvent.class)) {
return initialState;
}
AtomicBoolean cancel = new AtomicBoolean(initialState);
post(generate(LogNotifyEvent.class, cancel, entry, origin, new SenderPlatformEntity(sender)));
return cancel.get();
return postCancellable(LogNotifyEvent.class, initialState, entry, origin, new SenderPlatformEntity(sender));
}
public void dispatchLogReceive(UUID id, Action entry) {
post(LogReceiveEvent.class, () -> generate(LogReceiveEvent.class, id, entry));
postAsync(LogReceiveEvent.class, id, entry);
}
public void dispatchNodeAdd(Node node, PermissionHolder target, DataType dataType, Collection<? extends Node> before, Collection<? extends Node> after) {
post(NodeAddEvent.class, () -> generate(NodeAddEvent.class, proxy(target), dataType, ImmutableSet.copyOf(before), ImmutableSet.copyOf(after), node));
postAsync(NodeAddEvent.class, proxy(target), dataType, ImmutableSet.copyOf(before), ImmutableSet.copyOf(after), node);
}
public void dispatchNodeClear(PermissionHolder target, DataType dataType, Collection<? extends Node> before, Collection<? extends Node> after) {
post(NodeClearEvent.class, () -> generate(NodeClearEvent.class, proxy(target), dataType, ImmutableSet.copyOf(before), ImmutableSet.copyOf(after)));
postAsync(NodeClearEvent.class, proxy(target), dataType, ImmutableSet.copyOf(before), ImmutableSet.copyOf(after));
}
public void dispatchNodeRemove(Node node, PermissionHolder target, DataType dataType, Collection<? extends Node> before, Collection<? extends Node> after) {
post(NodeRemoveEvent.class, () -> generate(NodeRemoveEvent.class, proxy(target), dataType, ImmutableSet.copyOf(before), ImmutableSet.copyOf(after), node));
postAsync(NodeRemoveEvent.class, proxy(target), dataType, ImmutableSet.copyOf(before), ImmutableSet.copyOf(after), node);
}
public void dispatchConfigReload() {
post(ConfigReloadEvent.class, () -> generate(ConfigReloadEvent.class));
postAsync(ConfigReloadEvent.class);
}
public void dispatchPostSync() {
post(PostSyncEvent.class, () -> generate(PostSyncEvent.class));
postAsync(PostSyncEvent.class);
}
public boolean dispatchNetworkPreSync(boolean initialState, UUID id) {
if (!shouldPost(PreNetworkSyncEvent.class)) {
return initialState;
}
AtomicBoolean cancel = new AtomicBoolean(initialState);
post(generate(PreNetworkSyncEvent.class, cancel, id));
return cancel.get();
return postCancellable(PreNetworkSyncEvent.class, initialState, id);
}
public boolean dispatchPreSync(boolean initialState) {
if (!shouldPost(PreSyncEvent.class)) {
return initialState;
}
AtomicBoolean cancel = new AtomicBoolean(initialState);
post(generate(PreSyncEvent.class, cancel));
return cancel.get();
return postCancellable(PreSyncEvent.class, initialState);
}
public void dispatchTrackCreate(Track track, CreationCause cause) {
post(TrackCreateEvent.class, () -> generate(TrackCreateEvent.class, track.getApiProxy(), cause));
postAsync(TrackCreateEvent.class, track.getApiProxy(), cause);
}
public void dispatchTrackDelete(Track track, DeletionCause cause) {
post(TrackDeleteEvent.class, () -> generate(TrackDeleteEvent.class, track.getName(), ImmutableList.copyOf(track.getGroups()), cause));
postAsync(TrackDeleteEvent.class, track.getName(), ImmutableList.copyOf(track.getGroups()), cause);
}
public void dispatchTrackLoadAll() {
post(TrackLoadAllEvent.class, () -> generate(TrackLoadAllEvent.class));
postAsync(TrackLoadAllEvent.class);
}
public void dispatchTrackLoad(Track track) {
post(TrackLoadEvent.class, () -> generate(TrackLoadEvent.class, track.getApiProxy()));
postAsync(TrackLoadEvent.class, track.getApiProxy());
}
public void dispatchTrackAddGroup(Track track, String group, List<String> before, List<String> after) {
post(TrackAddGroupEvent.class, () -> generate(TrackAddGroupEvent.class, track.getApiProxy(), ImmutableList.copyOf(before), ImmutableList.copyOf(after), group));
postAsync(TrackAddGroupEvent.class, track.getApiProxy(), ImmutableList.copyOf(before), ImmutableList.copyOf(after), group);
}
public void dispatchTrackClear(Track track, List<String> before) {
post(TrackClearEvent.class, () -> generate(TrackClearEvent.class, track.getApiProxy(), ImmutableList.copyOf(before), ImmutableList.of()));
postAsync(TrackClearEvent.class, track.getApiProxy(), ImmutableList.copyOf(before), ImmutableList.of());
}
public void dispatchTrackRemoveGroup(Track track, String group, List<String> before, List<String> after) {
post(TrackRemoveGroupEvent.class, () -> generate(TrackRemoveGroupEvent.class, track.getApiProxy(), ImmutableList.copyOf(before), ImmutableList.copyOf(after), group));
postAsync(TrackRemoveGroupEvent.class, track.getApiProxy(), ImmutableList.copyOf(before), ImmutableList.copyOf(after), group);
}
public void dispatchUserCacheLoad(User user, UserCachedDataManager data) {
post(UserCacheLoadEvent.class, () -> generate(UserCacheLoadEvent.class, user.getApiProxy(), data));
postAsync(UserCacheLoadEvent.class, user.getApiProxy(), data);
}
public void dispatchDataRecalculate(PermissionHolder holder) {
if (holder.getType() == HolderType.USER) {
User user = (User) holder;
post(UserDataRecalculateEvent.class, () -> generate(UserDataRecalculateEvent.class, user.getApiProxy(), user.getCachedData()));
postAsync(UserDataRecalculateEvent.class, user.getApiProxy(), user.getCachedData());
} else {
Group group = (Group) holder;
post(GroupDataRecalculateEvent.class, () -> generate(GroupDataRecalculateEvent.class, group.getApiProxy(), group.getCachedData()));
postAsync(GroupDataRecalculateEvent.class, group.getApiProxy(), group.getCachedData());
}
}
public void dispatchUserFirstLogin(UUID uniqueId, String username) {
post(UserFirstLoginEvent.class, () -> generate(UserFirstLoginEvent.class, uniqueId, username));
postAsync(UserFirstLoginEvent.class, uniqueId, username);
}
public void dispatchPlayerLoginProcess(UUID uniqueId, String username, User user) {
if (!shouldPost(PlayerLoginProcessEvent.class)) {
return;
}
post(generate(PlayerLoginProcessEvent.class, uniqueId, username, user.getApiProxy()));
postSync(PlayerLoginProcessEvent.class, uniqueId, username, user.getApiProxy());
}
public void dispatchPlayerDataSave(UUID uniqueId, String username, PlayerSaveResult result) {
post(PlayerDataSaveEvent.class, () -> generate(PlayerDataSaveEvent.class, uniqueId, username, result));
postAsync(PlayerDataSaveEvent.class, uniqueId, username, result);
}
public String dispatchUniqueIdDetermineType(UUID uniqueId, String initialType) {
if (!shouldPost(UniqueIdDetermineTypeEvent.class)) {
return initialType;
}
AtomicReference<String> result = new AtomicReference<>(initialType);
post(generate(UniqueIdDetermineTypeEvent.class, result, uniqueId));
postSync(UniqueIdDetermineTypeEvent.class, result, uniqueId);
return result.get();
}
public UUID dispatchUniqueIdLookup(String username, UUID initial) {
if (!shouldPost(UniqueIdLookupEvent.class)) {
return initial;
}
AtomicReference<UUID> result = new AtomicReference<>(initial);
post(generate(UniqueIdLookupEvent.class, result, username));
postSync(UniqueIdLookupEvent.class, result, username);
return result.get();
}
public String dispatchUsernameLookup(UUID uniqueId, String initial) {
if (!shouldPost(UsernameLookupEvent.class)) {
return initial;
}
AtomicReference<String> result = new AtomicReference<>(initial);
post(generate(UsernameLookupEvent.class, result, uniqueId));
postSync(UsernameLookupEvent.class, result, uniqueId);
return result.get();
}
public boolean dispatchUsernameValidityCheck(String username, boolean initialState) {
if (!shouldPost(UsernameValidityCheckEvent.class)) {
return initialState;
}
AtomicBoolean result = new AtomicBoolean(initialState);
post(generate(UsernameValidityCheckEvent.class, username, result));
postSync(UsernameValidityCheckEvent.class, username, result);
return result.get();
}
public void dispatchUserLoad(User user) {
post(UserLoadEvent.class, () -> generate(UserLoadEvent.class, user.getApiProxy()));
postAsync(UserLoadEvent.class, user.getApiProxy());
}
public void dispatchUserDemote(User user, Track track, String from, String to, @Nullable Sender source) {
post(UserDemoteEvent.class, () -> {
Source s = source == null ? UnknownSource.INSTANCE : new EntitySourceImpl(new SenderPlatformEntity(source));
return generate(UserDemoteEvent.class, s, track.getApiProxy(), user.getApiProxy(), Optional.ofNullable(from), Optional.ofNullable(to));
});
public void dispatchUserDemote(User user, Track track, String from, String to, @Nullable Sender sender) {
Source source = sender == null ? UnknownSource.INSTANCE : new EntitySourceImpl(new SenderPlatformEntity(sender));
postAsync(UserDemoteEvent.class, source, track.getApiProxy(), user.getApiProxy(), Optional.ofNullable(from), Optional.ofNullable(to));
}
public void dispatchUserPromote(User user, Track track, String from, String to, @Nullable Sender source) {
post(UserPromoteEvent.class, () -> {
Source s = source == null ? UnknownSource.INSTANCE : new EntitySourceImpl(new SenderPlatformEntity(source));
return generate(UserPromoteEvent.class, s, track.getApiProxy(), user.getApiProxy(), Optional.ofNullable(from), Optional.ofNullable(to));
});
public void dispatchUserPromote(User user, Track track, String from, String to, @Nullable Sender sender) {
Source source = sender == null ? UnknownSource.INSTANCE : new EntitySourceImpl(new SenderPlatformEntity(sender));
postAsync(UserPromoteEvent.class, source, track.getApiProxy(), user.getApiProxy(), Optional.ofNullable(from), Optional.ofNullable(to));
}
private static ApiPermissionHolder proxy(PermissionHolder holder) {

View File

@ -35,7 +35,7 @@ final class FlagUtils {
private static final EnumSet<Flag> DEFAULT_FLAGS_SET = EnumSet.allOf(Flag.class);
private static final int DEFAULT_FLAGS_SIZE = DEFAULT_FLAGS_SET.size();
static final byte DEFAULT_FLAGS = encodeAsByte(DEFAULT_FLAGS_SET);
static final byte DEFAULT_FLAGS = toByte0(DEFAULT_FLAGS_SET);
/* bitwise utility methods */
@ -48,10 +48,10 @@ final class FlagUtils {
if (settings.size() == DEFAULT_FLAGS_SIZE) {
return DEFAULT_FLAGS;
}
return encodeAsByte(settings);
return toByte0(settings);
}
private static byte encodeAsByte(Set<Flag> settings) {
private static byte toByte0(Set<Flag> settings) {
byte b = 0;
for (Flag setting : settings) {
b |= (1 << setting.ordinal());

View File

@ -81,7 +81,7 @@ public class Storage {
}
}
private <T> CompletableFuture<T> makeFuture(Callable<T> supplier) {
private <T> CompletableFuture<T> future(Callable<T> supplier) {
return CompletableFuture.supplyAsync(() -> {
try {
return supplier.call();
@ -94,7 +94,7 @@ public class Storage {
}, this.plugin.getBootstrap().getScheduler().async());
}
private CompletableFuture<Void> makeFuture(Throwing.Runnable runnable) {
private CompletableFuture<Void> future(Throwing.Runnable runnable) {
return CompletableFuture.runAsync(() -> {
try {
runnable.run();
@ -132,19 +132,19 @@ public class Storage {
}
public CompletableFuture<Void> logAction(Action entry) {
return makeFuture(() -> this.implementation.logAction(entry));
return future(() -> this.implementation.logAction(entry));
}
public CompletableFuture<Log> getLog() {
return makeFuture(this.implementation::getLog);
return future(this.implementation::getLog);
}
public CompletableFuture<Void> applyBulkUpdate(BulkUpdate bulkUpdate) {
return makeFuture(() -> this.implementation.applyBulkUpdate(bulkUpdate));
return future(() -> this.implementation.applyBulkUpdate(bulkUpdate));
}
public CompletableFuture<User> loadUser(UUID uniqueId, String username) {
return makeFuture(() -> {
return future(() -> {
User user = this.implementation.loadUser(uniqueId, username);
if (user != null) {
this.plugin.getEventDispatcher().dispatchUserLoad(user);
@ -154,15 +154,15 @@ public class Storage {
}
public CompletableFuture<Void> saveUser(User user) {
return makeFuture(() -> this.implementation.saveUser(user));
return future(() -> this.implementation.saveUser(user));
}
public CompletableFuture<Set<UUID>> getUniqueUsers() {
return makeFuture(this.implementation::getUniqueUsers);
return future(this.implementation::getUniqueUsers);
}
public <N extends Node> CompletableFuture<List<NodeEntry<UUID, N>>> searchUserNodes(ConstraintNodeMatcher<N> constraint) {
return makeFuture(() -> {
return future(() -> {
List<NodeEntry<UUID, N>> result = this.implementation.searchUserNodes(constraint);
result.removeIf(entry -> entry.getNode().hasExpired());
return ImmutableList.copyOf(result);
@ -170,7 +170,7 @@ public class Storage {
}
public CompletableFuture<Group> createAndLoadGroup(String name, CreationCause cause) {
return makeFuture(() -> {
return future(() -> {
Group group = this.implementation.createAndLoadGroup(name.toLowerCase());
if (group != null) {
this.plugin.getEventDispatcher().dispatchGroupCreate(group, cause);
@ -180,7 +180,7 @@ public class Storage {
}
public CompletableFuture<Optional<Group>> loadGroup(String name) {
return makeFuture(() -> {
return future(() -> {
Optional<Group> group = this.implementation.loadGroup(name.toLowerCase());
if (group.isPresent()) {
this.plugin.getEventDispatcher().dispatchGroupLoad(group.get());
@ -190,25 +190,25 @@ public class Storage {
}
public CompletableFuture<Void> loadAllGroups() {
return makeFuture(() -> {
return future(() -> {
this.implementation.loadAllGroups();
this.plugin.getEventDispatcher().dispatchGroupLoadAll();
});
}
public CompletableFuture<Void> saveGroup(Group group) {
return makeFuture(() -> this.implementation.saveGroup(group));
return future(() -> this.implementation.saveGroup(group));
}
public CompletableFuture<Void> deleteGroup(Group group, DeletionCause cause) {
return makeFuture(() -> {
return future(() -> {
this.implementation.deleteGroup(group);
this.plugin.getEventDispatcher().dispatchGroupDelete(group, cause);
});
}
public <N extends Node> CompletableFuture<List<NodeEntry<String, N>>> searchGroupNodes(ConstraintNodeMatcher<N> constraint) {
return makeFuture(() -> {
return future(() -> {
List<NodeEntry<String, N>> result = this.implementation.searchGroupNodes(constraint);
result.removeIf(entry -> entry.getNode().hasExpired());
return ImmutableList.copyOf(result);
@ -216,7 +216,7 @@ public class Storage {
}
public CompletableFuture<Track> createAndLoadTrack(String name, CreationCause cause) {
return makeFuture(() -> {
return future(() -> {
Track track = this.implementation.createAndLoadTrack(name.toLowerCase());
if (track != null) {
this.plugin.getEventDispatcher().dispatchTrackCreate(track, cause);
@ -226,7 +226,7 @@ public class Storage {
}
public CompletableFuture<Optional<Track>> loadTrack(String name) {
return makeFuture(() -> {
return future(() -> {
Optional<Track> track = this.implementation.loadTrack(name.toLowerCase());
if (track.isPresent()) {
this.plugin.getEventDispatcher().dispatchTrackLoad(track.get());
@ -236,25 +236,25 @@ public class Storage {
}
public CompletableFuture<Void> loadAllTracks() {
return makeFuture(() -> {
return future(() -> {
this.implementation.loadAllTracks();
this.plugin.getEventDispatcher().dispatchTrackLoadAll();
});
}
public CompletableFuture<Void> saveTrack(Track track) {
return makeFuture(() -> this.implementation.saveTrack(track));
return future(() -> this.implementation.saveTrack(track));
}
public CompletableFuture<Void> deleteTrack(Track track, DeletionCause cause) {
return makeFuture(() -> {
return future(() -> {
this.implementation.deleteTrack(track);
this.plugin.getEventDispatcher().dispatchTrackDelete(track, cause);
});
}
public CompletableFuture<PlayerSaveResult> savePlayerData(UUID uniqueId, String username) {
return makeFuture(() -> {
return future(() -> {
PlayerSaveResult result = this.implementation.savePlayerData(uniqueId, username);
if (result != null) {
this.plugin.getEventDispatcher().dispatchPlayerDataSave(uniqueId, username, result);
@ -264,14 +264,14 @@ public class Storage {
}
public CompletableFuture<Void> deletePlayerData(UUID uniqueId) {
return makeFuture(() -> this.implementation.deletePlayerData(uniqueId));
return future(() -> this.implementation.deletePlayerData(uniqueId));
}
public CompletableFuture<UUID> getPlayerUniqueId(String username) {
return makeFuture(() -> this.implementation.getPlayerUniqueId(username));
return future(() -> this.implementation.getPlayerUniqueId(username));
}
public CompletableFuture<String> getPlayerName(UUID uniqueId) {
return makeFuture(() -> this.implementation.getPlayerName(uniqueId));
return future(() -> this.implementation.getPlayerName(uniqueId));
}
}

View File

@ -30,6 +30,8 @@ import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.concurrent.locks.Lock;
public class ExpireTemporaryTask implements Runnable {
private final LuckPermsPlugin plugin;
@ -67,15 +69,17 @@ public class ExpireTemporaryTask implements Runnable {
// return true if the holder's io lock is currently held, false otherwise
private static boolean shouldSkip(PermissionHolder holder) {
Lock lock = holder.getIoLock();
// if the holder is currently being manipulated by the storage impl,
// don't attempt to audit temporary permissions
if (!holder.getIoLock().tryLock()) {
if (!lock.tryLock()) {
// if #tryLock returns false, it means it's held by something else
return true;
}
// immediately release the lock & return false
holder.getIoLock().unlock();
lock.unlock();
return false;
}
}

View File

@ -61,7 +61,9 @@ public class PermissionRegistry implements AutoCloseable {
}
public List<String> rootAsList() {
return this.rootNode.makeImmutableCopy().getNodeEndings().stream().map(Map.Entry::getValue).collect(ImmutableCollectors.toList());
return this.rootNode.makeImmutableCopy().getNodeEndings().stream()
.map(Map.Entry::getValue)
.collect(ImmutableCollectors.toList());
}
public void offer(String permission) {
@ -92,7 +94,7 @@ public class PermissionRegistry implements AutoCloseable {
private void doInsert(String permission) {
// split the permission up into parts
List<String> parts = DOT_SPLIT.splitToList(permission);
Iterable<String> parts = DOT_SPLIT.split(permission);
// insert the permission into the node structure
TreeNode current = this.rootNode;