From fbc0787a1eaf3178e4a8ae7d3c672fa1ef1dd15a Mon Sep 17 00:00:00 2001 From: Luck Date: Sun, 17 Jul 2022 11:54:14 +0100 Subject: [PATCH] Implement Fabric meta/options API --- fabric/build.gradle | 2 +- .../luckperms/fabric/LPFabricPlugin.java | 4 +- ...java => FabricPermissionsApiListener.java} | 42 ++++++++++++++++--- .../fabric/mixin/ServerPlayerEntityMixin.java | 31 ++++++++++++++ .../luckperms/fabric/model/MixinUser.java | 4 ++ 5 files changed, 74 insertions(+), 9 deletions(-) rename fabric/src/main/java/me/lucko/luckperms/fabric/listeners/{PermissionCheckListener.java => FabricPermissionsApiListener.java} (66%) diff --git a/fabric/build.gradle b/fabric/build.gradle index d557231d4..889fbd606 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -29,7 +29,7 @@ dependencies { modImplementation(fabricApi.module(it, '0.55.2+1.19')) } - include(modImplementation('me.lucko:fabric-permissions-api:0.1-SNAPSHOT')) + include(modImplementation('me.lucko:fabric-permissions-api:0.2-SNAPSHOT')) implementation project(':common') } diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricPlugin.java b/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricPlugin.java index e70a1b9b5..b2d01b231 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricPlugin.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/LPFabricPlugin.java @@ -46,7 +46,7 @@ import me.lucko.luckperms.fabric.listeners.FabricAutoOpListener; import me.lucko.luckperms.fabric.listeners.FabricCommandListUpdater; import me.lucko.luckperms.fabric.listeners.FabricConnectionListener; import me.lucko.luckperms.fabric.listeners.FabricOtherListeners; -import me.lucko.luckperms.fabric.listeners.PermissionCheckListener; +import me.lucko.luckperms.fabric.listeners.FabricPermissionsApiListener; import me.lucko.luckperms.fabric.messaging.FabricMessagingFactory; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; @@ -88,7 +88,7 @@ public class LPFabricPlugin extends AbstractLuckPermsPlugin { this.connectionListener = new FabricConnectionListener(this); this.connectionListener.registerListeners(); - new PermissionCheckListener(this).registerListeners(); + new FabricPermissionsApiListener(this).registerListeners(); // Command registration also need to occur early, and will persist across game states as well. this.commandManager = new FabricCommandExecutor(this); diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/listeners/PermissionCheckListener.java b/fabric/src/main/java/me/lucko/luckperms/fabric/listeners/FabricPermissionsApiListener.java similarity index 66% rename from fabric/src/main/java/me/lucko/luckperms/fabric/listeners/PermissionCheckListener.java rename to fabric/src/main/java/me/lucko/luckperms/fabric/listeners/FabricPermissionsApiListener.java index cfef3c0f6..18c172397 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/listeners/PermissionCheckListener.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/listeners/FabricPermissionsApiListener.java @@ -25,7 +25,9 @@ package me.lucko.luckperms.fabric.listeners; +import me.lucko.fabric.api.permissions.v0.OptionRequestEvent; import me.lucko.fabric.api.permissions.v0.PermissionCheckEvent; +import me.lucko.luckperms.common.cacheddata.result.StringResult; import me.lucko.luckperms.common.cacheddata.result.TristateResult; import me.lucko.luckperms.common.query.QueryOptionsImpl; import me.lucko.luckperms.common.verbose.VerboseCheckTarget; @@ -41,31 +43,44 @@ import net.minecraft.server.network.ServerPlayerEntity; import org.checkerframework.checker.nullness.qual.NonNull; +import java.util.Optional; + /** * Listener to route permission checks made via fabric-permissions-api to LuckPerms. */ -public class PermissionCheckListener { +public class FabricPermissionsApiListener { private final LPFabricPlugin plugin; - public PermissionCheckListener(LPFabricPlugin plugin) { + public FabricPermissionsApiListener(LPFabricPlugin plugin) { this.plugin = plugin; } public void registerListeners() { PermissionCheckEvent.EVENT.register(this::onPermissionCheck); + OptionRequestEvent.EVENT.register(this::onOptionRequest); } private @NonNull TriState onPermissionCheck(CommandSource source, String permission) { if (source instanceof ServerCommandSource) { Entity entity = ((ServerCommandSource) source).getEntity(); if (entity instanceof ServerPlayerEntity) { - return onPlayerPermissionCheck((ServerPlayerEntity) entity, permission); + return playerPermissionCheck((ServerPlayerEntity) entity, permission); } } - return onOtherPermissionCheck(source, permission); + return otherPermissionCheck(source, permission); } - private TriState onPlayerPermissionCheck(ServerPlayerEntity player, String permission) { + private @NonNull Optional onOptionRequest(CommandSource source, String key) { + if (source instanceof ServerCommandSource) { + Entity entity = ((ServerCommandSource) source).getEntity(); + if (entity instanceof ServerPlayerEntity) { + return playerGetOption((ServerPlayerEntity) entity, key); + } + } + return otherGetOption(source, key); + } + + private TriState playerPermissionCheck(ServerPlayerEntity player, String permission) { switch (((MixinUser) player).hasPermission(permission)) { case TRUE: return TriState.TRUE; @@ -78,7 +93,7 @@ public class PermissionCheckListener { } } - private TriState onOtherPermissionCheck(CommandSource source, String permission) { + private TriState otherPermissionCheck(CommandSource source, String permission) { if (source instanceof ServerCommandSource) { String name = ((ServerCommandSource) source).getName(); VerboseCheckTarget target = VerboseCheckTarget.internal(name); @@ -90,4 +105,19 @@ public class PermissionCheckListener { return TriState.DEFAULT; } + private Optional playerGetOption(ServerPlayerEntity player, String key) { + return Optional.ofNullable(((MixinUser) player).getOption(key)); + } + + private Optional otherGetOption(CommandSource source, String key) { + if (source instanceof ServerCommandSource) { + String name = ((ServerCommandSource) source).getName(); + VerboseCheckTarget target = VerboseCheckTarget.internal(name); + + this.plugin.getVerboseHandler().offerMetaCheckEvent(CheckOrigin.PLATFORM_API, target, QueryOptionsImpl.DEFAULT_CONTEXTUAL, key, StringResult.nullResult()); + } + + return Optional.empty(); + } + } diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/mixin/ServerPlayerEntityMixin.java b/fabric/src/main/java/me/lucko/luckperms/fabric/mixin/ServerPlayerEntityMixin.java index 2ee381204..fe3990dec 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/mixin/ServerPlayerEntityMixin.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/mixin/ServerPlayerEntityMixin.java @@ -25,6 +25,7 @@ package me.lucko.luckperms.fabric.mixin; +import me.lucko.luckperms.common.cacheddata.type.MetaCache; import me.lucko.luckperms.common.cacheddata.type.PermissionCache; import me.lucko.luckperms.common.context.manager.QueryOptionsCache; import me.lucko.luckperms.common.locale.TranslationManager; @@ -136,6 +137,36 @@ public abstract class ServerPlayerEntityMixin implements MixinUser { return data.checkPermission(permission, CheckOrigin.PLATFORM_API_HAS_PERMISSION).result(); } + @Override + public String getOption(String key) { + if (key == null) { + throw new NullPointerException("key"); + } + if (this.luckperms$user == null || this.luckperms$queryOptions == null) { + // "fake" players will have our mixin, but won't have been initialised. + return null; + } + return getOption(key, this.luckperms$queryOptions.getQueryOptions()); + } + + @Override + public String getOption(String key, QueryOptions queryOptions) { + if (key == null) { + throw new NullPointerException("key"); + } + if (queryOptions == null) { + throw new NullPointerException("queryOptions"); + } + + final User user = this.luckperms$user; + if (user == null || this.luckperms$queryOptions == null) { + // "fake" players will have our mixin, but won't have been initialised. + return null; + } + + MetaCache cache = user.getCachedData().getMetaData(queryOptions); + return cache.getMetaOrChatMetaValue(key, CheckOrigin.PLATFORM_API); + } @Inject(at = @At("TAIL"), method = "copyFrom") private void luckperms_copyFrom(ServerPlayerEntity oldPlayer, boolean alive, CallbackInfo ci) { diff --git a/fabric/src/main/java/me/lucko/luckperms/fabric/model/MixinUser.java b/fabric/src/main/java/me/lucko/luckperms/fabric/model/MixinUser.java index 2a6911615..370f212d6 100644 --- a/fabric/src/main/java/me/lucko/luckperms/fabric/model/MixinUser.java +++ b/fabric/src/main/java/me/lucko/luckperms/fabric/model/MixinUser.java @@ -68,4 +68,8 @@ public interface MixinUser { Tristate hasPermission(String permission, QueryOptions queryOptions); + String getOption(String key); + + String getOption(String key, QueryOptions queryOptions); + }