Add some convenience API methods (#1926)

This commit is contained in:
Luck 2020-05-09 23:41:28 +01:00
parent 3d358e57ff
commit 7845d89f10
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
32 changed files with 429 additions and 86 deletions

View File

@ -42,6 +42,7 @@ import net.luckperms.api.node.NodeBuilderRegistry;
import net.luckperms.api.node.matcher.NodeMatcherFactory; import net.luckperms.api.node.matcher.NodeMatcherFactory;
import net.luckperms.api.platform.Platform; import net.luckperms.api.platform.Platform;
import net.luckperms.api.platform.PluginMetadata; import net.luckperms.api.platform.PluginMetadata;
import net.luckperms.api.player.PlayerAdapter;
import net.luckperms.api.query.QueryOptionsRegistry; import net.luckperms.api.query.QueryOptionsRegistry;
import net.luckperms.api.track.Track; import net.luckperms.api.track.Track;
import net.luckperms.api.track.TrackManager; import net.luckperms.api.track.TrackManager;
@ -116,6 +117,32 @@ public interface LuckPerms {
*/ */
@NonNull TrackManager getTrackManager(); @NonNull TrackManager getTrackManager();
/**
* Gets the {@link PlayerAdapter} instance, a utility class for adapting platform Player
* instances to {@link User}s.
*
* <p>The {@code playerClass} parameter must be equal to the class or interface used by the
* server platform to represent players.</p>
*
* <p>Specifically:</p>
*
* <p></p>
* <ul>
* <li>{@code org.bukkit.entity.Player}</li>
* <li>{@code net.md_5.bungee.api.connection.ProxiedPlayer}</li>
* <li>{@code org.spongepowered.api/entity.living.player.Player}</li>
* <li>{@code cn.nukkit.Player}</li>
* <li>{@code com.velocitypowered.api.proxy.Player}</li>
* </ul>
*
* @param playerClass the class used by the platform to represent players
* @param <T> the player class type
* @return the player adapter
* @throws IllegalArgumentException if the player class is not correct
* @since 5.1
*/
<T> @NonNull PlayerAdapter<T> getPlayerAdapter(Class<T> playerClass);
/** /**
* Gets the {@link Platform}, which represents the server platform the * Gets the {@link Platform}, which represents the server platform the
* plugin is running on. * plugin is running on.

View File

@ -25,7 +25,10 @@
package net.luckperms.api.cacheddata; package net.luckperms.api.cacheddata;
import net.luckperms.api.context.ContextManager;
import net.luckperms.api.model.PermissionHolder; import net.luckperms.api.model.PermissionHolder;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.model.user.User;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
@ -56,23 +59,57 @@ public interface CachedDataManager {
@NonNull Container<CachedMetaData> metaData(); @NonNull Container<CachedMetaData> metaData();
/** /**
* Gets PermissionData from the cache, given a specified context. * Gets PermissionData from the cache, using the given query options.
* *
* @param queryOptions the query options * @param queryOptions the query options
* @return a permission data instance * @return a permission data instance
* @throws NullPointerException if contexts is null
*/ */
@NonNull CachedPermissionData getPermissionData(@NonNull QueryOptions queryOptions); @NonNull CachedPermissionData getPermissionData(@NonNull QueryOptions queryOptions);
/** /**
* Gets MetaData from the cache, given a specified context. * Gets MetaData from the cache, using the given query options.
* *
* @param queryOptions the query options * @param queryOptions the query options
* @return a meta data instance * @return a meta data instance
* @throws NullPointerException if contexts is null
*/ */
@NonNull CachedMetaData getMetaData(@NonNull QueryOptions queryOptions); @NonNull CachedMetaData getMetaData(@NonNull QueryOptions queryOptions);
/**
* Gets PermissionData from the cache, using the most appropriate query options
* available at the time.
*
* <p>For {@link User}s, the most appropriate query options will be their
* {@link ContextManager#getQueryOptions(User) current active query options} if the
* corresponding player is online, and otherwise, will fallback to
* {@link ContextManager#getStaticQueryOptions() the current static query options}
* if they are offline.</p>
*
* <p>For {@link Group}s, the most appropriate query options will always be
* {@link ContextManager#getStaticQueryOptions()} the current static query options.</p>
*
* @return a permission data instance
* @since 5.1
*/
@NonNull CachedPermissionData getPermissionData();
/**
* Gets MetaData from the cache, using the most appropriate query options
* available at the time.
*
* <p>For {@link User}s, the most appropriate query options will be their
* {@link ContextManager#getQueryOptions(User) current active query options} if the
* corresponding player is online, and otherwise, will fallback to
* {@link ContextManager#getStaticQueryOptions() the current static query options}
* if they are offline.</p>
*
* <p>For {@link Group}s, the most appropriate query options will always be
* {@link ContextManager#getStaticQueryOptions()} the current static query options.</p>
*
* @return a meta data instance
* @since 5.1
*/
@NonNull CachedMetaData getMetaData();
/** /**
* Invalidates all cached {@link CachedPermissionData} and {@link CachedMetaData} * Invalidates all cached {@link CachedPermissionData} and {@link CachedMetaData}
* instances. * instances.

View File

@ -37,11 +37,11 @@ import java.util.Optional;
* Manages {@link ContextCalculator}s, and calculates applicable contexts for a * Manages {@link ContextCalculator}s, and calculates applicable contexts for a
* given type. * given type.
* *
* This interface accepts {@link Object} types as a parameter to avoid having to depend * <p>This interface accepts {@link Object} types as a parameter to avoid having to depend
* on specific server implementations. In all cases, the "player" or "subject" type for * on specific server implementations. In all cases, the "player" or "subject" type for
* the platform must be used. * the platform must be used.</p>
* *
* Specifically: * <p>Specifically:</p>
* *
* <p></p> * <p></p>
* <ul> * <ul>

View File

@ -0,0 +1,115 @@
/*
* 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 net.luckperms.api.player;
import net.luckperms.api.cacheddata.CachedDataManager;
import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.cacheddata.CachedPermissionData;
import net.luckperms.api.context.ContextManager;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.user.User;
import net.luckperms.api.model.user.UserManager;
import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.UUID;
/**
* A utility class for adapting platform Player instances to LuckPerms {@link User}s.
*
* <p>Note: this class will only work for online players.</p>
*
* <p>The "player type" parameter must be equal to the class or interface used by the
* server platform to represent players.</p>
*
* <p>Specifically:</p>
*
* <p></p>
* <ul>
* <li>{@code org.bukkit.entity.Player}</li>
* <li>{@code net.md_5.bungee.api.connection.ProxiedPlayer}</li>
* <li>{@code org.spongepowered.api/entity.living.player.Player}</li>
* <li>{@code cn.nukkit.Player}</li>
* <li>{@code com.velocitypowered.api.proxy.Player}</li>
* </ul>
*
* @param <T> the player type
* @since 5.1
*/
public interface PlayerAdapter<T> {
/**
* Gets the {@link User} instance for the given {@code player}.
*
* @param player the player
* @return the user
* @see UserManager#getUser(UUID)
*/
@NonNull User getUser(@NonNull T player);
/**
* Gets current {@link ImmutableContextSet active context} for the {@code player}.
*
* @param player the player
* @return the active context for the player
* @see ContextManager#getContext(Object)
*/
@NonNull ImmutableContextSet getContext(@NonNull T player);
/**
* Gets current {@link QueryOptions active query options} for the {@code player}.
*
* @param player the player
* @return the active query options for the player
* @see ContextManager#getQueryOptions(Object)
*/
@NonNull QueryOptions getQueryOptions(@NonNull T player);
/**
* Gets the current {@link CachedPermissionData} for the {@code player},
* using their {@link #getQueryOptions(Object) active query options}.
*
* @param player the player
* @return the cached permission data for the player
* @see CachedDataManager#getPermissionData()
*/
default @NonNull CachedPermissionData getPermissionData(@NonNull T player) {
return getUser(player).getCachedData().getPermissionData(getQueryOptions(player));
}
/**
* Gets the current {@link CachedMetaData} for the {@code player},
* using their {@link #getQueryOptions(Object) active query options}.
*
* @param player the player
* @return the cached meta data for the player
* @see CachedDataManager#getMetaData()
*/
default @NonNull CachedMetaData getMetaData(@NonNull T player) {
return getUser(player).getCachedData().getMetaData(getQueryOptions(player));
}
}

View File

@ -40,9 +40,10 @@ import net.luckperms.api.query.QueryOptions;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class BukkitContextManager extends ContextManager<Player> { public class BukkitContextManager extends ContextManager<Player, Player> {
public static final OptionKey<Boolean> OP_OPTION = OptionKey.of("op", Boolean.class); public static final OptionKey<Boolean> OP_OPTION = OptionKey.of("op", Boolean.class);
@ -61,13 +62,18 @@ public class BukkitContextManager extends ContextManager<Player> {
}); });
public BukkitContextManager(LPBukkitPlugin plugin) { public BukkitContextManager(LPBukkitPlugin plugin) {
super(plugin, Player.class); super(plugin, Player.class, Player.class);
} }
public void onPlayerQuit(Player player) { public void onPlayerQuit(Player player) {
this.onlineSubjectCaches.remove(player); this.onlineSubjectCaches.remove(player);
} }
@Override
public UUID getUniqueId(Player player) {
return player.getUniqueId();
}
@Override @Override
public QueryOptionsCache<Player> getCacheFor(Player subject) { public QueryOptionsCache<Player> getCacheFor(Player subject) {
if (subject == null) { if (subject == null) {

View File

@ -36,7 +36,6 @@ import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.calculator.CalculatorFactory; import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.command.CommandManager; import me.lucko.luckperms.common.command.CommandManager;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter; import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.dependencies.Dependency; import me.lucko.luckperms.common.dependencies.Dependency;
import me.lucko.luckperms.common.event.AbstractEventBus; import me.lucko.luckperms.common.event.AbstractEventBus;
import me.lucko.luckperms.common.messaging.MessagingFactory; import me.lucko.luckperms.common.messaging.MessagingFactory;
@ -52,7 +51,6 @@ import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
import net.luckperms.api.LuckPerms; import net.luckperms.api.LuckPerms;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -75,7 +73,7 @@ public class LPBungeePlugin extends AbstractLuckPermsPlugin {
private StandardUserManager userManager; private StandardUserManager userManager;
private StandardGroupManager groupManager; private StandardGroupManager groupManager;
private StandardTrackManager trackManager; private StandardTrackManager trackManager;
private ContextManager<ProxiedPlayer> contextManager; private BungeeContextManager contextManager;
public LPBungeePlugin(LPBungeeBootstrap bootstrap) { public LPBungeePlugin(LPBungeeBootstrap bootstrap) {
this.bootstrap = bootstrap; this.bootstrap = bootstrap;
@ -236,7 +234,7 @@ public class LPBungeePlugin extends AbstractLuckPermsPlugin {
} }
@Override @Override
public ContextManager<ProxiedPlayer> getContextManager() { public BungeeContextManager getContextManager() {
return this.contextManager; return this.contextManager;
} }

View File

@ -36,16 +36,22 @@ import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class BungeeContextManager extends ContextManager<ProxiedPlayer> { public class BungeeContextManager extends ContextManager<ProxiedPlayer, ProxiedPlayer> {
private final LoadingCache<ProxiedPlayer, QueryOptions> contextsCache = CaffeineFactory.newBuilder() private final LoadingCache<ProxiedPlayer, QueryOptions> contextsCache = CaffeineFactory.newBuilder()
.expireAfterWrite(50, TimeUnit.MILLISECONDS) .expireAfterWrite(50, TimeUnit.MILLISECONDS)
.build(this::calculate); .build(this::calculate);
public BungeeContextManager(LPBungeePlugin plugin) { public BungeeContextManager(LPBungeePlugin plugin) {
super(plugin, ProxiedPlayer.class); super(plugin, ProxiedPlayer.class, ProxiedPlayer.class);
}
@Override
public UUID getUniqueId(ProxiedPlayer player) {
return player.getUniqueId();
} }
@Override @Override

View File

@ -33,6 +33,7 @@ import me.lucko.luckperms.common.api.implementation.ApiMetaStackFactory;
import me.lucko.luckperms.common.api.implementation.ApiNodeBuilderRegistry; import me.lucko.luckperms.common.api.implementation.ApiNodeBuilderRegistry;
import me.lucko.luckperms.common.api.implementation.ApiNodeMatcherFactory; import me.lucko.luckperms.common.api.implementation.ApiNodeMatcherFactory;
import me.lucko.luckperms.common.api.implementation.ApiPlatform; import me.lucko.luckperms.common.api.implementation.ApiPlatform;
import me.lucko.luckperms.common.api.implementation.ApiPlayerAdapter;
import me.lucko.luckperms.common.api.implementation.ApiQueryOptionsRegistry; import me.lucko.luckperms.common.api.implementation.ApiQueryOptionsRegistry;
import me.lucko.luckperms.common.api.implementation.ApiTrackManager; import me.lucko.luckperms.common.api.implementation.ApiTrackManager;
import me.lucko.luckperms.common.api.implementation.ApiUserManager; import me.lucko.luckperms.common.api.implementation.ApiUserManager;
@ -53,11 +54,13 @@ import net.luckperms.api.node.NodeBuilderRegistry;
import net.luckperms.api.node.matcher.NodeMatcherFactory; import net.luckperms.api.node.matcher.NodeMatcherFactory;
import net.luckperms.api.platform.Platform; import net.luckperms.api.platform.Platform;
import net.luckperms.api.platform.PluginMetadata; import net.luckperms.api.platform.PluginMetadata;
import net.luckperms.api.player.PlayerAdapter;
import net.luckperms.api.query.QueryOptionsRegistry; import net.luckperms.api.query.QueryOptionsRegistry;
import net.luckperms.api.track.TrackManager; import net.luckperms.api.track.TrackManager;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -72,6 +75,7 @@ public class LuckPermsApiProvider implements LuckPerms {
private final UserManager userManager; private final UserManager userManager;
private final GroupManager groupManager; private final GroupManager groupManager;
private final TrackManager trackManager; private final TrackManager trackManager;
private final PlayerAdapter<?> playerAdapter;
private final ActionLogger actionLogger; private final ActionLogger actionLogger;
private final ContextManager contextManager; private final ContextManager contextManager;
private final MetaStackFactory metaStackFactory; private final MetaStackFactory metaStackFactory;
@ -83,6 +87,7 @@ public class LuckPermsApiProvider implements LuckPerms {
this.userManager = new ApiUserManager(plugin, plugin.getUserManager()); this.userManager = new ApiUserManager(plugin, plugin.getUserManager());
this.groupManager = new ApiGroupManager(plugin, plugin.getGroupManager()); this.groupManager = new ApiGroupManager(plugin, plugin.getGroupManager());
this.trackManager = new ApiTrackManager(plugin, plugin.getTrackManager()); this.trackManager = new ApiTrackManager(plugin, plugin.getTrackManager());
this.playerAdapter = new ApiPlayerAdapter<>(plugin.getUserManager(), plugin.getContextManager());
this.actionLogger = new ApiActionLogger(plugin); this.actionLogger = new ApiActionLogger(plugin);
this.contextManager = new ApiContextManager(plugin, plugin.getContextManager()); this.contextManager = new ApiContextManager(plugin, plugin.getContextManager());
this.metaStackFactory = new ApiMetaStackFactory(plugin); this.metaStackFactory = new ApiMetaStackFactory(plugin);
@ -118,6 +123,17 @@ public class LuckPermsApiProvider implements LuckPerms {
return this.trackManager; return this.trackManager;
} }
@SuppressWarnings("unchecked")
@Override
public @NonNull <T> PlayerAdapter<T> getPlayerAdapter(Class<T> playerClass) {
Objects.requireNonNull(playerClass, "playerClass");
Class<?> expectedClass = this.plugin.getContextManager().getPlayerClass();
if (!expectedClass.equals(playerClass)) {
throw new IllegalArgumentException("Player class " + playerClass.getName() + " does not equal " + expectedClass.getName());
}
return (PlayerAdapter<T>) this.playerAdapter;
}
@Override @Override
public @NonNull CompletableFuture<Void> runUpdateTask() { public @NonNull CompletableFuture<Void> runUpdateTask() {
return this.plugin.getSyncTaskBuffer().request(); return this.plugin.getSyncTaskBuffer().request();

View File

@ -46,7 +46,7 @@ public class ApiContextManager implements net.luckperms.api.context.ContextManag
private final LuckPermsPlugin plugin; private final LuckPermsPlugin plugin;
private final ContextManager handle; private final ContextManager handle;
public ApiContextManager(LuckPermsPlugin plugin, ContextManager<?> handle) { public ApiContextManager(LuckPermsPlugin plugin, ContextManager<?, ?> handle) {
this.plugin = plugin; this.plugin = plugin;
this.handle = handle; this.handle = handle;
} }

View File

@ -0,0 +1,76 @@
/*
* 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.api.implementation;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.model.manager.user.UserManager;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.user.User;
import net.luckperms.api.player.PlayerAdapter;
import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Objects;
@SuppressWarnings({"unchecked", "rawtypes"})
public class ApiPlayerAdapter<S, P extends S> implements PlayerAdapter<P> {
private final UserManager<?> userManager;
private final ContextManager<S, P> contextManager;
public ApiPlayerAdapter(UserManager<?> userManager, ContextManager<S, P> contextManager) {
this.userManager = userManager;
this.contextManager = contextManager;
}
private P checkType(P player) {
if (!this.contextManager.getPlayerClass().isAssignableFrom(player.getClass())) {
throw new IllegalStateException("Player class " + player.getClass() + " is not assignable from " + this.contextManager.getPlayerClass());
}
return player;
}
@Override
public @NonNull User getUser(@NonNull P player) {
Objects.requireNonNull(player, "player");
me.lucko.luckperms.common.model.User user = this.userManager.getIfLoaded(this.contextManager.getUniqueId(checkType(player)));
Objects.requireNonNull(user, "user");
return user.getApiProxy();
}
@Override
public @NonNull ImmutableContextSet getContext(@NonNull P player) {
Objects.requireNonNull(player, "player");
return this.contextManager.getContext(checkType(player));
}
@Override
public @NonNull QueryOptions getQueryOptions(@NonNull P player) {
Objects.requireNonNull(player, "player");
return this.contextManager.getQueryOptions(checkType(player));
}
}

View File

@ -97,6 +97,16 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
return this.metaDataManager.get(queryOptions); return this.metaDataManager.get(queryOptions);
} }
@Override
public @NonNull PermissionCache getPermissionData() {
return getPermissionData(getQueryOptions());
}
@Override
public @NonNull MetaCache getMetaData() {
return getMetaData(getQueryOptions());
}
/** /**
* Returns a {@link CacheMetadata} instance for the given {@link QueryOptions}. * Returns a {@link CacheMetadata} instance for the given {@link QueryOptions}.
* *
@ -105,6 +115,13 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
*/ */
protected abstract CacheMetadata getMetadataForQueryOptions(QueryOptions queryOptions); protected abstract CacheMetadata getMetadataForQueryOptions(QueryOptions queryOptions);
/**
* Gets the most appropriate active query options instance for the holder.
*
* @return the query options
*/
protected abstract QueryOptions getQueryOptions();
/** /**
* Gets the {@link CalculatorFactory} used to build {@link PermissionCalculator}s. * Gets the {@link CalculatorFactory} used to build {@link PermissionCalculator}s.
* *

View File

@ -44,4 +44,9 @@ public class GroupCachedDataManager extends HolderCachedDataManager<Group> imple
protected CacheMetadata getMetadataForQueryOptions(QueryOptions queryOptions) { protected CacheMetadata getMetadataForQueryOptions(QueryOptions queryOptions) {
return new CacheMetadata(HolderType.GROUP, this.holder.getPlainDisplayName(), queryOptions); return new CacheMetadata(HolderType.GROUP, this.holder.getPlainDisplayName(), queryOptions);
} }
@Override
protected QueryOptions getQueryOptions() {
return getPlugin().getContextManager().getStaticQueryOptions();
}
} }

View File

@ -44,4 +44,14 @@ public class UserCachedDataManager extends HolderCachedDataManager<User> impleme
protected CacheMetadata getMetadataForQueryOptions(QueryOptions queryOptions) { protected CacheMetadata getMetadataForQueryOptions(QueryOptions queryOptions) {
return new CacheMetadata(HolderType.USER, this.holder.getPlainDisplayName(), queryOptions); return new CacheMetadata(HolderType.USER, this.holder.getPlainDisplayName(), queryOptions);
} }
@Override
protected QueryOptions getQueryOptions() {
QueryOptions queryOptions = getPlugin().getQueryOptionsForUser(this.holder).orElse(null);
if (queryOptions != null) {
return queryOptions;
}
return getPlugin().getContextManager().getStaticQueryOptions();
}
} }

View File

@ -39,41 +39,50 @@ import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Base implementation of {@link ContextManager} which caches content lookups. * Base implementation of {@link ContextManager} which caches content lookups.
* *
* @param <T> the calculator type * @param <S> the calculator type
*/ */
public abstract class ContextManager<T> { public abstract class ContextManager<S, P extends S> {
protected final LuckPermsPlugin plugin; protected final LuckPermsPlugin plugin;
private final Class<T> subjectClass; private final Class<S> subjectClass;
private final Class<P> playerClass;
private final List<ContextCalculator<? super T>> calculators = new CopyOnWriteArrayList<>(); private final List<ContextCalculator<? super S>> calculators = new CopyOnWriteArrayList<>();
private final List<StaticContextCalculator> staticCalculators = new CopyOnWriteArrayList<>(); private final List<StaticContextCalculator> staticCalculators = new CopyOnWriteArrayList<>();
// caches static context lookups // caches static context lookups
private final StaticLookupCache staticLookupCache = new StaticLookupCache(); private final StaticLookupCache staticLookupCache = new StaticLookupCache();
protected ContextManager(LuckPermsPlugin plugin, Class<T> subjectClass) { protected ContextManager(LuckPermsPlugin plugin, Class<S> subjectClass, Class<P> playerClass) {
this.plugin = plugin; this.plugin = plugin;
this.subjectClass = subjectClass; this.subjectClass = subjectClass;
this.playerClass = playerClass;
} }
public Class<T> getSubjectClass() { public Class<S> getSubjectClass() {
return this.subjectClass; return this.subjectClass;
} }
public abstract QueryOptionsSupplier getCacheFor(T subject); public Class<P> getPlayerClass() {
return this.playerClass;
}
public QueryOptions getQueryOptions(T subject) { public abstract UUID getUniqueId(P player);
public abstract QueryOptionsSupplier getCacheFor(S subject);
public QueryOptions getQueryOptions(S subject) {
return getCacheFor(subject).getQueryOptions(); return getCacheFor(subject).getQueryOptions();
} }
public ImmutableContextSet getContext(T subject) { public ImmutableContextSet getContext(S subject) {
return getCacheFor(subject).getContextSet(); return getCacheFor(subject).getContextSet();
} }
@ -89,11 +98,11 @@ public abstract class ContextManager<T> {
return this.plugin.getConfiguration().get(ConfigKeys.GLOBAL_QUERY_OPTIONS).toBuilder().context(contextSet).build(); return this.plugin.getConfiguration().get(ConfigKeys.GLOBAL_QUERY_OPTIONS).toBuilder().context(contextSet).build();
} }
public abstract QueryOptions formQueryOptions(T subject, ImmutableContextSet contextSet); public abstract QueryOptions formQueryOptions(S subject, ImmutableContextSet contextSet);
public abstract void invalidateCache(T subject); public abstract void invalidateCache(S subject);
public void registerCalculator(ContextCalculator<? super T> calculator) { public void registerCalculator(ContextCalculator<? super S> calculator) {
// calculators registered first should have priority (and be checked last.) // calculators registered first should have priority (and be checked last.)
this.calculators.add(0, calculator); this.calculators.add(0, calculator);
@ -103,16 +112,16 @@ public abstract class ContextManager<T> {
} }
} }
public void unregisterCalculator(ContextCalculator<? super T> calculator) { public void unregisterCalculator(ContextCalculator<? super S> calculator) {
this.calculators.remove(calculator); this.calculators.remove(calculator);
if (calculator instanceof StaticContextCalculator) { if (calculator instanceof StaticContextCalculator) {
this.staticCalculators.remove(calculator); this.staticCalculators.remove(calculator);
} }
} }
protected QueryOptions calculate(T subject) { protected QueryOptions calculate(S subject) {
ImmutableContextSet.Builder accumulator = new ImmutableContextSetImpl.BuilderImpl(); ImmutableContextSet.Builder accumulator = new ImmutableContextSetImpl.BuilderImpl();
for (ContextCalculator<? super T> calculator : this.calculators) { for (ContextCalculator<? super S> calculator : this.calculators) {
try { try {
calculator.calculate(subject, accumulator::add); calculator.calculate(subject, accumulator::add);
} catch (Throwable e) { } catch (Throwable e) {
@ -138,7 +147,7 @@ public abstract class ContextManager<T> {
public ImmutableContextSet getPotentialContexts() { public ImmutableContextSet getPotentialContexts() {
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl(); ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
for (ContextCalculator<? super T> calculator : this.calculators) { for (ContextCalculator<? super S> calculator : this.calculators) {
ContextSet potentialContexts; ContextSet potentialContexts;
try { try {
potentialContexts = calculator.estimatePotentialContexts(); potentialContexts = calculator.estimatePotentialContexts();

View File

@ -41,9 +41,9 @@ import java.util.concurrent.TimeUnit;
*/ */
public final class QueryOptionsCache<T> extends ExpiringCache<QueryOptions> implements QueryOptionsSupplier { public final class QueryOptionsCache<T> extends ExpiringCache<QueryOptions> implements QueryOptionsSupplier {
private final T subject; private final T subject;
private final ContextManager<T> contextManager; private final ContextManager<T, ?> contextManager;
public QueryOptionsCache(T subject, ContextManager<T> contextManager) { public QueryOptionsCache(T subject, ContextManager<T, ?> contextManager) {
super(50L, TimeUnit.MILLISECONDS); // expire roughly every tick super(50L, TimeUnit.MILLISECONDS); // expire roughly every tick
this.subject = subject; this.subject = subject;
this.contextManager = contextManager; this.contextManager = contextManager;

View File

@ -188,7 +188,7 @@ public interface LuckPermsPlugin {
* *
* @return the context manager * @return the context manager
*/ */
ContextManager<?> getContextManager(); ContextManager<?, ?> getContextManager();
/** /**
* Gets the inheritance handler * Gets the inheritance handler

View File

@ -72,7 +72,7 @@ public interface Sender {
default String getNameWithLocation() { default String getNameWithLocation() {
String name = getName(); String name = getName();
ContextManager<?> contextManager = getPlugin().getContextManager(); ContextManager<?, ?> contextManager = getPlugin().getContextManager();
if (contextManager == null) { if (contextManager == null) {
return name; return name;
} }

View File

@ -40,9 +40,10 @@ import net.luckperms.api.query.QueryOptions;
import cn.nukkit.Player; import cn.nukkit.Player;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class NukkitContextManager extends ContextManager<Player> { public class NukkitContextManager extends ContextManager<Player, Player> {
public static final OptionKey<Boolean> OP_OPTION = OptionKey.of("op", Boolean.class); public static final OptionKey<Boolean> OP_OPTION = OptionKey.of("op", Boolean.class);
@ -61,13 +62,18 @@ public class NukkitContextManager extends ContextManager<Player> {
}); });
public NukkitContextManager(LPNukkitPlugin plugin) { public NukkitContextManager(LPNukkitPlugin plugin) {
super(plugin, Player.class); super(plugin, Player.class, Player.class);
} }
public void onPlayerQuit(Player player) { public void onPlayerQuit(Player player) {
this.onlineSubjectCaches.remove(player); this.onlineSubjectCaches.remove(player);
} }
@Override
public UUID getUniqueId(Player player) {
return player.getUniqueId();
}
@Override @Override
public QueryOptionsCache<Player> getCacheFor(Player subject) { public QueryOptionsCache<Player> getCacheFor(Player subject) {
if (subject == null) { if (subject == null) {

View File

@ -34,7 +34,7 @@ import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject;
import me.lucko.luckperms.sponge.service.model.ProxiedSubject; import me.lucko.luckperms.sponge.service.model.ProxiedSubject;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
@ -78,6 +78,11 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
return this.ref; return this.ref;
} }
@Override
public @NonNull QueryOptions getQueryOptions() {
return getContextsCache().getQueryOptions();
}
@Override @Override
public @NonNull Optional<CommandSource> getCommandSource() { public @NonNull Optional<CommandSource> getCommandSource() {
return handle().thenApply(LPSubject::getCommandSource).join(); return handle().thenApply(LPSubject::getCommandSource).join();
@ -105,7 +110,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
@Override @Override
public boolean hasPermission(@NonNull String permission) { public boolean hasPermission(@NonNull String permission) {
return handle().thenApply(handle -> handle.getPermissionValue(getActiveContextSet(), permission).asBoolean()).join(); return handle().thenApply(handle -> handle.getPermissionValue(getContextsCache().getContextSet(), permission).asBoolean()).join();
} }
@Override @Override
@ -116,7 +121,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
@Override @Override
public boolean isChildOf(@NonNull Subject parent) { public boolean isChildOf(@NonNull Subject parent) {
return handle().thenApply(handle -> handle.isChildOf( return handle().thenApply(handle -> handle.isChildOf(
getActiveContextSet(), getContextsCache().getContextSet(),
this.service.getReferenceFactory().obtain(parent) this.service.getReferenceFactory().obtain(parent)
)).join(); )).join();
} }
@ -132,7 +137,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public @NonNull List<Subject> getParents() { public @NonNull List<Subject> getParents() {
return (List) handle().thenApply(handle -> handle.getParents(getActiveContextSet()).stream() return (List) handle().thenApply(handle -> handle.getParents(getContextsCache().getContextSet()).stream()
.map(s -> new SubjectProxy(this.service, s)) .map(s -> new SubjectProxy(this.service, s))
.collect(ImmutableCollectors.toList())).join(); .collect(ImmutableCollectors.toList())).join();
} }
@ -152,7 +157,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
@Override @Override
public @NonNull Optional<String> getOption(@NonNull String key) { public @NonNull Optional<String> getOption(@NonNull String key) {
return handle().thenApply(handle -> handle.getOption(getActiveContextSet(), key)).join(); return handle().thenApply(handle -> handle.getOption(getContextsCache().getContextSet(), key)).join();
} }
@Override @Override
@ -165,11 +170,6 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
return CompatibilityUtil.convertContexts(getContextsCache().getContextSet()); return CompatibilityUtil.convertContexts(getContextsCache().getContextSet());
} }
@Override
public ImmutableContextSet getActiveContextSet() {
return getContextsCache().getContextSet();
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
return o == this || o instanceof SubjectProxy && this.ref.equals(((SubjectProxy) o).ref); return o == this || o instanceof SubjectProxy && this.ref.equals(((SubjectProxy) o).ref);

View File

@ -33,7 +33,7 @@ import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject;
import me.lucko.luckperms.sponge.service.model.ProxiedSubject; import me.lucko.luckperms.sponge.service.model.ProxiedSubject;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
@ -78,6 +78,11 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
return this.ref; return this.ref;
} }
@Override
public @NonNull QueryOptions getQueryOptions() {
return queryOptionsCache().getQueryOptions();
}
@Override @Override
public @NonNull Optional<CommandSource> getCommandSource() { public @NonNull Optional<CommandSource> getCommandSource() {
return handle().thenApply(LPSubject::getCommandSource).join(); return handle().thenApply(LPSubject::getCommandSource).join();
@ -110,7 +115,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
@Override @Override
public boolean hasPermission(@NonNull String permission) { public boolean hasPermission(@NonNull String permission) {
return handle().thenApply(handle -> handle.getPermissionValue(getActiveContextSet(), permission).asBoolean()).join(); return handle().thenApply(handle -> handle.getPermissionValue(queryOptionsCache().getContextSet(), permission).asBoolean()).join();
} }
@Override @Override
@ -120,7 +125,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
@Override @Override
public boolean isChildOf(@NonNull SubjectReference parent) { public boolean isChildOf(@NonNull SubjectReference parent) {
return handle().thenApply(handle -> handle.isChildOf(getActiveContextSet(), this.service.getReferenceFactory().obtain(parent))).join(); return handle().thenApply(handle -> handle.isChildOf(queryOptionsCache().getContextSet(), this.service.getReferenceFactory().obtain(parent))).join();
} }
@Override @Override
@ -131,7 +136,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@Override @Override
public @NonNull List<SubjectReference> getParents() { public @NonNull List<SubjectReference> getParents() {
return (List) handle().thenApply(handle -> handle.getParents(getActiveContextSet())).join(); return (List) handle().thenApply(handle -> handle.getParents(queryOptionsCache().getContextSet())).join();
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@ -147,7 +152,7 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
@Override @Override
public @NonNull Optional<String> getOption(@NonNull String key) { public @NonNull Optional<String> getOption(@NonNull String key) {
return handle().thenApply(handle -> handle.getOption(getActiveContextSet(), key)).join(); return handle().thenApply(handle -> handle.getOption(queryOptionsCache().getContextSet(), key)).join();
} }
@Override @Override
@ -165,11 +170,6 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi
return CompatibilityUtil.convertContexts(queryOptionsCache().getContextSet()); return CompatibilityUtil.convertContexts(queryOptionsCache().getContextSet());
} }
@Override
public ImmutableContextSet getActiveContextSet() {
return queryOptionsCache().getContextSet();
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
return o == this || o instanceof SubjectProxy && this.ref.equals(((SubjectProxy) o).ref); return o == this || o instanceof SubjectProxy && this.ref.equals(((SubjectProxy) o).ref);

View File

@ -32,6 +32,7 @@ import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory; import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.service.context.ContextCalculator; import org.spongepowered.api.service.context.ContextCalculator;
import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.PermissionService;
@ -48,7 +49,7 @@ public interface LPPermissionService {
LuckPermsPlugin getPlugin(); LuckPermsPlugin getPlugin();
ContextManager<Subject> getContextManager(); ContextManager<Subject, Player> getContextManager();
SubjectReferenceFactory getReferenceFactory(); SubjectReferenceFactory getReferenceFactory();

View File

@ -41,7 +41,7 @@ import java.util.Optional;
*/ */
public interface LPSubject { public interface LPSubject {
Subject sponge(); ProxiedSubject sponge();
LPPermissionService getService(); LPPermissionService getService();

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.sponge.service.model; package me.lucko.luckperms.sponge.service.model;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.Subject;
@ -33,11 +33,10 @@ import org.spongepowered.api.service.permission.Subject;
/** /**
* Marks that an object is a proxied representation of a {@link Subject}. * Marks that an object is a proxied representation of a {@link Subject}.
*/ */
public interface ProxiedSubject extends ProxiedServiceObject { public interface ProxiedSubject extends Subject, ProxiedServiceObject {
@NonNull @NonNull LPSubjectReference asSubjectReference();
LPSubjectReference asSubjectReference();
ImmutableContextSet getActiveContextSet(); @NonNull QueryOptions getQueryOptions();
} }

View File

@ -30,7 +30,6 @@ import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.command.abstraction.Command; import me.lucko.luckperms.common.command.abstraction.Command;
import me.lucko.luckperms.common.command.access.CommandPermission; import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter; import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.dependencies.Dependency; import me.lucko.luckperms.common.dependencies.Dependency;
import me.lucko.luckperms.common.event.AbstractEventBus; import me.lucko.luckperms.common.event.AbstractEventBus;
import me.lucko.luckperms.common.messaging.MessagingFactory; import me.lucko.luckperms.common.messaging.MessagingFactory;
@ -64,7 +63,6 @@ import net.luckperms.api.query.QueryOptions;
import org.spongepowered.api.service.permission.PermissionDescription; import org.spongepowered.api.service.permission.PermissionDescription;
import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.PermissionService;
import org.spongepowered.api.service.permission.Subject;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -90,7 +88,7 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin {
private SpongeUserManager userManager; private SpongeUserManager userManager;
private SpongeGroupManager groupManager; private SpongeGroupManager groupManager;
private StandardTrackManager trackManager; private StandardTrackManager trackManager;
private ContextManager<Subject> contextManager; private SpongeContextManager contextManager;
private me.lucko.luckperms.sponge.service.LuckPermsService service; private me.lucko.luckperms.sponge.service.LuckPermsService service;
private UpdateEventHandler updateEventHandler; private UpdateEventHandler updateEventHandler;
@ -311,7 +309,7 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin {
} }
@Override @Override
public ContextManager<Subject> getContextManager() { public SpongeContextManager getContextManager() {
return this.contextManager; return this.contextManager;
} }

View File

@ -36,18 +36,25 @@ import me.lucko.luckperms.sponge.LPSpongePlugin;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.Subject;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class SpongeContextManager extends ContextManager<Subject> { public class SpongeContextManager extends ContextManager<Subject, Player> {
private final LoadingCache<Subject, QueryOptionsCache<Subject>> subjectCaches = CaffeineFactory.newBuilder() private final LoadingCache<Subject, QueryOptionsCache<Subject>> subjectCaches = CaffeineFactory.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES) .expireAfterAccess(1, TimeUnit.MINUTES)
.build(key -> new QueryOptionsCache<>(key, this)); .build(key -> new QueryOptionsCache<>(key, this));
public SpongeContextManager(LPSpongePlugin plugin) { public SpongeContextManager(LPSpongePlugin plugin) {
super(plugin, Subject.class); super(plugin, Subject.class, Player.class);
}
@Override
public UUID getUniqueId(Player player) {
return player.getUniqueId();
} }
@Override @Override

View File

@ -46,6 +46,7 @@ import me.lucko.luckperms.sponge.service.model.persisted.PersistedCollection;
import me.lucko.luckperms.sponge.service.model.persisted.SubjectStorage; import me.lucko.luckperms.sponge.service.model.persisted.SubjectStorage;
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory; import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.plugin.PluginContainer;
import org.spongepowered.api.service.context.ContextCalculator; import org.spongepowered.api.service.context.ContextCalculator;
import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.PermissionService;
@ -143,7 +144,7 @@ public class LuckPermsService implements LPPermissionService {
} }
@Override @Override
public ContextManager<Subject> getContextManager() { public ContextManager<Subject, Player> getContextManager() {
return this.plugin.getContextManager(); return this.plugin.getContextManager();
} }

View File

@ -30,6 +30,7 @@ import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
import me.lucko.luckperms.sponge.service.model.LPSubjectData; import me.lucko.luckperms.sponge.service.model.LPSubjectData;
import me.lucko.luckperms.sponge.service.model.ProxiedSubject;
import net.luckperms.api.model.data.DataType; import net.luckperms.api.model.data.DataType;
@ -67,7 +68,7 @@ public final class ProxyFactory {
new me.lucko.luckperms.sponge.service.proxy.api6.SubjectCollectionProxy(luckPerms.getService(), luckPerms); new me.lucko.luckperms.sponge.service.proxy.api6.SubjectCollectionProxy(luckPerms.getService(), luckPerms);
} }
public static Subject toSponge(LPSubject luckPerms) { public static ProxiedSubject toSponge(LPSubject luckPerms) {
return IS_API_7 ? return IS_API_7 ?
new me.lucko.luckperms.sponge.service.proxy.api7.SubjectProxy(luckPerms.getService(), luckPerms.toReference()) : new me.lucko.luckperms.sponge.service.proxy.api7.SubjectProxy(luckPerms.getService(), luckPerms.toReference()) :
new me.lucko.luckperms.sponge.service.proxy.api6.SubjectProxy(luckPerms.getService(), luckPerms.toReference()); new me.lucko.luckperms.sponge.service.proxy.api6.SubjectProxy(luckPerms.getService(), luckPerms.toReference());

View File

@ -67,6 +67,11 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage
return new CacheMetadata(null, this.subject.getParentCollection().getIdentifier() + "/" + this.subject.getIdentifier(), queryOptions); return new CacheMetadata(null, this.subject.getParentCollection().getIdentifier() + "/" + this.subject.getIdentifier(), queryOptions);
} }
@Override
protected QueryOptions getQueryOptions() {
return this.subject.sponge().getQueryOptions();
}
@Override @Override
protected CalculatorFactory getCalculatorFactory() { protected CalculatorFactory getCalculatorFactory() {
return this; return this;

View File

@ -43,6 +43,7 @@ import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.ProxyFactory; import me.lucko.luckperms.sponge.service.ProxyFactory;
import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectReference; import me.lucko.luckperms.sponge.service.model.LPSubjectReference;
import me.lucko.luckperms.sponge.service.model.ProxiedSubject;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.model.data.DataType; import net.luckperms.api.model.data.DataType;
@ -50,7 +51,6 @@ import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate; import net.luckperms.api.util.Tristate;
import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.PermissionService;
import org.spongepowered.api.service.permission.Subject;
import java.util.Optional; import java.util.Optional;
@ -64,7 +64,7 @@ public abstract class PermissionHolderSubject<T extends PermissionHolder> implem
private final PermissionHolderSubjectData subjectData; private final PermissionHolderSubjectData subjectData;
private final PermissionHolderSubjectData transientSubjectData; private final PermissionHolderSubjectData transientSubjectData;
private Subject spongeSubject = null; private ProxiedSubject spongeSubject = null;
PermissionHolderSubject(LPSpongePlugin plugin, T parent) { PermissionHolderSubject(LPSpongePlugin plugin, T parent) {
this.parent = parent; this.parent = parent;
@ -83,7 +83,7 @@ public abstract class PermissionHolderSubject<T extends PermissionHolder> implem
} }
@Override @Override
public synchronized Subject sponge() { public synchronized ProxiedSubject sponge() {
if (this.spongeSubject == null) { if (this.spongeSubject == null) {
this.spongeSubject = ProxyFactory.toSponge(this); this.spongeSubject = ProxyFactory.toSponge(this);
} }

View File

@ -31,6 +31,7 @@ import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.ProxyFactory; import me.lucko.luckperms.sponge.service.ProxyFactory;
import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubject;
import me.lucko.luckperms.sponge.service.model.LPSubjectData; import me.lucko.luckperms.sponge.service.model.LPSubjectData;
import me.lucko.luckperms.sponge.service.model.ProxiedSubject;
import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubject; import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubject;
import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubjectData; import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubjectData;
import me.lucko.luckperms.sponge.service.model.calculated.MonitoredSubjectData; import me.lucko.luckperms.sponge.service.model.calculated.MonitoredSubjectData;
@ -38,7 +39,6 @@ import me.lucko.luckperms.sponge.service.model.calculated.MonitoredSubjectData;
import net.luckperms.api.model.data.DataType; import net.luckperms.api.model.data.DataType;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.service.permission.Subject;
import java.io.IOException; import java.io.IOException;
import java.util.Optional; import java.util.Optional;
@ -64,7 +64,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject {
private final PersistedSubjectData subjectData; private final PersistedSubjectData subjectData;
private final CalculatedSubjectData transientSubjectData; private final CalculatedSubjectData transientSubjectData;
private Subject spongeSubject = null; private ProxiedSubject spongeSubject = null;
/** /**
* The save buffer instance for saving changes to disk * The save buffer instance for saving changes to disk
@ -147,7 +147,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject {
} }
@Override @Override
public Subject sponge() { public ProxiedSubject sponge() {
if (this.spongeSubject == null) { if (this.spongeSubject == null) {
this.spongeSubject = ProxyFactory.toSponge(this); this.spongeSubject = ProxyFactory.toSponge(this);
} }

View File

@ -25,13 +25,10 @@
package me.lucko.luckperms.velocity; package me.lucko.luckperms.velocity;
import com.velocitypowered.api.proxy.Player;
import me.lucko.luckperms.common.api.LuckPermsApiProvider; import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.calculator.CalculatorFactory; import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.command.CommandManager; import me.lucko.luckperms.common.command.CommandManager;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter; import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.dependencies.Dependency; import me.lucko.luckperms.common.dependencies.Dependency;
import me.lucko.luckperms.common.event.AbstractEventBus; import me.lucko.luckperms.common.event.AbstractEventBus;
import me.lucko.luckperms.common.messaging.MessagingFactory; import me.lucko.luckperms.common.messaging.MessagingFactory;
@ -76,7 +73,7 @@ public class LPVelocityPlugin extends AbstractLuckPermsPlugin {
private StandardUserManager userManager; private StandardUserManager userManager;
private StandardGroupManager groupManager; private StandardGroupManager groupManager;
private StandardTrackManager trackManager; private StandardTrackManager trackManager;
private ContextManager<Player> contextManager; private VelocityContextManager contextManager;
public LPVelocityPlugin(LPVelocityBootstrap bootstrap) { public LPVelocityPlugin(LPVelocityBootstrap bootstrap) {
this.bootstrap = bootstrap; this.bootstrap = bootstrap;
@ -238,7 +235,7 @@ public class LPVelocityPlugin extends AbstractLuckPermsPlugin {
} }
@Override @Override
public ContextManager<Player> getContextManager() { public VelocityContextManager getContextManager() {
return this.contextManager; return this.contextManager;
} }

View File

@ -37,16 +37,22 @@ import me.lucko.luckperms.velocity.LPVelocityPlugin;
import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.QueryOptions; import net.luckperms.api.query.QueryOptions;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class VelocityContextManager extends ContextManager<Player> { public class VelocityContextManager extends ContextManager<Player, Player> {
private final LoadingCache<Player, QueryOptionsCache<Player>> subjectCaches = CaffeineFactory.newBuilder() private final LoadingCache<Player, QueryOptionsCache<Player>> subjectCaches = CaffeineFactory.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES) .expireAfterAccess(1, TimeUnit.MINUTES)
.build(key -> new QueryOptionsCache<>(key, this)); .build(key -> new QueryOptionsCache<>(key, this));
public VelocityContextManager(LPVelocityPlugin plugin) { public VelocityContextManager(LPVelocityPlugin plugin) {
super(plugin, Player.class); super(plugin, Player.class, Player.class);
}
@Override
public UUID getUniqueId(Player player) {
return player.getUniqueId();
} }
@Override @Override