diff --git a/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserRegisterPermissionsEvent.java b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserRegisterPermissionsEvent.java index 2fcb12b6b..d5cdaccdb 100644 --- a/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserRegisterPermissionsEvent.java +++ b/api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserRegisterPermissionsEvent.java @@ -32,8 +32,7 @@ import org.geysermc.geyser.api.util.TriState; * Fired by anything that wishes to gather permission nodes and defaults. *

* 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, Geyser-NeoForge and Geyser-Standalone. Note: NeoForge allows registering permissions, - * but does so without registering default values. + * It can be expected to fire on Geyser-Spigot, Geyser-NeoForge and Geyser-Standalone. * It may still be fired on other platforms due to a 3rd party. */ public interface GeyserRegisterPermissionsEvent extends Event { diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java index d1978c4a7..591ef8673 100644 --- a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeBootstrap.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.platform.neoforge; import net.minecraft.commands.CommandSourceStack; import net.minecraft.world.entity.player.Player; import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.EventPriority; import net.neoforged.fml.common.Mod; import net.neoforged.fml.loading.FMLLoader; import net.neoforged.neoforge.common.NeoForge; @@ -35,7 +36,6 @@ import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.server.ServerStartedEvent; import net.neoforged.neoforge.event.server.ServerStoppingEvent; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.command.CommandRegistry; import org.geysermc.geyser.command.CommandSourceConverter; import org.geysermc.geyser.command.GeyserCommandSource; import org.geysermc.geyser.platform.mod.GeyserModBootstrap; @@ -60,7 +60,7 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { NeoForge.EVENT_BUS.addListener(this::onPlayerJoin); GeyserNeoForgePermissionHandler permissionHandler = new GeyserNeoForgePermissionHandler(); - NeoForge.EVENT_BUS.addListener(permissionHandler::onPermissionGather); + NeoForge.EVENT_BUS.addListener(EventPriority.HIGHEST, permissionHandler::onPermissionGather); this.onGeyserInitialize(); @@ -75,7 +75,7 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap { ExecutionCoordinator.simpleCoordinator(), sourceConverter ); - this.setCommandRegistry(new CommandRegistry(GeyserImpl.getInstance(), cloud)); + this.setCommandRegistry(new GeyserNeoForgeCommandRegistry(GeyserImpl.getInstance(), cloud)); } private void onServerStarted(ServerStartedEvent event) { diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeCommandRegistry.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeCommandRegistry.java new file mode 100644 index 000000000..e4af78abf --- /dev/null +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgeCommandRegistry.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2019-2024 GeyserMC. http://geysermc.org + * + * 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. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.platform.neoforge; + +import com.google.common.util.concurrent.UncheckedExecutionException; +import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.command.CommandRegistry; +import org.geysermc.geyser.command.GeyserCommandSource; +import org.incendo.cloud.CommandManager; + +public class GeyserNeoForgeCommandRegistry extends CommandRegistry { + public GeyserNeoForgeCommandRegistry(GeyserImpl geyser, CommandManager cloud) { + super(geyser, cloud); + } + + // todo yeet once cloud enforced method contract here: + // https://github.com/Incendo/cloud/blob/master/cloud-core/src/main/java/org/incendo/cloud/CommandManager.java#L441-L449 + @Override + public boolean hasPermission(GeyserCommandSource source, String permission) { + try { + return super.hasPermission(source, permission); + } catch (UncheckedExecutionException e) { + return false; + } + } +} diff --git a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePermissionHandler.java b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePermissionHandler.java index 732687ae8..6fc334adb 100644 --- a/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePermissionHandler.java +++ b/bootstrap/mod/neoforge/src/main/java/org/geysermc/geyser/platform/neoforge/GeyserNeoForgePermissionHandler.java @@ -30,9 +30,9 @@ import net.neoforged.neoforge.server.permission.nodes.PermissionDynamicContextKe 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.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.event.lifecycle.GeyserRegisterPermissionsEvent; +import org.geysermc.geyser.api.util.TriState; import java.lang.reflect.Constructor; @@ -57,22 +57,27 @@ public class GeyserNeoForgePermissionHandler { } public void onPermissionGather(PermissionGatherEvent.Nodes event) { - this.registerNode(Constants.UPDATE_PERMISSION, event); - - GeyserImpl.getInstance().eventBus().fire((GeyserRegisterPermissionsEvent) (permission, defaultValue) -> this.registerNode(permission, event)); + GeyserImpl.getInstance().eventBus().fire( + (GeyserRegisterPermissionsEvent) (permission, defaultValue) -> { + if (permission.isBlank()) { + return; + } + this.registerNode(permission, defaultValue, event); + } + ); } - private void registerNode(String node, PermissionGatherEvent.Nodes event) { - PermissionNode permissionNode = this.createNode(node); + private void registerNode(String node, TriState permissionDefault, PermissionGatherEvent.Nodes event) { + PermissionNode permissionNode = this.createNode(node, permissionDefault); // NeoForge likes to crash if you try and register a duplicate node - if (!event.getNodes().contains(permissionNode)) { + if (event.getNodes().stream().noneMatch(eventNode -> eventNode.getNodeName().equals(node))) { event.addNodes(permissionNode); } } @SuppressWarnings("unchecked") - private PermissionNode createNode(String node) { + private PermissionNode createNode(String node, TriState permissionDefault) { // The typical constructors in PermissionNode require a // mod id, which means our permission nodes end up becoming // geyser_neoforge. instead of just . We work around @@ -82,7 +87,16 @@ public class GeyserNeoForgePermissionHandler { return (PermissionNode) PERMISSION_NODE_CONSTRUCTOR.newInstance( node, PermissionTypes.BOOLEAN, - (PermissionNode.PermissionResolver) (player, playerUUID, context) -> false, + (PermissionNode.PermissionResolver) (player, playerUUID, context) -> switch (permissionDefault) { + case TRUE -> true; + case FALSE -> false; + case NOT_SET -> { + if (player != null) { + yield player.createCommandSourceStack().hasPermission(player.server.getOperatorUserPermissionLevel()); + } + yield false; + } + }, new PermissionDynamicContextKey[0] ); } catch (Exception e) { diff --git a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSource.java b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSource.java index 9ba89b4dd..3612cb8b7 100644 --- a/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSource.java +++ b/bootstrap/mod/src/main/java/org/geysermc/geyser/platform/mod/command/ModCommandSource.java @@ -88,7 +88,7 @@ public class ModCommandSource implements GeyserCommandSource { // 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); + return GeyserImpl.getInstance().commandRegistry().hasPermission(this, permission); } @Override diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index 7b4dec7cf..05baec501 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -41,7 +41,6 @@ import org.bukkit.permissions.PermissionDefault; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.checkerframework.checker.nullness.qual.NonNull; -import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.adapters.spigot.SpigotAdapters; @@ -277,14 +276,13 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { geyserLogger.debug("Using default world manager."); } - // Register permissions so they appear in, for example, LuckPerms' UI // Re-registering permissions without removing it throws an error - PluginManager pluginManager = Bukkit.getPluginManager(); - - // todo: this can probably always be run regardless if geyser has been initialized once or not, since we are removing the permission geyser.eventBus().fire((GeyserRegisterPermissionsEvent) (permission, def) -> { + if (permission.isBlank()) { + return; + } PermissionDefault permissionDefault = switch (def) { case TRUE -> PermissionDefault.TRUE; case FALSE -> PermissionDefault.FALSE; @@ -302,9 +300,6 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { pluginManager.addPermission(new Permission(permission, permissionDefault)); }); - pluginManager.addPermission(new Permission(Constants.UPDATE_PERMISSION, - "Whether update notifications can be seen", PermissionDefault.OP)); - // Events cannot be unregistered - re-registering results in duplicate firings GeyserSpigotBlockPlaceListener blockPlaceListener = new GeyserSpigotBlockPlaceListener(geyser, this.geyserWorldManager); pluginManager.registerEvents(blockPlaceListener, this); diff --git a/core/src/main/java/org/geysermc/geyser/Constants.java b/core/src/main/java/org/geysermc/geyser/Constants.java index 5de8e6e6b..4c9c36e17 100644 --- a/core/src/main/java/org/geysermc/geyser/Constants.java +++ b/core/src/main/java/org/geysermc/geyser/Constants.java @@ -38,6 +38,8 @@ public final class Constants { public static final String GEYSER_DOWNLOAD_LOCATION = "https://geysermc.org/download"; public static final String UPDATE_PERMISSION = "geyser.update"; + public static final String SERVER_SETTINGS_PERMISSION = "geyser.settings.server"; + public static final String SETTINGS_GAMERULES_PERMISSION = "geyser.settings.gamerules"; static final String SAVED_REFRESH_TOKEN_FILE = "saved-refresh-tokens.json"; diff --git a/core/src/main/java/org/geysermc/geyser/command/CommandRegistry.java b/core/src/main/java/org/geysermc/geyser/command/CommandRegistry.java index 1a60b746c..786433c0f 100644 --- a/core/src/main/java/org/geysermc/geyser/command/CommandRegistry.java +++ b/core/src/main/java/org/geysermc/geyser/command/CommandRegistry.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.command; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.AllArgsConstructor; import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.api.command.Command; @@ -112,7 +113,7 @@ public class CommandRegistry { new GeyserExceptionHandler<>(NoSuchCommandException.class, (src, e) -> src.sendLocaleString("geyser.command.not_found")), new GeyserExceptionHandler<>(ArgumentParseException.class, (src, e) -> src.sendLocaleString("geyser.command.invalid_argument", e.getCause().getMessage())), new GeyserExceptionHandler<>(CommandExecutionException.class, (src, e) -> handleUnexpectedThrowable(src, e.getCause())), - new GeyserExceptionHandler<>(RuntimeException.class, (src, e) -> handleUnexpectedThrowable(src, e.getCause())) + new GeyserExceptionHandler<>(Throwable.class, (src, e) -> handleUnexpectedThrowable(src, e.getCause())) ); for (GeyserExceptionHandler handler : exceptionHandlers) { handler.register(cloud); @@ -195,6 +196,10 @@ public class CommandRegistry { register(command, this.extensionCommands.computeIfAbsent(extension, e -> new HashMap<>())); } + public boolean hasPermission(GeyserCommandSource source, String permission) { + return cloud.hasPermission(source, permission); + } + private void register(GeyserCommand command, Map commands) { command.register(cloud); @@ -218,6 +223,11 @@ public class CommandRegistry { for (Map.Entry permission : permissionDefaults.entrySet()) { event.register(permission.getKey(), permission.getValue()); } + + // Register other various Geyser permissions + event.register(Constants.UPDATE_PERMISSION, TriState.NOT_SET); + event.register(Constants.SERVER_SETTINGS_PERMISSION, TriState.NOT_SET); + event.register(Constants.SETTINGS_GAMERULES_PERMISSION, TriState.NOT_SET); } /** @@ -277,7 +287,7 @@ public class CommandRegistry { } @AllArgsConstructor - private static class GeyserExceptionHandler implements ExceptionHandler { + private static class GeyserExceptionHandler implements ExceptionHandler { final Class type; final BiConsumer handler; diff --git a/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java b/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java index 939edebe7..b419dee30 100644 --- a/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java @@ -89,6 +89,9 @@ public abstract class GeyserCommand implements org.geysermc.geyser.api.command.C if (name.isBlank()) { throw new IllegalArgumentException("Command cannot be null or blank!"); } + if (permission.isBlank()) { + permissionDefault = null; + } this.name = name; this.description = description; diff --git a/core/src/main/java/org/geysermc/geyser/command/GeyserPermission.java b/core/src/main/java/org/geysermc/geyser/command/GeyserPermission.java index 7af32d570..2ba9b32e6 100644 --- a/core/src/main/java/org/geysermc/geyser/command/GeyserPermission.java +++ b/core/src/main/java/org/geysermc/geyser/command/GeyserPermission.java @@ -42,6 +42,9 @@ public class GeyserPermission implements PredicatePermission manager; public Result check(GeyserCommandSource source) { + if (permission.isBlank()) { + return Result.ALLOWED; + } if (bedrockOnly) { if (source.connection() == null) { return Result.NOT_BEDROCK; diff --git a/core/src/main/java/org/geysermc/geyser/command/standalone/StandaloneCloudCommandManager.java b/core/src/main/java/org/geysermc/geyser/command/standalone/StandaloneCloudCommandManager.java index 2788cb201..4a0e78a78 100644 --- a/core/src/main/java/org/geysermc/geyser/command/standalone/StandaloneCloudCommandManager.java +++ b/core/src/main/java/org/geysermc/geyser/command/standalone/StandaloneCloudCommandManager.java @@ -86,6 +86,9 @@ public class StandaloneCloudCommandManager extends CommandManager { + if (permission.isBlank()) { + return; + } if (def == TriState.TRUE) { basePermissions.add(permission); } diff --git a/core/src/main/java/org/geysermc/geyser/extension/command/GeyserExtensionCommand.java b/core/src/main/java/org/geysermc/geyser/extension/command/GeyserExtensionCommand.java index 5613cba1b..f90045e9a 100644 --- a/core/src/main/java/org/geysermc/geyser/extension/command/GeyserExtensionCommand.java +++ b/core/src/main/java/org/geysermc/geyser/extension/command/GeyserExtensionCommand.java @@ -27,7 +27,6 @@ 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; @@ -111,12 +110,6 @@ public abstract class GeyserExtensionCommand extends GeyserCommand { @Override public Builder permission(@NonNull String permission) { this.permission = Objects.requireNonNull(permission, "command permission"); - if (!permission.contains(".") && !permission.isBlank()) { - 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; } @@ -124,12 +117,6 @@ public abstract class GeyserExtensionCommand extends GeyserCommand { public Builder 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(".") && !permission.isBlank()) { - 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; } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 3eb2dc18c..fdff1cd19 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -65,8 +65,6 @@ import io.netty.channel.Channel; import io.netty.channel.EventLoop; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; @@ -1463,7 +1461,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { public boolean hasPermission(String permission) { // for Geyser-Standalone, standalone's permission system will handle it. // for server platforms, the session will be mapped to a server command sender, and the server's api will be used. - return geyser.commandRegistry().cloud().hasPermission(this, permission); + return geyser.commandRegistry().hasPermission(this, permission); } /** diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java index df28f7ca7..38e9e152b 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDefaultGameTypeTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import org.cloudburstmc.protocol.bedrock.packet.SetDefaultGameTypePacket; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; +import org.geysermc.geyser.Constants; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -41,7 +42,7 @@ public class BedrockSetDefaultGameTypeTranslator extends PacketTranslator= 2 && session.hasPermission("geyser.settings.server")) { + if (session.getOpPermissionLevel() >= 2 && session.hasPermission(Constants.SERVER_SETTINGS_PERMISSION)) { session.getGeyser().getWorldManager().setDefaultGameMode(session, GameMode.byId(packet.getGamemode())); } // Stop the client from updating their own Gamemode without telling the server diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java index b996a96b1..0f68cf2df 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetDifficultyTranslator.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket; +import org.geysermc.geyser.Constants; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -39,7 +40,7 @@ public class BedrockSetDifficultyTranslator extends PacketTranslator= 2 && session.hasPermission("geyser.settings.server")) { + if (session.getOpPermissionLevel() >= 2 && session.hasPermission(Constants.SERVER_SETTINGS_PERMISSION)) { if (packet.getDifficulty() != session.getWorldCache().getDifficulty().ordinal()) { session.getGeyser().getWorldManager().setDifficulty(session, Difficulty.from(packet.getDifficulty())); } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java index 2d8d420f8..185cf576a 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; +import org.geysermc.geyser.Constants; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -45,7 +46,7 @@ public class BedrockSetPlayerGameTypeTranslator extends PacketTranslator= 2 && session.hasPermission("geyser.settings.server")) { + if (session.getOpPermissionLevel() >= 2 && session.hasPermission(Constants.SERVER_SETTINGS_PERMISSION)) { if (packet.getGamemode() != session.getGameMode().ordinal()) { // Bedrock has more Gamemodes than Java, leading to cases 5 (for "default") and 6 (for "spectator") being sent // https://github.com/CloudburstMC/Protocol/blob/3.0/bedrock-codec/src/main/java/org/cloudburstmc/protocol/bedrock/data/GameType.java diff --git a/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java b/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java index ed97408b9..0311c4834 100644 --- a/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.util; import org.geysermc.cumulus.component.DropdownComponent; import org.geysermc.cumulus.form.CustomForm; +import org.geysermc.geyser.Constants; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.level.GameRule; import org.geysermc.geyser.level.WorldManager; @@ -79,7 +80,7 @@ public class SettingsUtils { } } - boolean showGamerules = session.getOpPermissionLevel() >= 2 || session.hasPermission("geyser.settings.gamerules"); + boolean showGamerules = session.getOpPermissionLevel() >= 2 || session.hasPermission(Constants.SETTINGS_GAMERULES_PERMISSION); if (showGamerules) { builder.label("geyser.settings.title.game_rules") .translator(MinecraftLocale::getLocaleString); // we need translate gamerules next