Remove NeoForge capability attachment

This commit is contained in:
Luck 2024-12-04 20:39:55 +00:00
parent 29c93fac4f
commit b18717edef
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
19 changed files with 125 additions and 572 deletions

View File

@ -25,25 +25,13 @@
package me.lucko.luckperms.bungee.context;
import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.bungee.LPBungeePlugin;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.InlineQueryOptionsSupplier;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.util.CaffeineFactory;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.QueryOptions;
import me.lucko.luckperms.common.context.manager.InlineContextManager;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class BungeeContextManager extends ContextManager<ProxiedPlayer, ProxiedPlayer> {
private final LoadingCache<ProxiedPlayer, QueryOptions> contextsCache = CaffeineFactory.newBuilder()
.expireAfterWrite(50, TimeUnit.MILLISECONDS)
.build(this::calculate);
public class BungeeContextManager extends InlineContextManager<ProxiedPlayer, ProxiedPlayer> {
public BungeeContextManager(LPBungeePlugin plugin) {
super(plugin, ProxiedPlayer.class, ProxiedPlayer.class);
}
@ -52,35 +40,4 @@ public class BungeeContextManager extends ContextManager<ProxiedPlayer, ProxiedP
public UUID getUniqueId(ProxiedPlayer player) {
return player.getUniqueId();
}
@Override
public QueryOptionsSupplier getCacheFor(ProxiedPlayer subject) {
if (subject == null) {
throw new NullPointerException("subject");
}
return new InlineQueryOptionsSupplier<>(subject, this.contextsCache);
}
// override getContext, getQueryOptions and invalidateCache to skip the QueryOptionsSupplier
@Override
public ImmutableContextSet getContext(ProxiedPlayer subject) {
return getQueryOptions(subject).context();
}
@Override
public QueryOptions getQueryOptions(ProxiedPlayer subject) {
return this.contextsCache.get(subject);
}
@Override
protected void invalidateCache(ProxiedPlayer subject) {
this.contextsCache.invalidate(subject);
}
@Override
public QueryOptions formQueryOptions(ProxiedPlayer subject, ImmutableContextSet contextSet) {
return formQueryOptions(contextSet);
}
}

View File

@ -48,7 +48,8 @@ import java.util.function.Predicate;
/**
* Base implementation of {@link ContextManager} which caches content lookups.
*
* @param <S> the calculator type
* @param <S> the subject type
* @param <P> the player type
*/
public abstract class ContextManager<S, P extends S> {

View File

@ -0,0 +1,90 @@
/*
* 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.context.manager;
import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.util.CaffeineFactory;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.QueryOptions;
import java.util.concurrent.TimeUnit;
public abstract class InlineContextManager<S, P extends S> extends ContextManager<S, P> {
private final LoadingCache<S, QueryOptions> contextsCache = CaffeineFactory.newBuilder()
.expireAfterWrite(50, TimeUnit.MILLISECONDS)
.build(this::calculate);
protected InlineContextManager(LuckPermsPlugin plugin, Class<S> subjectClass, Class<P> playerClass) {
super(plugin, subjectClass, playerClass);
}
@Override
public final QueryOptionsSupplier getCacheFor(S subject) {
if (subject == null) {
throw new NullPointerException("subject");
}
return new InlineQueryOptionsSupplier<>(subject, this.contextsCache);
}
// override getContext, getQueryOptions and invalidateCache to skip the QueryOptionsSupplier
@Override
public final ImmutableContextSet getContext(S subject) {
return getQueryOptions(subject).context();
}
@Override
public final QueryOptions getQueryOptions(S subject) {
return this.contextsCache.get(subject);
}
@Override
protected final void invalidateCache(S subject) {
this.contextsCache.invalidate(subject);
}
@Override
public QueryOptions formQueryOptions(S subject, ImmutableContextSet contextSet) {
return formQueryOptions(contextSet);
}
private static final class InlineQueryOptionsSupplier<T> implements QueryOptionsSupplier {
private final T key;
private final LoadingCache<T, QueryOptions> cache;
InlineQueryOptionsSupplier(T key, LoadingCache<T, QueryOptions> cache) {
this.key = key;
this.cache = cache;
}
@Override
public QueryOptions getQueryOptions() {
return this.cache.get(this.key);
}
}
}

View File

@ -1,44 +0,0 @@
/*
* 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.context.manager;
import com.github.benmanes.caffeine.cache.LoadingCache;
import net.luckperms.api.query.QueryOptions;
public final class InlineQueryOptionsSupplier<T> implements QueryOptionsSupplier {
private final T key;
private final LoadingCache<T, QueryOptions> cache;
public InlineQueryOptionsSupplier(T key, LoadingCache<T, QueryOptions> cache) {
this.key = key;
this.cache = cache;
}
@Override
public QueryOptions getQueryOptions() {
return this.cache.get(this.key);
}
}

View File

@ -26,7 +26,6 @@ neoForge {
dependencies {
add('shade', project(':common'))
compileOnly project(':common:loader-utils')
compileOnly project(':neoforge:neoforge-api')
}
shadowJar {

View File

@ -47,12 +47,10 @@ configurations.implementation {
dependencies {
add('shade', project(':api'))
add('shade', project(':common:loader-utils'))
add('shade', project(':neoforge:neoforge-api'))
}
build {
dependsOn(":neoforge:build")
dependsOn(":neoforge:neoforge-api:build")
}
jar {

View File

@ -1,16 +0,0 @@
plugins {
alias(libs.plugins.moddevgradle)
}
sourceCompatibility = 17
targetCompatibility = 21
neoForge {
version = project.neoForgeVersion
validateAccessTransformers = true
}
dependencies {
implementation project(':api')
}

View File

@ -1,83 +0,0 @@
/*
* 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.neoforge.capabilities;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.capabilities.EntityCapability;
/**
* A NeoForge {@link EntityCapability} that attaches LuckPerms functionality onto {@link ServerPlayer}s.
*/
public interface UserCapability {
/**
* The identifier used for the capability
*/
ResourceLocation IDENTIFIER = ResourceLocation.fromNamespaceAndPath("luckperms", "user");
/**
* The capability instance.
*/
EntityCapability<UserCapability, Void> CAPABILITY = EntityCapability.createVoid(IDENTIFIER, UserCapability.class);
/**
* Checks for a permission.
*
* @param permission the permission
* @return the result
*/
default boolean hasPermission(String permission) {
return checkPermission(permission).asBoolean();
}
/**
* Runs a permission check.
*
* @param permission the permission
* @return the result
*/
Tristate checkPermission(String permission);
/**
* Runs a permission check.
*
* @param permission the permission
* @param queryOptions the query options
* @return the result
*/
Tristate checkPermission(String permission, QueryOptions queryOptions);
/**
* Gets the user's currently query options.
*
* @return the current query options for the user
*/
QueryOptions getQueryOptions();
}

View File

@ -41,7 +41,6 @@ import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin;
import me.lucko.luckperms.common.sender.DummyConsoleSender;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.neoforge.calculator.NeoForgeCalculatorFactory;
import me.lucko.luckperms.neoforge.capabilities.UserCapabilityListener;
import me.lucko.luckperms.neoforge.context.NeoForgeContextManager;
import me.lucko.luckperms.neoforge.context.NeoForgePlayerCalculator;
import me.lucko.luckperms.neoforge.listeners.NeoForgeAutoOpListener;
@ -93,9 +92,6 @@ public class LPNeoForgePlugin extends AbstractLuckPermsPlugin {
NeoForgePlatformListener platformListener = new NeoForgePlatformListener(this);
this.bootstrap.registerListeners(platformListener);
UserCapabilityListener userCapabilityListener = new UserCapabilityListener();
this.bootstrap.registerListeners(userCapabilityListener);
NeoForgePermissionHandlerListener permissionHandlerListener = new NeoForgePermissionHandlerListener(this);
this.bootstrap.registerListeners(permissionHandlerListener);

View File

@ -28,15 +28,15 @@ package me.lucko.luckperms.neoforge;
import com.mojang.brigadier.ParseResults;
import me.lucko.luckperms.common.cacheddata.result.TristateResult;
import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.query.QueryOptionsImpl;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.sender.SenderFactory;
import me.lucko.luckperms.common.verbose.VerboseCheckTarget;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.neoforge.capabilities.UserCapability;
import me.lucko.luckperms.neoforge.capabilities.UserCapabilityImpl;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
@ -72,24 +72,22 @@ public class NeoForgeSenderFactory extends SenderFactory<LPNeoForgePlugin, Comma
@Override
protected void sendMessage(CommandSourceStack sender, Component message) {
Locale locale;
if (sender.getEntity() instanceof ServerPlayer) {
ServerPlayer player = (ServerPlayer) sender.getEntity();
UserCapabilityImpl user = UserCapabilityImpl.get(player);
locale = user.getLocale(player);
} else {
locale = null;
}
Locale locale = sender.getEntity() instanceof ServerPlayer player
? TranslationManager.parseLocale(player.getLanguage())
: null;
sender.sendSuccess(() -> toNativeText(TranslationManager.render(message, locale)), false);
}
@Override
protected Tristate getPermissionValue(CommandSourceStack commandSource, String node) {
if (commandSource.getEntity() instanceof ServerPlayer) {
ServerPlayer player = (ServerPlayer) commandSource.getEntity();
UserCapability user = UserCapabilityImpl.get(player);
return user.checkPermission(node);
if (commandSource.getEntity() instanceof ServerPlayer player) {
User user = getPlugin().getUserManager().getIfLoaded(player.getUUID());
if (user == null) {
return Tristate.UNDEFINED;
}
QueryOptions queryOptions = getPlugin().getContextManager().getQueryOptions(player);
return user.getCachedData().getPermissionData(queryOptions).checkPermission(node, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result();
}
VerboseCheckTarget target = VerboseCheckTarget.internal(commandSource.getTextName());

View File

@ -1,163 +0,0 @@
/*
* 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.neoforge.capabilities;
import me.lucko.luckperms.common.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.neoforge.context.NeoForgeContextManager;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
import java.util.Optional;
public class UserCapabilityImpl implements UserCapability {
private static Optional<UserCapability> getCapability(Player player) {
return Optional.ofNullable(player.getCapability(CAPABILITY));
}
/**
* Gets a {@link UserCapability} for a given {@link ServerPlayer}.
*
* @param player the player
* @return the capability
*/
public static @NotNull UserCapabilityImpl get(@NotNull Player player) {
return (UserCapabilityImpl) getCapability(player).orElseThrow(() -> new IllegalStateException("Capability missing for " + player.getUUID()));
}
/**
* Gets a {@link UserCapability} for a given {@link ServerPlayer}.
*
* @param player the player
* @return the capability, or null
*/
public static @Nullable UserCapabilityImpl getNullable(@NotNull Player player) {
return (UserCapabilityImpl) getCapability(player).orElse(null);
}
private boolean initialised = false;
private boolean invalidated = false;
private User user;
private QueryOptionsCache<ServerPlayer> queryOptionsCache;
private String language;
private Locale locale;
public UserCapabilityImpl() {
}
public void initialise(UserCapabilityImpl previous) {
this.user = previous.user;
this.queryOptionsCache = previous.queryOptionsCache;
this.language = previous.language;
this.locale = previous.locale;
this.initialised = true;
}
public void initialise(User user, ServerPlayer player, NeoForgeContextManager contextManager) {
this.user = user;
this.queryOptionsCache = new QueryOptionsCache<>(player, contextManager);
this.initialised = true;
}
private void assertInitialised() {
if (!this.initialised) {
throw new IllegalStateException("Capability has not been initialised");
}
if (this.invalidated) {
throw new IllegalStateException("Capability has been invalidated");
}
}
public void invalidate() {
this.invalidated = false;
this.user = null;
this.queryOptionsCache = null;
this.language = null;
this.locale = null;
}
@Override
public Tristate checkPermission(String permission) {
assertInitialised();
if (permission == null) {
throw new NullPointerException("permission");
}
return checkPermission(permission, this.queryOptionsCache.getQueryOptions());
}
@Override
public Tristate checkPermission(String permission, QueryOptions queryOptions) {
assertInitialised();
if (permission == null) {
throw new NullPointerException("permission");
}
if (queryOptions == null) {
throw new NullPointerException("queryOptions");
}
PermissionCache cache = this.user.getCachedData().getPermissionData(queryOptions);
return cache.checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result();
}
public User getUser() {
assertInitialised();
return this.user;
}
@Override
public QueryOptions getQueryOptions() {
return getQueryOptionsCache().getQueryOptions();
}
public QueryOptionsCache<ServerPlayer> getQueryOptionsCache() {
assertInitialised();
return this.queryOptionsCache;
}
public Locale getLocale(ServerPlayer player) {
if (this.language == null || !this.language.equals(player.getLanguage())) {
this.language = player.getLanguage();
this.locale = TranslationManager.parseLocale(this.language);
}
return this.locale;
}
}

View File

@ -1,69 +0,0 @@
/*
* 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.neoforge.capabilities;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
public class UserCapabilityListener {
@SubscribeEvent
public void onRegisterCapabilities(RegisterCapabilitiesEvent event) {
event.registerEntity(
UserCapability.CAPABILITY,
EntityType.PLAYER,
(player, ctx) -> {
if (!(player instanceof ServerPlayer)) {
// Don't attach to LocalPlayer
return null;
}
return new UserCapabilityImpl();
}
);
}
@SubscribeEvent
public void onPlayerClone(PlayerEvent.Clone event) {
Player previousPlayer = event.getOriginal();
Player currentPlayer = event.getEntity();
try {
UserCapabilityImpl previous = UserCapabilityImpl.get(previousPlayer);
UserCapabilityImpl current = UserCapabilityImpl.get(currentPlayer);
current.initialise(previous);
previous.invalidate();
current.getQueryOptionsCache().invalidate();
} catch (IllegalStateException e) {
// continue on if we cannot copy original data
}
}
}

View File

@ -26,10 +26,8 @@
package me.lucko.luckperms.neoforge.context;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.InlineContextManager;
import me.lucko.luckperms.neoforge.LPNeoForgePlugin;
import me.lucko.luckperms.neoforge.capabilities.UserCapabilityImpl;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.OptionKey;
import net.luckperms.api.query.QueryOptions;
@ -37,7 +35,7 @@ import net.minecraft.server.level.ServerPlayer;
import java.util.UUID;
public class NeoForgeContextManager extends ContextManager<ServerPlayer, ServerPlayer> {
public class NeoForgeContextManager extends InlineContextManager<ServerPlayer, ServerPlayer> {
public static final OptionKey<Boolean> INTEGRATED_SERVER_OWNER = OptionKey.of("integrated_server_owner", Boolean.class);
public NeoForgeContextManager(LPNeoForgePlugin plugin) {
@ -49,15 +47,6 @@ public class NeoForgeContextManager extends ContextManager<ServerPlayer, ServerP
return player.getUUID();
}
@Override
public QueryOptionsCache<ServerPlayer> getCacheFor(ServerPlayer subject) {
if (subject == null) {
throw new NullPointerException("subject");
}
return UserCapabilityImpl.get(subject).getQueryOptionsCache();
}
@Override
public QueryOptions formQueryOptions(ServerPlayer subject, ImmutableContextSet contextSet) {
QueryOptions.Builder builder = this.plugin.getConfiguration().get(ConfigKeys.GLOBAL_QUERY_OPTIONS).toBuilder();
@ -67,13 +56,4 @@ public class NeoForgeContextManager extends ContextManager<ServerPlayer, ServerP
return builder.context(contextSet).build();
}
@Override
public void invalidateCache(ServerPlayer subject) {
UserCapabilityImpl capability = UserCapabilityImpl.getNullable(subject);
if (capability != null) {
capability.getQueryOptionsCache().invalidate();
}
}
}

View File

@ -33,7 +33,6 @@ import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.util.AbstractConnectionListener;
import me.lucko.luckperms.neoforge.LPNeoForgePlugin;
import me.lucko.luckperms.neoforge.NeoForgeSenderFactory;
import me.lucko.luckperms.neoforge.capabilities.UserCapabilityImpl;
import me.lucko.luckperms.neoforge.util.AsyncConfigurationTask;
import net.kyori.adventure.text.Component;
import net.minecraft.network.Connection;
@ -146,9 +145,6 @@ public class NeoForgeConnectionListener extends AbstractConnectionListener {
}
}
// initialise capability
UserCapabilityImpl userCapability = UserCapabilityImpl.get(player);
userCapability.initialise(user, player, this.plugin.getContextManager());
this.plugin.getContextManager().signalContextUpdate(player);
}

View File

@ -32,7 +32,6 @@ import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.CheckOrigin;
import me.lucko.luckperms.neoforge.LPNeoForgeBootstrap;
import me.lucko.luckperms.neoforge.LPNeoForgePlugin;
import me.lucko.luckperms.neoforge.capabilities.UserCapabilityImpl;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.QueryMode;
import net.luckperms.api.query.QueryOptions;
@ -78,12 +77,9 @@ public class NeoForgePermissionHandler implements IPermissionHandler {
@Override
public <T> T getPermission(ServerPlayer player, PermissionNode<T> node, PermissionDynamicContext<?>... context) {
UserCapabilityImpl capability = UserCapabilityImpl.getNullable(player);
if (capability != null) {
User user = capability.getUser();
QueryOptions queryOptions = capability.getQueryOptionsCache().getQueryOptions();
User user = plugin.getUserManager().getIfLoaded(player.getUUID());
if (user != null) {
QueryOptions queryOptions = plugin.getContextManager().getQueryOptions(player);
T value = getPermissionValue(user, queryOptions, node, context);
if (value != null) {
return value;

View File

@ -32,8 +32,7 @@ import me.lucko.luckperms.common.graph.Graph;
import me.lucko.luckperms.common.graph.TraversalAlgorithm;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.neoforge.LPNeoForgePlugin;
import me.lucko.luckperms.neoforge.capabilities.UserCapability;
import me.lucko.luckperms.neoforge.capabilities.UserCapabilityImpl;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.util.Tristate;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.level.ServerPlayer;
@ -140,22 +139,16 @@ public final class BrigadierInjector {
@Override
public boolean test(CommandSourceStack source) {
if (source.getEntity() instanceof ServerPlayer) {
ServerPlayer player = (ServerPlayer) source.getEntity();
Tristate state = Tristate.UNDEFINED;
// If player is still connecting and has not been added to world then check LP user directly
if (!player.isAddedToLevel()) {
User user = this.plugin.getUserManager().getIfLoaded(player.getUUID());
if (user == null) {
// Should never happen but just in case...
return false;
}
state = user.getCachedData().getPermissionData().checkPermission(permission);
} else {
UserCapability user = UserCapabilityImpl.get(player);
state = user.checkPermission(this.permission);
if (source.getEntity() instanceof ServerPlayer player) {
User user = this.plugin.getUserManager().getIfLoaded(player.getUUID());
if (user == null) {
return false;
}
QueryOptions queryOptions = this.plugin.getContextManager().getQueryOptions(player);
Tristate state = user.getCachedData().getPermissionData(queryOptions).checkPermission(this.permission);
if (state != Tristate.UNDEFINED) {
return state.asBoolean() && this.delegate.test(source.withPermission(4));
}

View File

@ -30,7 +30,6 @@ include (
'fabric',
'neoforge',
'neoforge:loader',
'neoforge:neoforge-api',
'forge',
'forge:loader',
'forge:forge-api',

View File

@ -25,31 +25,20 @@
package me.lucko.luckperms.sponge.context;
import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.InlineQueryOptionsSupplier;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.util.CaffeineFactory;
import me.lucko.luckperms.common.context.manager.InlineContextManager;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.service.model.ContextCalculatorProxy;
import me.lucko.luckperms.sponge.service.model.TemporaryCauseHolderSubject;
import net.luckperms.api.context.ContextCalculator;
import net.luckperms.api.context.ContextConsumer;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.context.StaticContextCalculator;
import net.luckperms.api.query.QueryOptions;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.event.Cause;
import org.spongepowered.api.service.permission.Subject;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class SpongeContextManager extends ContextManager<Subject, ServerPlayer> {
private final LoadingCache<Subject, QueryOptions> contextsCache = CaffeineFactory.newBuilder()
.expireAfterWrite(50, TimeUnit.MILLISECONDS)
.build(this::calculate);
public class SpongeContextManager extends InlineContextManager<Subject, ServerPlayer> {
public SpongeContextManager(LPSpongePlugin plugin) {
super(plugin, Subject.class, ServerPlayer.class);
@ -86,34 +75,4 @@ public class SpongeContextManager extends ContextManager<Subject, ServerPlayer>
public UUID getUniqueId(ServerPlayer player) {
return player.uniqueId();
}
@Override
public QueryOptionsSupplier getCacheFor(Subject subject) {
if (subject == null) {
throw new NullPointerException("subject");
}
return new InlineQueryOptionsSupplier<>(subject, this.contextsCache);
}
// override getContext, getQueryOptions and invalidateCache to skip the QueryOptionsSupplier
@Override
public ImmutableContextSet getContext(Subject subject) {
return getQueryOptions(subject).context();
}
@Override
public QueryOptions getQueryOptions(Subject subject) {
return this.contextsCache.get(subject);
}
@Override
protected void invalidateCache(Subject subject) {
this.contextsCache.invalidate(subject);
}
@Override
public QueryOptions formQueryOptions(Subject subject, ImmutableContextSet contextSet) {
return formQueryOptions(contextSet);
}
}

View File

@ -25,25 +25,13 @@
package me.lucko.luckperms.velocity.context;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.velocitypowered.api.proxy.Player;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.util.CaffeineFactory;
import me.lucko.luckperms.common.context.manager.InlineContextManager;
import me.lucko.luckperms.velocity.LPVelocityPlugin;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.QueryOptions;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class VelocityContextManager extends ContextManager<Player, Player> {
private final LoadingCache<Player, QueryOptionsCache<Player>> subjectCaches = CaffeineFactory.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES)
.build(key -> new QueryOptionsCache<>(key, this));
public class VelocityContextManager extends InlineContextManager<Player, Player> {
public VelocityContextManager(LPVelocityPlugin plugin) {
super(plugin, Player.class, Player.class);
}
@ -52,26 +40,4 @@ public class VelocityContextManager extends ContextManager<Player, Player> {
public UUID getUniqueId(Player player) {
return player.getUniqueId();
}
@Override
public QueryOptionsSupplier getCacheFor(Player subject) {
if (subject == null) {
throw new NullPointerException("subject");
}
return this.subjectCaches.get(subject);
}
@Override
protected void invalidateCache(Player subject) {
QueryOptionsCache<Player> cache = this.subjectCaches.getIfPresent(subject);
if (cache != null) {
cache.invalidate();
}
}
@Override
public QueryOptions formQueryOptions(Player subject, ImmutableContextSet contextSet) {
return formQueryOptions(contextSet);
}
}