From 161c948e5799c6e8d7a3df99234ce0a193054e2f Mon Sep 17 00:00:00 2001 From: Raktbastr Date: Fri, 13 Feb 2026 23:51:56 -0600 Subject: [PATCH] Added support for floodgate, fixed help command --- README.md | 23 +++++++----- .../command/WhitelistCommand.java | 25 +++++++++++++ .../command/WhitelistCommandHandler.java | 37 ++++++++++++++++++- .../config/MessagesConfig.java | 2 +- .../service/MinecraftProfileService.java | 14 +++++-- 5 files changed, 85 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index f72b464..8fb75a7 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,16 @@ This means you can easily migrate your existing whitelists. ## Commands & Permissions -| Command | Description | Permission | -|------------------------------------|---------------------------------------------------------------------------------|-------------------------| -| `/globalwhitelist add ` | Add a player to the whitelist | `globalwhitelist` | -| `/globalwhitelist remove ` | Remove a player from the whitelist | `globalwhitelist` | -| `/globalwhitelist list` | Displays all players in the whitelist | `globalwhitelist` | -| `/globalwhitelist on` | Enable the whitelist | `globalwhitelist.admin` | -| `/globalwhitelist off` | Disable the whitelist | `globalwhitelist.admin` | -| `/globalwhitelist enforced` | Enforce the whitelist. Players not on the whitelist (if enabled) will be kicked | `globalwhitelist.admin` | -| `/globalwhitelist unenforced` | Disable enforcement. Players not on the whitelist will not be kicked | `globalwhitelist.admin` | -| `/globalwhitelist reload` | Reload the whitelist configuration | `globalwhitelist.admin` | +| Command | Description | Permission | +|----------------------------------------------|---------------------------------------------------------------------------------|-------------------------| +| `/globalwhitelist help` | Display the help section | `globalwhitelist` | +| `/globalwhitelist add ` | Add a player to the whitelist | `globalwhitelist` | +| `/globalwhitelist remove ` | Remove a player from the whitelist | `globalwhitelist` | +| `/globalwhitelist floodgate_add ` | Add a bedrock player to the whitelist | `globalwhitelist` | +| `/globalwhitelist floodgate_remove ` | Remove a bedrock player from the whitelist | `globalwhitelist` | +| `/globalwhitelist list` | Displays all players in the whitelist | `globalwhitelist` | +| `/globalwhitelist on` | Enable the whitelist | `globalwhitelist.admin` | +| `/globalwhitelist off` | Disable the whitelist | `globalwhitelist.admin` | +| `/globalwhitelist enforced` | Enforce the whitelist. Players not on the whitelist (if enabled) will be kicked | `globalwhitelist.admin` | +| `/globalwhitelist unenforced` | Disable enforcement. Players not on the whitelist will not be kicked | `globalwhitelist.admin` | +| `/globalwhitelist reload` | Reload the whitelist configuration | `globalwhitelist.admin` | diff --git a/src/main/java/com/uravgcode/globalwhitelist/command/WhitelistCommand.java b/src/main/java/com/uravgcode/globalwhitelist/command/WhitelistCommand.java index 26f98c0..ec93550 100644 --- a/src/main/java/com/uravgcode/globalwhitelist/command/WhitelistCommand.java +++ b/src/main/java/com/uravgcode/globalwhitelist/command/WhitelistCommand.java @@ -34,6 +34,9 @@ public final class WhitelistCommand { .then(buildOffCommand(commandHandler)) .then(buildEnforcedCommand(commandHandler)) .then(buildUnenforcedCommand(commandHandler)) + .then(buildFloodgateRemoveCommand(commandHandler)) + .then(buildFloodgateAddCommand(commandHandler)) + .then(buildHelpCommand(commandHandler)) .build(); return new BrigadierCommand(rootNode); @@ -47,6 +50,14 @@ public final class WhitelistCommand { .executes(handler::add)); } + private static LiteralArgumentBuilder buildFloodgateAddCommand(WhitelistCommandHandler handler) { + return BrigadierCommand.literalArgumentBuilder("floodgate_add") + .requires(source -> source.hasPermission(PERMISSION_BASE) || source.hasPermission(PERMISSION_ADMIN)) + .then(BrigadierCommand.requiredArgumentBuilder("player", StringArgumentType.word()) + .suggests(handler::suggestOnlinePlayers) + .executes(handler::floodgate_add)); + } + private static LiteralArgumentBuilder buildRemoveCommand(WhitelistCommandHandler handler) { return BrigadierCommand.literalArgumentBuilder("remove") .requires(source -> source.hasPermission(PERMISSION_BASE) || source.hasPermission(PERMISSION_ADMIN)) @@ -55,6 +66,14 @@ public final class WhitelistCommand { .executes(handler::remove)); } + private static LiteralArgumentBuilder buildFloodgateRemoveCommand(WhitelistCommandHandler handler) { + return BrigadierCommand.literalArgumentBuilder("floodgate_remove") + .requires(source -> source.hasPermission(PERMISSION_BASE) || source.hasPermission(PERMISSION_ADMIN)) + .then(BrigadierCommand.requiredArgumentBuilder("player", StringArgumentType.word()) + .suggests(handler::suggestWhitelistedPlayers) + .executes(handler::floodgate_remove)); + } + private static LiteralArgumentBuilder buildListCommand(WhitelistCommandHandler handler) { return BrigadierCommand.literalArgumentBuilder("list") .requires(source -> source.hasPermission(PERMISSION_BASE) || source.hasPermission(PERMISSION_ADMIN)) @@ -90,4 +109,10 @@ public final class WhitelistCommand { .requires(source -> source.hasPermission(PERMISSION_ADMIN)) .executes(handler::reload); } + + private static LiteralArgumentBuilder buildHelpCommand(WhitelistCommandHandler handler) { + return BrigadierCommand.literalArgumentBuilder("help") + .requires(source -> source.hasPermission(PERMISSION_BASE)) + .executes(handler::help); + } } diff --git a/src/main/java/com/uravgcode/globalwhitelist/command/WhitelistCommandHandler.java b/src/main/java/com/uravgcode/globalwhitelist/command/WhitelistCommandHandler.java index f967949..b336d66 100644 --- a/src/main/java/com/uravgcode/globalwhitelist/command/WhitelistCommandHandler.java +++ b/src/main/java/com/uravgcode/globalwhitelist/command/WhitelistCommandHandler.java @@ -40,7 +40,22 @@ public record WhitelistCommandHandler( var source = context.getSource(); var playerName = context.getArgument("player", String.class); - profileService.getProfile(playerName).ifPresentOrElse(player -> { + profileService.getProfile(playerName, false).ifPresentOrElse(player -> { + if (whitelist.add(player)) { + source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_ADD_SUCCESS, playerName)); + } else { + source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_ADD_ALREADY_WHITELISTED, playerName)); + } + }, () -> source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_PLAYER_DOES_NOT_EXIST, playerName))); + + return Command.SINGLE_SUCCESS; + } + + public int floodgate_add(CommandContext context) { + var source = context.getSource(); + var playerName = context.getArgument("player", String.class); + + profileService.getProfile(playerName, true).ifPresentOrElse(player -> { if (whitelist.add(player)) { source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_ADD_SUCCESS, playerName)); } else { @@ -55,7 +70,25 @@ public record WhitelistCommandHandler( var source = context.getSource(); var playerName = context.getArgument("player", String.class); - profileService.getProfile(playerName).ifPresentOrElse(player -> { + profileService.getProfile(playerName, false).ifPresentOrElse(player -> { + if (whitelist.remove(player)) { + source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_REMOVE_SUCCESS, playerName)); + if (config.whitelistEnabled() && config.enforceWhitelistEnabled()) { + proxy.getPlayer(playerName).ifPresent(p -> p.disconnect(messages.getMessage(MessagesConfig.WHITELIST_REJECTED))); + } + } else { + source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_REMOVE_NOT_WHITELISTED, playerName)); + } + }, () -> source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_PLAYER_DOES_NOT_EXIST, playerName))); + + return Command.SINGLE_SUCCESS; + } + + public int floodgate_remove(CommandContext context) { + var source = context.getSource(); + var playerName = context.getArgument("player", String.class); + + profileService.getProfile(playerName, true).ifPresentOrElse(player -> { if (whitelist.remove(player)) { source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_REMOVE_SUCCESS, playerName)); if (config.whitelistEnabled() && config.enforceWhitelistEnabled()) { diff --git a/src/main/java/com/uravgcode/globalwhitelist/config/MessagesConfig.java b/src/main/java/com/uravgcode/globalwhitelist/config/MessagesConfig.java index 2ed2269..8a187b8 100644 --- a/src/main/java/com/uravgcode/globalwhitelist/config/MessagesConfig.java +++ b/src/main/java/com/uravgcode/globalwhitelist/config/MessagesConfig.java @@ -79,7 +79,7 @@ public class MessagesConfig { } private void loadDefaults() { - messages.setProperty(WHITELIST_HELP, "/globalwhitelist "); + messages.setProperty(WHITELIST_HELP, "/globalwhitelist "); messages.setProperty(WHITELIST_ADD_SUCCESS, "Added to the whitelist"); messages.setProperty(WHITELIST_ADD_ALREADY_WHITELISTED, "Player is already whitelisted"); diff --git a/src/main/java/com/uravgcode/globalwhitelist/service/MinecraftProfileService.java b/src/main/java/com/uravgcode/globalwhitelist/service/MinecraftProfileService.java index a6f8aa4..9b28315 100644 --- a/src/main/java/com/uravgcode/globalwhitelist/service/MinecraftProfileService.java +++ b/src/main/java/com/uravgcode/globalwhitelist/service/MinecraftProfileService.java @@ -14,7 +14,8 @@ import java.util.Optional; import java.util.UUID; public class MinecraftProfileService { - private static final URI API_BASE_URL = URI.create("https://api.minecraftservices.com/minecraft/profile/lookup/name/"); + private static final URI MC_API_BASE_URL = URI.create("https://api.minecraftservices.com/minecraft/profile/lookup/name/"); + private static final URI FLOODGATE_API_BASE_URL = URI.create("https://api.geysermc.org/v2/utils/uuid/bedrock_or_java/"); private static final Duration TIMEOUT = Duration.ofSeconds(5); private final Logger logger; @@ -27,15 +28,21 @@ public class MinecraftProfileService { .build(); } - public Optional getProfile(String playerName) { + public Optional getProfile(String playerName, boolean floodgate) { if (playerName == null || playerName.isBlank()) { logger.warn("player name cannot be null or empty"); return Optional.empty(); } + URI api_url; + if (floodgate) { + api_url = URI.create(FLOODGATE_API_BASE_URL+playerName+"?prefix="+playerName.charAt(0)); + } else { + api_url = URI.create(MC_API_BASE_URL+playerName); + } try { var request = HttpRequest.newBuilder() - .uri(API_BASE_URL.resolve(playerName)) + .uri(api_url) .timeout(TIMEOUT) .GET() .build(); @@ -50,6 +57,7 @@ public class MinecraftProfileService { } default -> { logger.warn("api request failed with status {}: {}", response.statusCode(), response.body()); + logger.warn(api_url.toString()); yield Optional.empty(); } };