mirror of https://github.com/GeyserMC/Geyser.git
- removed fabric permission api, done by cloud now
- updated GeyserPermission to 2.0 - removed mod platform specific permission checkers TODO: - test neoforge permission registration event - fix: exception handling
This commit is contained in:
parent
f2a3feac05
commit
677f79dbd7
|
@ -30,9 +30,10 @@ import org.geysermc.geyser.api.util.TriState;
|
|||
|
||||
/**
|
||||
* Fired by anything that wishes to gather permission nodes and defaults.
|
||||
* <br><br>
|
||||
* <p>
|
||||
* This event is not guaranteed to be fired, as certain Geyser platforms do not have a native permission system.
|
||||
* It can be expected to fire on Geyser-Spigot and Geyser-Standalone.
|
||||
* It can be expected to fire on Geyser-Spigot, Geyser-NeoForge and Geyser-Standalone. Note: NeoForge allows registering permissions,
|
||||
* but does so without registering default values.
|
||||
* It may still be fired on other platforms due to a 3rd party.
|
||||
*/
|
||||
public interface GeyserRegisterPermissionsEvent extends Event {
|
||||
|
|
|
@ -23,9 +23,6 @@ dependencies {
|
|||
exclude(group = "io.netty.incubator")
|
||||
}
|
||||
|
||||
modImplementation(libs.fabric.permissions)
|
||||
include(libs.fabric.permissions)
|
||||
|
||||
modImplementation(libs.cloud.fabric)
|
||||
include(libs.cloud.fabric)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.platform.fabric;
|
||||
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
|
@ -33,7 +32,6 @@ import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
|||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.command.CommandRegistry;
|
||||
import org.geysermc.geyser.command.CommandSourceConverter;
|
||||
|
@ -67,7 +65,6 @@ public class GeyserFabricBootstrap extends GeyserModBootstrap implements ModInit
|
|||
|
||||
this.onGeyserInitialize();
|
||||
|
||||
// TODO: verify
|
||||
var sourceConverter = CommandSourceConverter.layered(
|
||||
CommandSourceStack.class,
|
||||
id -> getServer().getPlayerList().getPlayer(id),
|
||||
|
@ -82,8 +79,4 @@ public class GeyserFabricBootstrap extends GeyserModBootstrap implements ModInit
|
|||
this.setCommandRegistry(new CommandRegistry(GeyserImpl.getInstance(), cloud));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode) {
|
||||
return Permissions.check(source, permissionNode, source.getServer().getOperatorUserPermissionLevel());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ import net.neoforged.neoforge.common.NeoForge;
|
|||
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
|
||||
import net.neoforged.neoforge.event.server.ServerStartedEvent;
|
||||
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.command.CommandRegistry;
|
||||
import org.geysermc.geyser.command.CommandSourceConverter;
|
||||
|
@ -49,8 +48,6 @@ import org.incendo.cloud.neoforge.NeoForgeServerCommandManager;
|
|||
@Mod(ModConstants.MOD_ID)
|
||||
public class GeyserNeoForgeBootstrap extends GeyserModBootstrap {
|
||||
|
||||
private final GeyserNeoForgePermissionHandler permissionHandler = new GeyserNeoForgePermissionHandler();
|
||||
|
||||
public GeyserNeoForgeBootstrap() {
|
||||
super(new GeyserNeoForgePlatform());
|
||||
|
||||
|
@ -61,11 +58,12 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap {
|
|||
|
||||
NeoForge.EVENT_BUS.addListener(this::onServerStopping);
|
||||
NeoForge.EVENT_BUS.addListener(this::onPlayerJoin);
|
||||
NeoForge.EVENT_BUS.addListener(this.permissionHandler::onPermissionGather);
|
||||
|
||||
GeyserNeoForgePermissionHandler permissionHandler = new GeyserNeoForgePermissionHandler();
|
||||
NeoForge.EVENT_BUS.addListener(permissionHandler::onPermissionGather);
|
||||
|
||||
this.onGeyserInitialize();
|
||||
|
||||
// TODO: verify; idek how to make permissions on neoforge work with this...
|
||||
var sourceConverter = CommandSourceConverter.layered(
|
||||
CommandSourceStack.class,
|
||||
id -> getServer().getPlayerList().getPlayer(id),
|
||||
|
@ -92,10 +90,4 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap {
|
|||
private void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) {
|
||||
GeyserModUpdateListener.onPlayReady(event.getEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode) {
|
||||
return this.permissionHandler.hasPermission(source, permissionNode);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,23 +25,16 @@
|
|||
|
||||
package org.geysermc.geyser.platform.neoforge;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.neoforged.neoforge.server.permission.PermissionAPI;
|
||||
import net.neoforged.neoforge.server.permission.events.PermissionGatherEvent;
|
||||
import net.neoforged.neoforge.server.permission.nodes.PermissionDynamicContextKey;
|
||||
import net.neoforged.neoforge.server.permission.nodes.PermissionNode;
|
||||
import net.neoforged.neoforge.server.permission.nodes.PermissionType;
|
||||
import net.neoforged.neoforge.server.permission.nodes.PermissionTypes;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.geyser.Constants;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.command.Command;
|
||||
import org.geysermc.geyser.command.CommandRegistry;
|
||||
import org.geysermc.geyser.api.event.lifecycle.GeyserRegisterPermissionsEvent;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class GeyserNeoForgePermissionHandler {
|
||||
|
||||
|
@ -63,49 +56,10 @@ public class GeyserNeoForgePermissionHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private final Map<String, PermissionNode<Boolean>> permissionNodes = new HashMap<>();
|
||||
|
||||
public void onPermissionGather(PermissionGatherEvent.Nodes event) {
|
||||
this.registerNode(Constants.UPDATE_PERMISSION, event);
|
||||
|
||||
CommandRegistry commandManager = GeyserImpl.getInstance().commandRegistry();
|
||||
for (Map.Entry<String, Command> entry : commandManager.commands().entrySet()) {
|
||||
Command command = entry.getValue();
|
||||
|
||||
// Don't register aliases
|
||||
if (!command.name().equals(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.registerNode(command.permission(), event);
|
||||
}
|
||||
|
||||
for (Map<String, Command> commands : commandManager.extensionCommands().values()) {
|
||||
for (Map.Entry<String, Command> entry : commands.entrySet()) {
|
||||
Command command = entry.getValue();
|
||||
|
||||
// Don't register aliases
|
||||
if (!command.name().equals(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.registerNode(command.permission(), event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode) {
|
||||
ServerPlayer player = source.getPlayer();
|
||||
if (!source.isPlayer() || player == null) {
|
||||
return true;
|
||||
}
|
||||
PermissionNode<Boolean> node = this.permissionNodes.get(permissionNode);
|
||||
if (node == null) {
|
||||
GeyserImpl.getInstance().getLogger().warning("Unable to find permission node " + permissionNode);
|
||||
return false;
|
||||
}
|
||||
|
||||
return PermissionAPI.getPermission(player, node);
|
||||
GeyserImpl.getInstance().eventBus().fire((GeyserRegisterPermissionsEvent) (permission, defaultValue) -> this.registerNode(permission, event));
|
||||
}
|
||||
|
||||
private void registerNode(String node, PermissionGatherEvent.Nodes event) {
|
||||
|
@ -114,7 +68,6 @@ public class GeyserNeoForgePermissionHandler {
|
|||
// NeoForge likes to crash if you try and register a duplicate node
|
||||
if (!event.getNodes().contains(permissionNode)) {
|
||||
event.addNodes(permissionNode);
|
||||
this.permissionNodes.put(node, permissionNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ package org.geysermc.geyser.platform.mod;
|
|||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
@ -60,7 +59,6 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||
private static GeyserModBootstrap instance;
|
||||
|
||||
private final GeyserModPlatform platform;
|
||||
|
||||
private GeyserImpl geyser;
|
||||
private Path dataFolder;
|
||||
|
||||
|
@ -201,8 +199,6 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||
return this.platform.resolveResource(resource);
|
||||
}
|
||||
|
||||
public abstract boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode);
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
private boolean loadConfig() {
|
||||
try {
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.platform.mod;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.geysermc.geyser.Constants;
|
||||
import org.geysermc.geyser.platform.mod.command.ModCommandSource;
|
||||
|
@ -33,9 +32,9 @@ import org.geysermc.geyser.util.VersionCheckUtils;
|
|||
|
||||
public final class GeyserModUpdateListener {
|
||||
public static void onPlayReady(Player player) {
|
||||
CommandSourceStack stack = player.createCommandSourceStack();
|
||||
if (GeyserModBootstrap.getInstance().hasPermission(stack, Constants.UPDATE_PERMISSION)) {
|
||||
VersionCheckUtils.checkForGeyserUpdate(() -> new ModCommandSource(stack));
|
||||
ModCommandSource source = new ModCommandSource(player.createCommandSourceStack());
|
||||
if (source.hasPermission(Constants.UPDATE_PERMISSION)) {
|
||||
VersionCheckUtils.checkForGeyserUpdate(() -> source);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||
import org.geysermc.geyser.platform.mod.GeyserModBootstrap;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
|
||||
import java.util.Objects;
|
||||
|
@ -86,7 +85,10 @@ public class ModCommandSource implements GeyserCommandSource {
|
|||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
return GeyserModBootstrap.getInstance().hasPermission(source, permission);
|
||||
// Unlike other bootstraps; we delegate to cloud here too:
|
||||
// On NeoForge; we'd have to keep track of all PermissionNodes - cloud already does that
|
||||
// For Fabric, we won't need to include the Fabric Permissions API anymore - cloud already does that too :p
|
||||
return GeyserImpl.getInstance().commandRegistry().cloud().hasPermission(this, permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.geysermc.geyser.command.GeyserCommandSource;
|
|||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class VelocityCommandSource implements GeyserCommandSource {
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.geysermc.geyser.extension.command.GeyserExtensionCommand;
|
|||
import org.geysermc.geyser.text.ChatColor;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.exception.ArgumentParseException;
|
||||
import org.incendo.cloud.exception.CommandExecutionException;
|
||||
import org.incendo.cloud.exception.InvalidCommandSenderException;
|
||||
|
@ -256,7 +257,7 @@ public class CommandRegistry {
|
|||
}
|
||||
|
||||
try {
|
||||
handleThrowable(source, throwable);
|
||||
handleThrowable(source, result.commandContext(), throwable);
|
||||
} catch (Throwable secondary) {
|
||||
// otherwise it gets swallowed by whenComplete.
|
||||
// we assume this won't throw.
|
||||
|
@ -265,8 +266,9 @@ public class CommandRegistry {
|
|||
});
|
||||
}
|
||||
|
||||
private void handleThrowable(@NonNull GeyserCommandSource source, @NonNull Throwable throwable) {
|
||||
private void handleThrowable(@NonNull GeyserCommandSource source, @NonNull CommandContext<GeyserCommandSource> commandContext, @NonNull Throwable throwable) {
|
||||
if (throwable instanceof Exception exception) {
|
||||
cloud.exceptionController().handleException(commandContext, exception);
|
||||
for (ExceptionHandler<?> handler : exceptionHandlers) {
|
||||
if (handler.handle(source, exception)) {
|
||||
return;
|
||||
|
@ -316,8 +318,7 @@ public class CommandRegistry {
|
|||
E e = (E) exception;
|
||||
// if cloud has a registered exception handler for this type, use it, otherwise use this handler.
|
||||
// we register all the exception handlers to cloud, so it will likely just be cloud invoking this same handler.
|
||||
cloud.exceptionController().handleException(,exception);
|
||||
cloud.handleException(source, type, e, handler);
|
||||
cloud.exceptionController().handleException(source, type, e, handler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -26,7 +26,11 @@
|
|||
package org.geysermc.geyser.command;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.permission.Permission;
|
||||
import org.incendo.cloud.permission.PermissionResult;
|
||||
import org.incendo.cloud.permission.PredicatePermission;
|
||||
|
||||
@AllArgsConstructor
|
||||
|
@ -37,11 +41,6 @@ public class GeyserPermission implements PredicatePermission<GeyserCommandSource
|
|||
private final String permission;
|
||||
private final CommandManager<GeyserCommandSource> manager;
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(GeyserCommandSource source) {
|
||||
return check(source).toBoolean();
|
||||
}
|
||||
|
||||
public Result check(GeyserCommandSource source) {
|
||||
if (bedrockOnly) {
|
||||
if (source.connection() == null) {
|
||||
|
@ -60,6 +59,16 @@ public class GeyserPermission implements PredicatePermission<GeyserCommandSource
|
|||
return Result.NO_PERMISSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CloudKey<Void> key() {
|
||||
return CloudKey.cloudKey(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull PermissionResult testPermission(@NonNull GeyserCommandSource sender) {
|
||||
return check(sender).toPermission(permission);
|
||||
}
|
||||
|
||||
public enum Result {
|
||||
|
||||
/**
|
||||
|
@ -82,8 +91,8 @@ public class GeyserPermission implements PredicatePermission<GeyserCommandSource
|
|||
*/
|
||||
ALLOWED;
|
||||
|
||||
public boolean toBoolean() {
|
||||
return this == ALLOWED;
|
||||
public PermissionResult toPermission(String permission) {
|
||||
return PermissionResult.of(this == ALLOWED, Permission.of(permission));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ package org.geysermc.geyser.extension.command;
|
|||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.command.Command;
|
||||
import org.geysermc.geyser.api.command.CommandExecutor;
|
||||
import org.geysermc.geyser.api.command.CommandSource;
|
||||
|
@ -110,6 +111,12 @@ public abstract class GeyserExtensionCommand extends GeyserCommand {
|
|||
@Override
|
||||
public Builder<T> permission(@NonNull String permission) {
|
||||
this.permission = Objects.requireNonNull(permission, "command permission");
|
||||
if (!permission.contains(".")) {
|
||||
String newPermission = extension.description().id() + "." + permission;
|
||||
GeyserImpl.getInstance().getLogger().error("Extension " + extension.name() + " tried to register an invalid permission (" + permission + ")." +
|
||||
"Changing it to " + newPermission + "!");
|
||||
this.permission = newPermission;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -117,6 +124,12 @@ public abstract class GeyserExtensionCommand extends GeyserCommand {
|
|||
public Builder<T> permission(@NonNull String permission, @NonNull TriState defaultValue) {
|
||||
this.permission = Objects.requireNonNull(permission, "command permission");
|
||||
this.permissionDefault = Objects.requireNonNull(defaultValue, "command permission defaultValue");
|
||||
if (!permission.contains(".")) {
|
||||
String newPermission = extension.description().id() + "." + permission;
|
||||
GeyserImpl.getInstance().getLogger().error("Extension " + extension.name() + " tried to register an invalid permission (" + permission + ")." +
|
||||
"Changing it to " + newPermission + "!");
|
||||
this.permission = newPermission;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ viaproxy = "3.2.0-SNAPSHOT"
|
|||
fabric-minecraft = "1.20.4"
|
||||
fabric-loader = "0.15.2"
|
||||
fabric-api = "0.91.2+1.20.4"
|
||||
fabric-permissions = "0.2-SNAPSHOT"
|
||||
neoforge-minecraft = "20.4.48-beta"
|
||||
mixin = "0.8.5"
|
||||
|
||||
|
@ -100,7 +99,6 @@ mixin = { group = "org.spongepowered", name = "mixin", version.ref = "mixin" }
|
|||
fabric-minecraft = { group = "com.mojang", name = "minecraft", version.ref = "fabric-minecraft" }
|
||||
fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabric-loader" }
|
||||
fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric-api" }
|
||||
fabric-permissions = { group = "me.lucko", name = "fabric-permissions-api", version.ref = "fabric-permissions" }
|
||||
|
||||
neoforge-minecraft = { group = "net.neoforged", name = "neoforge", version.ref = "neoforge-minecraft" }
|
||||
|
||||
|
|
Loading…
Reference in New Issue