Added support for floodgate, fixed help command

This commit is contained in:
Raktbastr 2026-02-13 23:51:56 -06:00
parent 84ee6ac378
commit 161c948e57
5 changed files with 85 additions and 16 deletions

View file

@ -7,9 +7,12 @@ This means you can easily migrate your existing whitelists.
## Commands & Permissions ## Commands & Permissions
| Command | Description | Permission | | Command | Description | Permission |
|------------------------------------|---------------------------------------------------------------------------------|-------------------------| |----------------------------------------------|---------------------------------------------------------------------------------|-------------------------|
| `/globalwhitelist help` | Display the help section | `globalwhitelist` |
| `/globalwhitelist add <player>` | Add a player to the whitelist | `globalwhitelist` | | `/globalwhitelist add <player>` | Add a player to the whitelist | `globalwhitelist` |
| `/globalwhitelist remove <player>` | Remove a player from the whitelist | `globalwhitelist` | | `/globalwhitelist remove <player>` | Remove a player from the whitelist | `globalwhitelist` |
| `/globalwhitelist floodgate_add <player>` | Add a bedrock player to the whitelist | `globalwhitelist` |
| `/globalwhitelist floodgate_remove <player>` | Remove a bedrock player from the whitelist | `globalwhitelist` |
| `/globalwhitelist list` | Displays all players in the whitelist | `globalwhitelist` | | `/globalwhitelist list` | Displays all players in the whitelist | `globalwhitelist` |
| `/globalwhitelist on` | Enable the whitelist | `globalwhitelist.admin` | | `/globalwhitelist on` | Enable the whitelist | `globalwhitelist.admin` |
| `/globalwhitelist off` | Disable the whitelist | `globalwhitelist.admin` | | `/globalwhitelist off` | Disable the whitelist | `globalwhitelist.admin` |

View file

@ -34,6 +34,9 @@ public final class WhitelistCommand {
.then(buildOffCommand(commandHandler)) .then(buildOffCommand(commandHandler))
.then(buildEnforcedCommand(commandHandler)) .then(buildEnforcedCommand(commandHandler))
.then(buildUnenforcedCommand(commandHandler)) .then(buildUnenforcedCommand(commandHandler))
.then(buildFloodgateRemoveCommand(commandHandler))
.then(buildFloodgateAddCommand(commandHandler))
.then(buildHelpCommand(commandHandler))
.build(); .build();
return new BrigadierCommand(rootNode); return new BrigadierCommand(rootNode);
@ -47,6 +50,14 @@ public final class WhitelistCommand {
.executes(handler::add)); .executes(handler::add));
} }
private static LiteralArgumentBuilder<CommandSource> 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<CommandSource> buildRemoveCommand(WhitelistCommandHandler handler) { private static LiteralArgumentBuilder<CommandSource> buildRemoveCommand(WhitelistCommandHandler handler) {
return BrigadierCommand.literalArgumentBuilder("remove") return BrigadierCommand.literalArgumentBuilder("remove")
.requires(source -> source.hasPermission(PERMISSION_BASE) || source.hasPermission(PERMISSION_ADMIN)) .requires(source -> source.hasPermission(PERMISSION_BASE) || source.hasPermission(PERMISSION_ADMIN))
@ -55,6 +66,14 @@ public final class WhitelistCommand {
.executes(handler::remove)); .executes(handler::remove));
} }
private static LiteralArgumentBuilder<CommandSource> 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<CommandSource> buildListCommand(WhitelistCommandHandler handler) { private static LiteralArgumentBuilder<CommandSource> buildListCommand(WhitelistCommandHandler handler) {
return BrigadierCommand.literalArgumentBuilder("list") return BrigadierCommand.literalArgumentBuilder("list")
.requires(source -> source.hasPermission(PERMISSION_BASE) || source.hasPermission(PERMISSION_ADMIN)) .requires(source -> source.hasPermission(PERMISSION_BASE) || source.hasPermission(PERMISSION_ADMIN))
@ -90,4 +109,10 @@ public final class WhitelistCommand {
.requires(source -> source.hasPermission(PERMISSION_ADMIN)) .requires(source -> source.hasPermission(PERMISSION_ADMIN))
.executes(handler::reload); .executes(handler::reload);
} }
private static LiteralArgumentBuilder<CommandSource> buildHelpCommand(WhitelistCommandHandler handler) {
return BrigadierCommand.literalArgumentBuilder("help")
.requires(source -> source.hasPermission(PERMISSION_BASE))
.executes(handler::help);
}
} }

View file

@ -40,7 +40,22 @@ public record WhitelistCommandHandler(
var source = context.getSource(); var source = context.getSource();
var playerName = context.getArgument("player", String.class); 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<CommandSource> context) {
var source = context.getSource();
var playerName = context.getArgument("player", String.class);
profileService.getProfile(playerName, true).ifPresentOrElse(player -> {
if (whitelist.add(player)) { if (whitelist.add(player)) {
source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_ADD_SUCCESS, playerName)); source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_ADD_SUCCESS, playerName));
} else { } else {
@ -55,7 +70,25 @@ public record WhitelistCommandHandler(
var source = context.getSource(); var source = context.getSource();
var playerName = context.getArgument("player", String.class); 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<CommandSource> context) {
var source = context.getSource();
var playerName = context.getArgument("player", String.class);
profileService.getProfile(playerName, true).ifPresentOrElse(player -> {
if (whitelist.remove(player)) { if (whitelist.remove(player)) {
source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_REMOVE_SUCCESS, playerName)); source.sendMessage(messages.getMessage(MessagesConfig.WHITELIST_REMOVE_SUCCESS, playerName));
if (config.whitelistEnabled() && config.enforceWhitelistEnabled()) { if (config.whitelistEnabled() && config.enforceWhitelistEnabled()) {

View file

@ -79,7 +79,7 @@ public class MessagesConfig {
} }
private void loadDefaults() { private void loadDefaults() {
messages.setProperty(WHITELIST_HELP, "<red>/globalwhitelist <add|remove|list|on|off|enforce|unenforce|reload>"); messages.setProperty(WHITELIST_HELP, "<red>/globalwhitelist <add|remove|list|on|off|enforce|unenforce|reload|floodgate_add|floodgate_remove>");
messages.setProperty(WHITELIST_ADD_SUCCESS, "Added <player> to the whitelist"); messages.setProperty(WHITELIST_ADD_SUCCESS, "Added <player> to the whitelist");
messages.setProperty(WHITELIST_ADD_ALREADY_WHITELISTED, "<red>Player is already whitelisted"); messages.setProperty(WHITELIST_ADD_ALREADY_WHITELISTED, "<red>Player is already whitelisted");

View file

@ -14,7 +14,8 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public class MinecraftProfileService { 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 static final Duration TIMEOUT = Duration.ofSeconds(5);
private final Logger logger; private final Logger logger;
@ -27,15 +28,21 @@ public class MinecraftProfileService {
.build(); .build();
} }
public Optional<PlayerProfile> getProfile(String playerName) { public Optional<PlayerProfile> getProfile(String playerName, boolean floodgate) {
if (playerName == null || playerName.isBlank()) { if (playerName == null || playerName.isBlank()) {
logger.warn("player name cannot be null or empty"); logger.warn("player name cannot be null or empty");
return Optional.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 { try {
var request = HttpRequest.newBuilder() var request = HttpRequest.newBuilder()
.uri(API_BASE_URL.resolve(playerName)) .uri(api_url)
.timeout(TIMEOUT) .timeout(TIMEOUT)
.GET() .GET()
.build(); .build();
@ -50,6 +57,7 @@ public class MinecraftProfileService {
} }
default -> { default -> {
logger.warn("api request failed with status {}: {}", response.statusCode(), response.body()); logger.warn("api request failed with status {}: {}", response.statusCode(), response.body());
logger.warn(api_url.toString());
yield Optional.empty(); yield Optional.empty();
} }
}; };