Permissions class for general perms, GeyserImpl is responsible for the subscription

This commit is contained in:
Konicai 2024-06-08 21:10:55 -05:00
parent c672d6273b
commit d1abeee7b8
13 changed files with 96 additions and 31 deletions

View file

@ -29,8 +29,8 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.PostLoginEvent; import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler; import net.md_5.bungee.event.EventHandler;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.Permissions;
import org.geysermc.geyser.platform.bungeecord.command.BungeeCommandSource; import org.geysermc.geyser.platform.bungeecord.command.BungeeCommandSource;
import org.geysermc.geyser.util.VersionCheckUtils; import org.geysermc.geyser.util.VersionCheckUtils;
@ -40,7 +40,7 @@ public final class GeyserBungeeUpdateListener implements Listener {
public void onPlayerJoin(final PostLoginEvent event) { public void onPlayerJoin(final PostLoginEvent event) {
if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) { if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) {
final ProxiedPlayer player = event.getPlayer(); final ProxiedPlayer player = event.getPlayer();
if (player.hasPermission(Constants.UPDATE_PERMISSION)) { if (player.hasPermission(Permissions.CHECK_UPDATE)) {
VersionCheckUtils.checkForGeyserUpdate(() -> new BungeeCommandSource(player)); VersionCheckUtils.checkForGeyserUpdate(() -> new BungeeCommandSource(player));
} }
} }

View file

@ -26,14 +26,14 @@
package org.geysermc.geyser.platform.mod; package org.geysermc.geyser.platform.mod;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import org.geysermc.geyser.Constants; import org.geysermc.geyser.Permissions;
import org.geysermc.geyser.platform.mod.command.ModCommandSource; import org.geysermc.geyser.platform.mod.command.ModCommandSource;
import org.geysermc.geyser.util.VersionCheckUtils; import org.geysermc.geyser.util.VersionCheckUtils;
public final class GeyserModUpdateListener { public final class GeyserModUpdateListener {
public static void onPlayReady(Player player) { public static void onPlayReady(Player player) {
ModCommandSource source = new ModCommandSource(player.createCommandSourceStack()); ModCommandSource source = new ModCommandSource(player.createCommandSourceStack());
if (source.hasPermission(Constants.UPDATE_PERMISSION)) { if (source.hasPermission(Permissions.CHECK_UPDATE)) {
VersionCheckUtils.checkForGeyserUpdate(() -> source); VersionCheckUtils.checkForGeyserUpdate(() -> source);
} }
} }

View file

@ -29,8 +29,8 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.Permissions;
import org.geysermc.geyser.platform.spigot.command.SpigotCommandSource; import org.geysermc.geyser.platform.spigot.command.SpigotCommandSource;
import org.geysermc.geyser.util.VersionCheckUtils; import org.geysermc.geyser.util.VersionCheckUtils;
@ -40,7 +40,7 @@ public final class GeyserSpigotUpdateListener implements Listener {
public void onPlayerJoin(final PlayerJoinEvent event) { public void onPlayerJoin(final PlayerJoinEvent event) {
if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) { if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
if (player.hasPermission(Constants.UPDATE_PERMISSION)) { if (player.hasPermission(Permissions.CHECK_UPDATE)) {
VersionCheckUtils.checkForGeyserUpdate(() -> new SpigotCommandSource(player)); VersionCheckUtils.checkForGeyserUpdate(() -> new SpigotCommandSource(player));
} }
} }

View file

@ -70,6 +70,7 @@ import java.util.stream.Collectors;
public class GeyserStandaloneBootstrap implements GeyserBootstrap { public class GeyserStandaloneBootstrap implements GeyserBootstrap {
private StandaloneCloudCommandManager cloud;
private CommandRegistry commandRegistry; private CommandRegistry commandRegistry;
private GeyserStandaloneConfiguration geyserConfig; private GeyserStandaloneConfiguration geyserConfig;
private final GeyserStandaloneLogger geyserLogger = new GeyserStandaloneLogger(); private final GeyserStandaloneLogger geyserLogger = new GeyserStandaloneLogger();
@ -223,15 +224,22 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
geyser = GeyserImpl.load(PlatformType.STANDALONE, this); geyser = GeyserImpl.load(PlatformType.STANDALONE, this);
if (!geyser.isReloading()) { boolean reloading = geyser.isReloading();
// fire GeyserDefineCommandsEvent after PreInitEvent, before PostInitEvent, for consistency with other bootstraps if (!reloading) {
StandaloneCloudCommandManager cloud = new StandaloneCloudCommandManager(geyser); // Currently there would be no significant benefit of re-initializing commands. Also, we would have to unsubscribe CommandRegistry.
// Fire GeyserDefineCommandsEvent after PreInitEvent, before PostInitEvent, for consistency with other bootstraps.
cloud = new StandaloneCloudCommandManager(geyser);
commandRegistry = new CommandRegistry(geyser, cloud); commandRegistry = new CommandRegistry(geyser, cloud);
cloud.fireRegisterPermissionsEvent(); // event must be fired after CommandRegistry has subscribed its listener
} }
GeyserImpl.start(); GeyserImpl.start();
if (!reloading) {
// Event must be fired after CommandRegistry has subscribed its listener.
// Also, the subscription for the Permissions class is created when Geyser is initialized.
cloud.fireRegisterPermissionsEvent();
}
if (gui != null) { if (gui != null) {
gui.enableCommands(geyser.getScheduledThread(), commandRegistry); gui.enableCommands(geyser.getScheduledThread(), commandRegistry);
} }

View file

@ -28,8 +28,8 @@ package org.geysermc.geyser.platform.velocity;
import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.PostLoginEvent; import com.velocitypowered.api.event.connection.PostLoginEvent;
import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.Player;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.Permissions;
import org.geysermc.geyser.platform.velocity.command.VelocityCommandSource; import org.geysermc.geyser.platform.velocity.command.VelocityCommandSource;
import org.geysermc.geyser.util.VersionCheckUtils; import org.geysermc.geyser.util.VersionCheckUtils;
@ -39,7 +39,7 @@ public final class GeyserVelocityUpdateListener {
public void onPlayerJoin(PostLoginEvent event) { public void onPlayerJoin(PostLoginEvent event) {
if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) { if (GeyserImpl.getInstance().getConfig().isNotifyOnNewBedrockUpdate()) {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
if (player.hasPermission(Constants.UPDATE_PERMISSION)) { if (player.hasPermission(Permissions.CHECK_UPDATE)) {
VersionCheckUtils.checkForGeyserUpdate(() -> new VelocityCommandSource(player)); VersionCheckUtils.checkForGeyserUpdate(() -> new VelocityCommandSource(player));
} }
} }

View file

@ -35,11 +35,7 @@ public final class Constants {
public static final String NEWS_PROJECT_NAME = "geyser"; public static final String NEWS_PROJECT_NAME = "geyser";
public static final String FLOODGATE_DOWNLOAD_LOCATION = "https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/master/"; public static final String FLOODGATE_DOWNLOAD_LOCATION = "https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/master/";
public static final String GEYSER_DOWNLOAD_LOCATION = "https://geysermc.org/download"; 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"; static final String SAVED_REFRESH_TOKEN_FILE = "saved-refresh-tokens.json";

View file

@ -104,7 +104,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@Getter @Getter
public class GeyserImpl implements GeyserApi { public class GeyserImpl implements GeyserApi, EventRegistrar {
public static final ObjectMapper JSON_MAPPER = new ObjectMapper() public static final ObjectMapper JSON_MAPPER = new ObjectMapper()
.enable(JsonParser.Feature.IGNORE_UNDEFINED) .enable(JsonParser.Feature.IGNORE_UNDEFINED)
.enable(JsonParser.Feature.ALLOW_COMMENTS) .enable(JsonParser.Feature.ALLOW_COMMENTS)
@ -233,6 +233,9 @@ public class GeyserImpl implements GeyserApi {
CompletableFuture.runAsync(AssetUtils::downloadAndRunClientJarTasks); CompletableFuture.runAsync(AssetUtils::downloadAndRunClientJarTasks);
}); });
// Register our general permissions when possible
eventBus.subscribe(this, GeyserRegisterPermissionsEvent.class, Permissions::register);
startInstance(); startInstance();
GeyserConfiguration config = bootstrap.getGeyserConfig(); GeyserConfiguration config = bootstrap.getGeyserConfig();

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 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;
import org.geysermc.geyser.api.event.lifecycle.GeyserRegisterPermissionsEvent;
import org.geysermc.geyser.api.util.TriState;
import java.util.HashMap;
import java.util.Map;
/**
* Permissions related to Geyser
*/
public final class Permissions {
private static final Map<String, TriState> PERMISSIONS = new HashMap<>();
public static final String CHECK_UPDATE = register("geyser.update");
public static final String SERVER_SETTINGS = register("geyser.settings.server");
public static final String SETTINGS_GAMERULES = register("geyser.settings.gamerules");
private Permissions() {
//no
}
private static String register(String permission) {
return register(permission, TriState.NOT_SET);
}
@SuppressWarnings("SameParameterValue")
private static String register(String permission, TriState permissionDefault) {
PERMISSIONS.put(permission, permissionDefault);
return permission;
}
public static void register(GeyserRegisterPermissionsEvent event) {
for (Map.Entry<String, TriState> permission : PERMISSIONS.entrySet()) {
event.register(permission.getKey(), permission.getValue());
}
}
}

View file

@ -27,7 +27,6 @@ package org.geysermc.geyser.command;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.api.event.EventRegistrar; import org.geysermc.geyser.api.event.EventRegistrar;
@ -238,11 +237,6 @@ public class CommandRegistry implements EventRegistrar {
for (Map.Entry<String, TriState> permission : permissionDefaults.entrySet()) { for (Map.Entry<String, TriState> permission : permissionDefaults.entrySet()) {
event.register(permission.getKey(), permission.getValue()); 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);
} }
public boolean hasPermission(GeyserCommandSource source, String permission) { public boolean hasPermission(GeyserCommandSource source, String permission) {

View file

@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player;
import org.cloudburstmc.protocol.bedrock.packet.SetDefaultGameTypePacket; import org.cloudburstmc.protocol.bedrock.packet.SetDefaultGameTypePacket;
import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket;
import org.geysermc.geyser.Constants; import org.geysermc.geyser.Permissions;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
@ -42,7 +42,7 @@ public class BedrockSetDefaultGameTypeTranslator extends PacketTranslator<SetDef
*/ */
@Override @Override
public void translate(GeyserSession session, SetDefaultGameTypePacket packet) { public void translate(GeyserSession session, SetDefaultGameTypePacket packet) {
if (session.getOpPermissionLevel() >= 2 && session.hasPermission(Constants.SERVER_SETTINGS_PERMISSION)) { if (session.getOpPermissionLevel() >= 2 && session.hasPermission(Permissions.SERVER_SETTINGS)) {
session.getGeyser().getWorldManager().setDefaultGameMode(session, GameMode.byId(packet.getGamemode())); session.getGeyser().getWorldManager().setDefaultGameMode(session, GameMode.byId(packet.getGamemode()));
} }
// Stop the client from updating their own Gamemode without telling the server // Stop the client from updating their own Gamemode without telling the server

View file

@ -25,9 +25,9 @@
package org.geysermc.geyser.translator.protocol.bedrock.entity.player; package org.geysermc.geyser.translator.protocol.bedrock.entity.player;
import org.geysermc.geyser.Permissions;
import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty; import org.geysermc.mcprotocollib.protocol.data.game.setting.Difficulty;
import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket; import org.cloudburstmc.protocol.bedrock.packet.SetDifficultyPacket;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
@ -40,7 +40,7 @@ public class BedrockSetDifficultyTranslator extends PacketTranslator<SetDifficul
*/ */
@Override @Override
public void translate(GeyserSession session, SetDifficultyPacket packet) { public void translate(GeyserSession session, SetDifficultyPacket packet) {
if (session.getOpPermissionLevel() >= 2 && session.hasPermission(Constants.SERVER_SETTINGS_PERMISSION)) { if (session.getOpPermissionLevel() >= 2 && session.hasPermission(Permissions.SERVER_SETTINGS)) {
if (packet.getDifficulty() != session.getWorldCache().getDifficulty().ordinal()) { if (packet.getDifficulty() != session.getWorldCache().getDifficulty().ordinal()) {
session.getGeyser().getWorldManager().setDifficulty(session, Difficulty.from(packet.getDifficulty())); session.getGeyser().getWorldManager().setDifficulty(session, Difficulty.from(packet.getDifficulty()));
} }

View file

@ -26,7 +26,7 @@
package org.geysermc.geyser.translator.protocol.bedrock.entity.player; package org.geysermc.geyser.translator.protocol.bedrock.entity.player;
import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket;
import org.geysermc.geyser.Constants; import org.geysermc.geyser.Permissions;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.Translator;
@ -46,7 +46,7 @@ public class BedrockSetPlayerGameTypeTranslator extends PacketTranslator<SetPlay
@Override @Override
public void translate(GeyserSession session, SetPlayerGameTypePacket packet) { public void translate(GeyserSession session, SetPlayerGameTypePacket packet) {
// yes, if you are OP // yes, if you are OP
if (session.getOpPermissionLevel() >= 2 && session.hasPermission(Constants.SERVER_SETTINGS_PERMISSION)) { if (session.getOpPermissionLevel() >= 2 && session.hasPermission(Permissions.SERVER_SETTINGS)) {
if (packet.getGamemode() != session.getGameMode().ordinal()) { if (packet.getGamemode() != session.getGameMode().ordinal()) {
// Bedrock has more Gamemodes than Java, leading to cases 5 (for "default") and 6 (for "spectator") being sent // 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 // https://github.com/CloudburstMC/Protocol/blob/3.0/bedrock-codec/src/main/java/org/cloudburstmc/protocol/bedrock/data/GameType.java

View file

@ -27,8 +27,8 @@ package org.geysermc.geyser.util;
import org.geysermc.cumulus.component.DropdownComponent; import org.geysermc.cumulus.component.DropdownComponent;
import org.geysermc.cumulus.form.CustomForm; import org.geysermc.cumulus.form.CustomForm;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.Permissions;
import org.geysermc.geyser.level.GameRule; import org.geysermc.geyser.level.GameRule;
import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.level.WorldManager;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
@ -80,7 +80,7 @@ public class SettingsUtils {
} }
} }
boolean showGamerules = session.getOpPermissionLevel() >= 2 || session.hasPermission(Constants.SETTINGS_GAMERULES_PERMISSION); boolean showGamerules = session.getOpPermissionLevel() >= 2 || session.hasPermission(Permissions.SETTINGS_GAMERULES);
if (showGamerules) { if (showGamerules) {
builder.label("geyser.settings.title.game_rules") builder.label("geyser.settings.title.game_rules")
.translator(MinecraftLocale::getLocaleString); // we need translate gamerules next .translator(MinecraftLocale::getLocaleString); // we need translate gamerules next