mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-19 06:49:24 +00:00
Feature: Cloud 2.0, publishing setup fixes (#496)
* - Update to cloud 2.0 - bump floodgate version to 2.2.3 - fix publishing setup - don't publish shadow jars, ensure api/core artifacts aren't shaded jars * - update bstats - fix alias -> description * tiny cleanup, fix whitelisting bedrock players when the linked java account is online (and shares the same name) * Update build process * Ensure BUILD_JSON env is init * Fallback to GH run number * update guice to 6.0.0 to be compatible with java 21 * update languages module * Support 1.20.5 spigot, update languages module, update Bungee dependency so the project builds * remove codemc repo, update cloud-paper to snapshot build for 1.20.5 support --------- Co-authored-by: Kas-tle <26531652+Kas-tle@users.noreply.github.com>
This commit is contained in:
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,4 +1,4 @@
|
||||
[submodule "core/src/main/resources/languages"]
|
||||
path = core/src/main/resources/languages
|
||||
url = https://github.com/GeyserMC/languages
|
||||
branch = l10n_floodgate
|
||||
branch = floodgate
|
||||
@@ -1,3 +1,5 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
dependencies {
|
||||
api("org.geysermc.geyser", "common", Versions.geyserVersion)
|
||||
api("org.geysermc.cumulus", "cumulus", Versions.cumulusVersion)
|
||||
@@ -5,3 +7,12 @@ dependencies {
|
||||
|
||||
compileOnly("io.netty", "netty-transport", Versions.nettyVersion)
|
||||
}
|
||||
|
||||
tasks {
|
||||
named<Jar>("jar") {
|
||||
archiveClassifier.set("")
|
||||
}
|
||||
named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("shaded")
|
||||
}
|
||||
}
|
||||
|
||||
1
build-logic/settings.gradle.kts
Normal file
1
build-logic/settings.gradle.kts
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = "build-logic"
|
||||
@@ -30,11 +30,11 @@ object Versions {
|
||||
const val configUtilsVersion = "1.0-SNAPSHOT"
|
||||
const val spigotVersion = "1.19.4-R0.1-SNAPSHOT"
|
||||
const val fastutilVersion = "8.5.3"
|
||||
const val guiceVersion = "5.1.0"
|
||||
const val guiceVersion = "6.0.0"
|
||||
const val nettyVersion = "4.1.49.Final"
|
||||
const val snakeyamlVersion = "1.28"
|
||||
const val cloudVersion = "1.5.0"
|
||||
const val bstatsVersion = "d2fbbd6823"
|
||||
const val cloudVersion = "2.0.0-beta.2"
|
||||
const val bstatsVersion = "3.0.2"
|
||||
|
||||
const val javaWebsocketVersion = "1.5.2"
|
||||
|
||||
|
||||
@@ -12,4 +12,10 @@ indra {
|
||||
|
||||
publishSnapshotsTo("geysermc", "https://repo.opencollab.dev/maven-snapshots")
|
||||
publishReleasesTo("geysermc", "https://repo.opencollab.dev/maven-releases")
|
||||
}
|
||||
|
||||
publishing {
|
||||
// skip shadow jar from publishing. Workaround for https://github.com/johnrengelman/shadow/issues/651
|
||||
val javaComponent = project.components["java"] as AdhocComponentWithVariants
|
||||
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) { skip() }
|
||||
}
|
||||
@@ -4,12 +4,12 @@ var guavaVersion = "21.0"
|
||||
|
||||
dependencies {
|
||||
api(projects.core)
|
||||
implementation("cloud.commandframework", "cloud-bungee", Versions.cloudVersion)
|
||||
implementation("org.incendo", "cloud-bungee", Versions.cloudVersion)
|
||||
}
|
||||
|
||||
relocate("com.google.inject")
|
||||
relocate("net.kyori")
|
||||
relocate("cloud.commandframework")
|
||||
relocate("org.incendo.cloud")
|
||||
// used in cloud
|
||||
relocate("io.leangen.geantyref")
|
||||
// since 1.20
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
|
||||
package org.geysermc.floodgate.module;
|
||||
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.bungee.BungeeCommandManager;
|
||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
@@ -35,7 +32,6 @@ import com.google.inject.name.Named;
|
||||
import com.google.inject.name.Names;
|
||||
import java.util.logging.Logger;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import org.geysermc.floodgate.BungeePlugin;
|
||||
@@ -51,6 +47,7 @@ import org.geysermc.floodgate.platform.pluginmessage.PluginMessageUtils;
|
||||
import org.geysermc.floodgate.platform.util.PlatformUtils;
|
||||
import org.geysermc.floodgate.player.FloodgateCommandPreprocessor;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.player.audience.FloodgateSenderMapper;
|
||||
import org.geysermc.floodgate.pluginmessage.BungeePluginMessageRegistration;
|
||||
import org.geysermc.floodgate.pluginmessage.BungeePluginMessageUtils;
|
||||
import org.geysermc.floodgate.pluginmessage.BungeeSkinApplier;
|
||||
@@ -60,6 +57,9 @@ import org.geysermc.floodgate.skin.SkinApplier;
|
||||
import org.geysermc.floodgate.util.BungeeCommandUtil;
|
||||
import org.geysermc.floodgate.util.BungeePlatformUtils;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.bungee.BungeeCommandManager;
|
||||
import org.incendo.cloud.execution.ExecutionCoordinator;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class BungeePlatformModule extends AbstractModule {
|
||||
@@ -88,9 +88,8 @@ public final class BungeePlatformModule extends AbstractModule {
|
||||
public CommandManager<UserAudience> commandManager(CommandUtil commandUtil) {
|
||||
CommandManager<UserAudience> commandManager = new BungeeCommandManager<>(
|
||||
plugin,
|
||||
CommandExecutionCoordinator.simpleCoordinator(),
|
||||
commandUtil::getUserAudience,
|
||||
audience -> (CommandSender) audience.source()
|
||||
ExecutionCoordinator.simpleCoordinator(),
|
||||
new FloodgateSenderMapper<>(commandUtil)
|
||||
);
|
||||
commandManager.registerCommandPreProcessor(new FloodgateCommandPreprocessor<>(commandUtil));
|
||||
return commandManager;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
plugins {
|
||||
id("floodgate.generate-templates")
|
||||
}
|
||||
@@ -13,10 +15,8 @@ dependencies {
|
||||
api("com.nukkitx.fastutil", "fastutil-short-object-maps", Versions.fastutilVersion)
|
||||
api("com.nukkitx.fastutil", "fastutil-int-object-maps", Versions.fastutilVersion)
|
||||
api("org.java-websocket", "Java-WebSocket", Versions.javaWebsocketVersion)
|
||||
api("cloud.commandframework", "cloud-core", Versions.cloudVersion)
|
||||
|
||||
//todo use official dependency once https://github.com/Bastian/bstats-metrics/pull/118 is merged
|
||||
api("com.github.Konicai.bstats-metrics", "bstats-base", Versions.bstatsVersion)
|
||||
api("org.incendo", "cloud-core", Versions.cloudVersion)
|
||||
api("org.bstats", "bstats-base", Versions.bstatsVersion)
|
||||
}
|
||||
|
||||
// present on all platforms
|
||||
@@ -31,4 +31,10 @@ tasks {
|
||||
replaceToken("branch", branchName())
|
||||
replaceToken("buildNumber", buildNumber())
|
||||
}
|
||||
}
|
||||
named<Jar>("jar") {
|
||||
archiveClassifier.set("")
|
||||
}
|
||||
named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("shaded")
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,8 @@
|
||||
package org.geysermc.floodgate.command;
|
||||
|
||||
import static org.geysermc.floodgate.command.CommonCommandMessage.CHECK_CONSOLE;
|
||||
import static org.incendo.cloud.parser.standard.StringParser.stringParser;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.Command;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.arguments.standard.StringArgument;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import com.google.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -46,9 +42,13 @@ import org.geysermc.floodgate.platform.command.FloodgateCommand;
|
||||
import org.geysermc.floodgate.platform.command.TranslatableMessage;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.player.UserAudience.PlayerAudience;
|
||||
import org.geysermc.floodgate.player.audience.PlayerAudienceArgument;
|
||||
import org.geysermc.floodgate.player.audience.ProfileAudience;
|
||||
import org.geysermc.floodgate.player.audience.ProfileAudienceArgument;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.description.Description;
|
||||
|
||||
@NoArgsConstructor
|
||||
public final class LinkAccountCommand implements FloodgateCommand {
|
||||
@@ -56,20 +56,19 @@ public final class LinkAccountCommand implements FloodgateCommand {
|
||||
@Inject private FloodgateLogger logger;
|
||||
|
||||
@Override
|
||||
public Command<UserAudience> buildCommand(CommandManager<UserAudience> commandManager) {
|
||||
public Command<PlayerAudience> buildCommand(CommandManager<UserAudience> commandManager) {
|
||||
return commandManager.commandBuilder("linkaccount",
|
||||
ArgumentDescription.of("Link your Java account with your Bedrock account"))
|
||||
Description.of("Link your Java account with your Bedrock account"))
|
||||
.senderType(PlayerAudience.class)
|
||||
.permission(Permission.COMMAND_LINK.get())
|
||||
.argument(ProfileAudienceArgument.of("player", true))
|
||||
.argument(StringArgument.optional("code"))
|
||||
.argument(PlayerAudienceArgument.ofAnyUsernameBoth("player"))
|
||||
.optional("code", stringParser())
|
||||
.handler(this::execute)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext<UserAudience> context) {
|
||||
UserAudience sender = context.getSender();
|
||||
public void execute(CommandContext<PlayerAudience> context) {
|
||||
UserAudience sender = context.sender();
|
||||
|
||||
PlayerLink link = api.getPlayerLink();
|
||||
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
|
||||
package org.geysermc.floodgate.command;
|
||||
|
||||
import cloud.commandframework.Command;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.platform.command.FloodgateCommand;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
|
||||
public class TestCommand implements FloodgateCommand {
|
||||
@Override
|
||||
@@ -43,10 +43,9 @@ public class TestCommand implements FloodgateCommand {
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext<UserAudience> context) {
|
||||
int players = FloodgateApi.getInstance().getPlayers().size();
|
||||
context.getSender().sendMessage(String.valueOf(players));
|
||||
context.sender().sendMessage(String.valueOf(players));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,10 +27,6 @@ package org.geysermc.floodgate.command;
|
||||
|
||||
import static org.geysermc.floodgate.command.CommonCommandMessage.CHECK_CONSOLE;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.Command;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import com.google.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -44,24 +40,27 @@ import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.player.UserAudience.PlayerAudience;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.command.util.Permission;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.description.Description;
|
||||
|
||||
@NoArgsConstructor
|
||||
public final class UnlinkAccountCommand implements FloodgateCommand {
|
||||
@Inject private FloodgateApi api;
|
||||
|
||||
@Override
|
||||
public Command<UserAudience> buildCommand(CommandManager<UserAudience> commandManager) {
|
||||
public Command<PlayerAudience> buildCommand(CommandManager<UserAudience> commandManager) {
|
||||
return commandManager.commandBuilder("unlinkaccount",
|
||||
ArgumentDescription.of("Unlink your Java account from your Bedrock account"))
|
||||
Description.of("Unlink your Java account from your Bedrock account"))
|
||||
.senderType(PlayerAudience.class)
|
||||
.permission(Permission.COMMAND_UNLINK.get())
|
||||
.handler(this::execute)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext<UserAudience> context) {
|
||||
UserAudience sender = context.getSender();
|
||||
public void execute(CommandContext<PlayerAudience> context) {
|
||||
UserAudience sender = context.sender();
|
||||
|
||||
PlayerLink link = api.getPlayerLink();
|
||||
|
||||
|
||||
@@ -27,10 +27,6 @@ package org.geysermc.floodgate.command;
|
||||
|
||||
import static org.geysermc.floodgate.command.CommonCommandMessage.CHECK_CONSOLE;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.Command;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.inject.Inject;
|
||||
@@ -46,10 +42,14 @@ import org.geysermc.floodgate.platform.command.FloodgateCommand;
|
||||
import org.geysermc.floodgate.platform.command.TranslatableMessage;
|
||||
import org.geysermc.floodgate.platform.util.PlayerType;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.player.audience.PlayerAudienceArgument;
|
||||
import org.geysermc.floodgate.player.audience.ProfileAudience;
|
||||
import org.geysermc.floodgate.player.audience.ProfileAudienceArgument;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.description.Description;
|
||||
|
||||
public class WhitelistCommand implements FloodgateCommand {
|
||||
@Inject private FloodgateConfig config;
|
||||
@@ -59,23 +59,23 @@ public class WhitelistCommand implements FloodgateCommand {
|
||||
@Override
|
||||
public Command<UserAudience> buildCommand(CommandManager<UserAudience> commandManager) {
|
||||
Command.Builder<UserAudience> builder = commandManager.commandBuilder("fwhitelist",
|
||||
ArgumentDescription.of("Easy way to whitelist Bedrock players"))
|
||||
Description.of("Easy way to whitelist Bedrock players"))
|
||||
.permission(Permission.COMMAND_WHITELIST.get());
|
||||
|
||||
commandManager.command(builder
|
||||
.literal("add", "a")
|
||||
.argument(ProfileAudienceArgument.of("player", true, true, PlayerType.ONLY_BEDROCK))
|
||||
.argument(PlayerAudienceArgument.ofAnyIdentifierBedrock("player"))
|
||||
.handler(context -> performCommand(context, true)));
|
||||
|
||||
return builder
|
||||
.literal("remove", "r")
|
||||
.argument(ProfileAudienceArgument.of("player", true, true, PlayerType.ONLY_BEDROCK))
|
||||
.argument(PlayerAudienceArgument.ofAnyIdentifierBedrock("player"))
|
||||
.handler(context -> performCommand(context, false))
|
||||
.build();
|
||||
}
|
||||
|
||||
public void performCommand(CommandContext<UserAudience> context, boolean add) {
|
||||
UserAudience sender = context.getSender();
|
||||
UserAudience sender = context.sender();
|
||||
ProfileAudience profile = context.get("player");
|
||||
UUID uuid = profile.uuid();
|
||||
String name = profile.username();
|
||||
@@ -114,7 +114,7 @@ public class WhitelistCommand implements FloodgateCommand {
|
||||
name = name.substring(config.getUsernamePrefix().length());
|
||||
}
|
||||
|
||||
if (name.length() < 1 || name.length() > 16) {
|
||||
if (name.isEmpty() || name.length() > 16) {
|
||||
sender.sendMessage(Message.INVALID_USERNAME);
|
||||
return;
|
||||
}
|
||||
@@ -181,11 +181,6 @@ public class WhitelistCommand implements FloodgateCommand {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext<UserAudience> context) {
|
||||
// ignored, all the logic is in the other method
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRegister(FloodgateConfig config) {
|
||||
// currently only Spigot (our only non-Proxy platform) has a whitelist build-in.
|
||||
|
||||
@@ -27,7 +27,6 @@ package org.geysermc.floodgate.command.main;
|
||||
|
||||
import static org.geysermc.floodgate.util.Constants.COLOR_CHAR;
|
||||
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.inject.Inject;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
@@ -41,6 +40,7 @@ import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
import org.geysermc.floodgate.util.HttpClient.HttpResponse;
|
||||
import org.geysermc.floodgate.util.Utils;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
|
||||
final class FirewallCheckSubcommand extends FloodgateSubCommand {
|
||||
@Inject
|
||||
@@ -63,7 +63,7 @@ final class FirewallCheckSubcommand extends FloodgateSubCommand {
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext<UserAudience> context) {
|
||||
UserAudience sender = context.getSender();
|
||||
UserAudience sender = context.sender();
|
||||
executeChecks(
|
||||
globalApiCheck(sender)
|
||||
).whenComplete((response, $) ->
|
||||
|
||||
@@ -27,17 +27,17 @@ package org.geysermc.floodgate.command.main;
|
||||
|
||||
import static org.geysermc.floodgate.util.Constants.COLOR_CHAR;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.Command;
|
||||
import cloud.commandframework.Command.Builder;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import java.util.Locale;
|
||||
import org.geysermc.floodgate.command.util.Permission;
|
||||
import org.geysermc.floodgate.platform.command.FloodgateCommand;
|
||||
import org.geysermc.floodgate.platform.command.FloodgateSubCommand;
|
||||
import org.geysermc.floodgate.platform.command.SubCommands;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.Command.Builder;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.description.Description;
|
||||
|
||||
public final class MainCommand extends SubCommands implements FloodgateCommand {
|
||||
public MainCommand() {
|
||||
@@ -49,14 +49,14 @@ public final class MainCommand extends SubCommands implements FloodgateCommand {
|
||||
public Command<UserAudience> buildCommand(CommandManager<UserAudience> commandManager) {
|
||||
Builder<UserAudience> builder = commandManager.commandBuilder(
|
||||
"floodgate",
|
||||
ArgumentDescription.of("A set of Floodgate related actions in one command"))
|
||||
Description.of("A set of Floodgate related actions in one command"))
|
||||
.senderType(UserAudience.class)
|
||||
.permission(Permission.COMMAND_MAIN.get())
|
||||
.handler(this::execute);
|
||||
|
||||
for (FloodgateSubCommand subCommand : subCommands()) {
|
||||
commandManager.command(builder
|
||||
.literal(subCommand.name().toLowerCase(Locale.ROOT), subCommand.description())
|
||||
.literal(subCommand.name().toLowerCase(Locale.ROOT), Description.of(subCommand.description()))
|
||||
.permission(subCommand.permission().get())
|
||||
.handler(subCommand::execute)
|
||||
);
|
||||
@@ -66,12 +66,11 @@ public final class MainCommand extends SubCommands implements FloodgateCommand {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext<UserAudience> context) {
|
||||
StringBuilder helpMessage = new StringBuilder("Available subcommands are:\n");
|
||||
|
||||
for (FloodgateSubCommand subCommand : subCommands()) {
|
||||
if (context.getSender().hasPermission(subCommand.permission().get())) {
|
||||
if (context.sender().hasPermission(subCommand.permission().get())) {
|
||||
helpMessage.append('\n').append(COLOR_CHAR).append('b')
|
||||
.append(subCommand.name().toLowerCase(Locale.ROOT))
|
||||
.append(COLOR_CHAR).append("f - ").append(COLOR_CHAR).append('7')
|
||||
@@ -79,6 +78,6 @@ public final class MainCommand extends SubCommands implements FloodgateCommand {
|
||||
}
|
||||
}
|
||||
|
||||
context.getSender().sendMessage(helpMessage.toString());
|
||||
context.sender().sendMessage(helpMessage.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ package org.geysermc.floodgate.command.main;
|
||||
|
||||
import static org.geysermc.floodgate.util.Constants.COLOR_CHAR;
|
||||
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
@@ -38,6 +37,7 @@ import org.geysermc.floodgate.platform.command.FloodgateSubCommand;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.util.Constants;
|
||||
import org.geysermc.floodgate.util.HttpClient;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
|
||||
public class VersionSubcommand extends FloodgateSubCommand {
|
||||
@Inject
|
||||
@@ -67,7 +67,7 @@ public class VersionSubcommand extends FloodgateSubCommand {
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext<UserAudience> context) {
|
||||
UserAudience sender = context.getSender();
|
||||
UserAudience sender = context.sender();
|
||||
sender.sendMessage(String.format(
|
||||
COLOR_CHAR + "7You're currently on " + COLOR_CHAR + "b%s" +
|
||||
COLOR_CHAR + "7 (branch: " + COLOR_CHAR + "b%s" + COLOR_CHAR + "7)\n" +
|
||||
|
||||
@@ -112,11 +112,6 @@ public abstract class CommandUtil {
|
||||
return usernames;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param uuid
|
||||
* @return
|
||||
*/
|
||||
public abstract Object getPlayerByUuid(@NonNull UUID uuid);
|
||||
|
||||
public Object getPlayerByUuid(@NonNull UUID uuid, PlayerType limitTo) {
|
||||
@@ -125,15 +120,15 @@ public abstract class CommandUtil {
|
||||
|
||||
public abstract Object getPlayerByUsername(@NonNull String username);
|
||||
|
||||
public Object getPlayerByUsername(@NonNull String username, PlayerType limitTo) {
|
||||
return applyPlayerTypeFilter(getPlayerByUsername(username), limitTo, username);
|
||||
public Object getPlayerByUsername(@NonNull String username, PlayerType filter) {
|
||||
return applyPlayerTypeFilter(getPlayerByUsername(username), filter, username);
|
||||
}
|
||||
|
||||
protected Object applyPlayerTypeFilter(Object player, PlayerType filter, Object fallback) {
|
||||
if (filter == ALL_PLAYERS || player instanceof String || player instanceof UUID) {
|
||||
return player;
|
||||
}
|
||||
return (filter == ONLY_BEDROCK) == api.isFloodgatePlayer(getUuidFromSource(player))
|
||||
return (filter == ONLY_BEDROCK) == api.isFloodgateId(getUuidFromSource(player))
|
||||
? player
|
||||
: fallback;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,10 @@
|
||||
|
||||
package org.geysermc.floodgate.platform.command;
|
||||
|
||||
import cloud.commandframework.Command;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
|
||||
/** The base class for every Floodgate command. */
|
||||
public interface FloodgateCommand {
|
||||
@@ -39,14 +38,7 @@ public interface FloodgateCommand {
|
||||
* @param commandManager the manager to create a command
|
||||
* @return the command to register
|
||||
*/
|
||||
Command<UserAudience> buildCommand(CommandManager<UserAudience> commandManager);
|
||||
|
||||
/**
|
||||
* Called when the command created in {@link #buildCommand(CommandManager)} is executed.
|
||||
*
|
||||
* @param context the context of the executed command
|
||||
*/
|
||||
void execute(CommandContext<UserAudience> context);
|
||||
Command<? extends UserAudience> buildCommand(CommandManager<UserAudience> commandManager);
|
||||
|
||||
/**
|
||||
* Called by the CommandRegister to check if the command should be added given the config.
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
|
||||
package org.geysermc.floodgate.platform.command;
|
||||
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import org.geysermc.floodgate.command.util.Permission;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
|
||||
public abstract class FloodgateSubCommand {
|
||||
public abstract String name();
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
|
||||
package org.geysermc.floodgate.player;
|
||||
|
||||
import cloud.commandframework.execution.preprocessor.CommandPreprocessingContext;
|
||||
import cloud.commandframework.execution.preprocessor.CommandPreprocessor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.incendo.cloud.execution.preprocessor.CommandPreprocessingContext;
|
||||
import org.incendo.cloud.execution.preprocessor.CommandPreprocessor;
|
||||
|
||||
/**
|
||||
* Command preprocessor which decorated incoming {@link cloud.commandframework.context.CommandContext}
|
||||
* Command preprocessor which decorated incoming {@link org.incendo.cloud.context.CommandContext}
|
||||
* with Floodgate specific objects
|
||||
*
|
||||
* @param <C> Command sender type
|
||||
@@ -44,6 +44,6 @@ public final class FloodgateCommandPreprocessor<C> implements CommandPreprocesso
|
||||
|
||||
@Override
|
||||
public void accept(@NonNull CommandPreprocessingContext<C> context) {
|
||||
context.getCommandContext().store("CommandUtil", commandUtil);
|
||||
context.commandContext().store("CommandUtil", commandUtil);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.player.audience;
|
||||
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.incendo.cloud.SenderMapper;
|
||||
|
||||
public class FloodgateSenderMapper<T> implements SenderMapper<T, UserAudience> {
|
||||
|
||||
private final CommandUtil commandUtil;
|
||||
|
||||
public FloodgateSenderMapper(CommandUtil commandUtil) {
|
||||
this.commandUtil = commandUtil;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull UserAudience map(@NonNull T base) {
|
||||
return this.commandUtil.getUserAudience(base);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public @NonNull T reverse(@NonNull UserAudience mapped) {
|
||||
return (T) mapped.source();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.player.audience;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public final class InvalidPlayerIdentifierException extends IllegalArgumentException {
|
||||
|
||||
public InvalidPlayerIdentifierException(@NonNull String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.player.audience;
|
||||
|
||||
import static org.incendo.cloud.parser.standard.StringParser.quotedStringParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.platform.util.PlayerType;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.util.BrigadierUtils;
|
||||
import org.incendo.cloud.component.CommandComponent;
|
||||
import org.incendo.cloud.parser.ArgumentParseResult;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
|
||||
public class PlayerAudienceArgument {
|
||||
|
||||
public static CommandComponent.Builder<UserAudience, ProfileAudience> ofAnyIdentifierBedrock(String name) {
|
||||
return of(name, true, true, PlayerType.ONLY_BEDROCK);
|
||||
}
|
||||
|
||||
public static CommandComponent.Builder<UserAudience, ProfileAudience> ofAnyUsernameBoth(String name) {
|
||||
return of(name, false, true, PlayerType.ALL_PLAYERS);
|
||||
}
|
||||
|
||||
private static CommandComponent.Builder<UserAudience, ProfileAudience> of(String name, boolean allowUuid, boolean allowOffline, PlayerType limitTo) {
|
||||
return CommandComponent.<UserAudience, ProfileAudience>builder()
|
||||
.name(name)
|
||||
.parser(quotedStringParser().flatMapSuccess(ProfileAudience.class,
|
||||
(context, input) -> {
|
||||
CommandUtil commandUtil = context.get("CommandUtil");
|
||||
|
||||
ProfileAudience profileAudience;
|
||||
if (input.length() > 16) {
|
||||
// This must be a UUID.
|
||||
if (!allowUuid) {
|
||||
return ArgumentParseResult.failureFuture(
|
||||
new InvalidPlayerIdentifierException(
|
||||
"UUID is not allowed here"));
|
||||
}
|
||||
|
||||
if (input.length() != 32 && input.length() != 36) {
|
||||
// Neither UUID without dashes nor with dashes.
|
||||
return ArgumentParseResult.failureFuture(
|
||||
new InvalidPlayerIdentifierException(
|
||||
"Expected player name/UUID"));
|
||||
}
|
||||
|
||||
try {
|
||||
// We only want to make sure the UUID is valid here.
|
||||
Object player = commandUtil.getPlayerByUuid(
|
||||
UUID.fromString(input), limitTo);
|
||||
profileAudience = commandUtil.getProfileAudience(player,
|
||||
allowOffline);
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
return ArgumentParseResult.failureFuture(
|
||||
new InvalidPlayerIdentifierException(
|
||||
"Invalid UUID '" + input + "'"));
|
||||
}
|
||||
} else {
|
||||
// This is a username.
|
||||
Object player = commandUtil.getPlayerByUsername(input, limitTo);
|
||||
profileAudience = commandUtil.getProfileAudience(player,
|
||||
allowOffline);
|
||||
}
|
||||
|
||||
if (profileAudience == null) {
|
||||
return ArgumentParseResult.failureFuture(
|
||||
new InvalidPlayerIdentifierException(
|
||||
"Invalid player '" + input + "'"));
|
||||
}
|
||||
|
||||
return ArgumentParseResult.successFuture(profileAudience);
|
||||
}))
|
||||
.suggestionProvider((context, input) -> {
|
||||
CommandUtil commandUtil = context.get("CommandUtil");
|
||||
|
||||
boolean quoted = input.remainingInput().startsWith("\"");
|
||||
List<Suggestion> suggestions = new ArrayList<Suggestion>();
|
||||
for (final String player : commandUtil.getOnlineUsernames(limitTo)) {
|
||||
suggestions.add(
|
||||
Suggestion.simple(BrigadierUtils.escapeIfRequired(player, quoted)));
|
||||
}
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 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/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.player.audience;
|
||||
|
||||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.platform.util.PlayerType;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
|
||||
public class ProfileAudienceArgument extends CommandArgument<UserAudience, ProfileAudience> {
|
||||
private ProfileAudienceArgument(@NonNull String name, ProfileAudienceParser parser) {
|
||||
super(true, name, parser, ProfileAudience.class);
|
||||
}
|
||||
|
||||
public static ProfileAudienceArgument of(
|
||||
String name,
|
||||
boolean allowUuid,
|
||||
boolean allowOffline,
|
||||
PlayerType limitTo) {
|
||||
return new ProfileAudienceArgument(name,
|
||||
new ProfileAudienceParser(allowUuid, allowOffline, limitTo));
|
||||
}
|
||||
|
||||
public static ProfileAudienceArgument of(
|
||||
String name,
|
||||
boolean allowOffline,
|
||||
PlayerType limitTo) {
|
||||
return of(name, false, allowOffline, limitTo);
|
||||
}
|
||||
|
||||
public static ProfileAudienceArgument ofOnline(String name, PlayerType limitTo) {
|
||||
return of(name, false, false, limitTo);
|
||||
}
|
||||
|
||||
public static ProfileAudienceArgument ofOnline(String name, boolean allowUuid) {
|
||||
return of(name, allowUuid, false, PlayerType.ALL_PLAYERS);
|
||||
}
|
||||
|
||||
public static CommandArgument<UserAudience, ProfileAudience> ofOnline(String name) {
|
||||
return of(name, false, false, PlayerType.ALL_PLAYERS);
|
||||
}
|
||||
|
||||
public static ProfileAudienceArgument of(String name, boolean allowOffline) {
|
||||
return of(name, false, allowOffline, PlayerType.ALL_PLAYERS);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static final class ProfileAudienceParser
|
||||
implements ArgumentParser<UserAudience, ProfileAudience> {
|
||||
|
||||
private final boolean allowUuid;
|
||||
private final boolean allowOffline;
|
||||
private final PlayerType limitTo;
|
||||
|
||||
@Override
|
||||
public @NonNull ArgumentParseResult<ProfileAudience> parse(
|
||||
@NonNull CommandContext<@NonNull UserAudience> commandContext,
|
||||
@NonNull Queue<@NonNull String> inputQueue) {
|
||||
CommandUtil commandUtil = commandContext.get("CommandUtil");
|
||||
|
||||
String input = inputQueue.poll();
|
||||
if (input == null || input.length() < 3) {
|
||||
return ArgumentParseResult.failure(
|
||||
new NullPointerException("Expected player name/UUID"));
|
||||
}
|
||||
|
||||
if (input.startsWith("\"")) {
|
||||
if (input.endsWith("\"")) {
|
||||
// Remove quotes from both sides of this string
|
||||
input = input.substring(1);
|
||||
input = input.substring(0, input.length() - 1);
|
||||
} else {
|
||||
// Multi-line
|
||||
StringBuilder builder = new StringBuilder(input);
|
||||
while (!inputQueue.isEmpty()) {
|
||||
String string = inputQueue.remove();
|
||||
builder.append(' ').append(string);
|
||||
if (string.endsWith("\"")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (builder.lastIndexOf("\"") != builder.length() - 1) {
|
||||
return ArgumentParseResult.failure(
|
||||
new InvalidPlayerIdentifierException("Malformed string provided; " +
|
||||
"no end quotes found!"));
|
||||
}
|
||||
|
||||
builder.deleteCharAt(0);
|
||||
builder.deleteCharAt(builder.length() - 1);
|
||||
input = builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
ProfileAudience profileAudience;
|
||||
|
||||
if (input.length() > 16) {
|
||||
// This must be a UUID.
|
||||
if (!allowUuid) {
|
||||
return ArgumentParseResult.failure(
|
||||
new InvalidPlayerIdentifierException("UUID is not allowed here"));
|
||||
}
|
||||
|
||||
if (input.length() != 32 && input.length() != 36) {
|
||||
// Neither UUID without dashes nor with dashes.
|
||||
return ArgumentParseResult.failure(
|
||||
new InvalidPlayerIdentifierException("Expected player name/UUID"));
|
||||
}
|
||||
|
||||
try {
|
||||
// We only want to make sure the UUID is valid here.
|
||||
Object player = commandUtil.getPlayerByUuid(UUID.fromString(input), limitTo);
|
||||
profileAudience = commandUtil.getProfileAudience(player, allowOffline);
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
return ArgumentParseResult.failure(
|
||||
new InvalidPlayerIdentifierException("Invalid UUID '" + input + "'"));
|
||||
}
|
||||
} else {
|
||||
// This is a username.
|
||||
Object player = commandUtil.getPlayerByUsername(input, limitTo);
|
||||
profileAudience = commandUtil.getProfileAudience(player, allowOffline);
|
||||
}
|
||||
|
||||
if (profileAudience == null) {
|
||||
return ArgumentParseResult.failure(
|
||||
new InvalidPlayerIdentifierException("Invalid player '" + input + "'"));
|
||||
}
|
||||
|
||||
return ArgumentParseResult.success(profileAudience);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull List<String> suggestions(
|
||||
@NonNull CommandContext<UserAudience> commandContext,
|
||||
@NonNull String input) {
|
||||
CommandUtil commandUtil = commandContext.get("CommandUtil");
|
||||
String trimmedInput = input.trim();
|
||||
|
||||
if (trimmedInput.isEmpty()) {
|
||||
return ImmutableList.copyOf(commandUtil.getOnlineUsernames(limitTo));
|
||||
}
|
||||
|
||||
String lowercaseInput = input.toLowerCase(Locale.ROOT);
|
||||
ImmutableList.Builder<String> builder = ImmutableList.builder();
|
||||
|
||||
for (final String player : commandUtil.getOnlineUsernames(limitTo)) {
|
||||
if (player.toLowerCase(Locale.ROOT).startsWith(lowercaseInput)) {
|
||||
builder.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContextFree() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class InvalidPlayerIdentifierException extends IllegalArgumentException {
|
||||
private static final long serialVersionUID = -6500019324607183855L;
|
||||
|
||||
public InvalidPlayerIdentifierException(@NonNull String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
package org.geysermc.floodgate.register;
|
||||
|
||||
import cloud.commandframework.CommandManager;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
@@ -33,6 +32,7 @@ import java.util.Set;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.platform.command.FloodgateCommand;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
|
||||
/**
|
||||
* This class is responsible for registering commands to the command register of the platform that
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
/*
|
||||
Code taken from Brigadier's StringArgumentType and StringReader
|
||||
*/
|
||||
public final class BrigadierUtils {
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public static boolean isAllowedInUnquotedString(char c) {
|
||||
return c >= '0' && c <= '9' ||
|
||||
c >= 'A' && c <= 'Z' ||
|
||||
c >= 'a' && c <= 'z' ||
|
||||
c == '_' || c == '-' ||
|
||||
c == '.' || c == '+';
|
||||
}
|
||||
|
||||
public static String escapeIfRequired(String input, boolean quoted) {
|
||||
if (quoted) {
|
||||
return escape(input);
|
||||
}
|
||||
|
||||
for (final char c : input.toCharArray()) {
|
||||
if (!isAllowedInUnquotedString(c)) {
|
||||
return "\"" + input + "\"";
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
private static String escape(final String input) {
|
||||
final StringBuilder result = new StringBuilder("\"");
|
||||
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
final char c = input.charAt(i);
|
||||
if (c == '\\' || c == '"') {
|
||||
result.append('\\');
|
||||
}
|
||||
result.append(c);
|
||||
}
|
||||
|
||||
result.append("\"");
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,4 @@ org.gradle.configureondemand=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
|
||||
version=2.2.2-SNAPSHOT
|
||||
version=2.2.3-SNAPSHOT
|
||||
@@ -13,7 +13,9 @@ indra {
|
||||
dependencies {
|
||||
api(projects.core)
|
||||
|
||||
implementation("cloud.commandframework", "cloud-bukkit", Versions.cloudVersion)
|
||||
// TODO move to release once cloud-paper releases for 1.20.5
|
||||
// https://repo.papermc.io/#browse/browse:maven-public:org%2Fincendo%2Fcloud-paper%2F2.0.0-SNAPSHOT%2F2.0.0-20240427.220226-58
|
||||
implementation("org.incendo", "cloud-paper", "2.0.0-20240427.220226-58")
|
||||
// hack to make pre 1.12 work
|
||||
implementation("com.google.guava", "guava", guavaVersion)
|
||||
|
||||
@@ -26,7 +28,7 @@ dependencies {
|
||||
|
||||
relocate("com.google.inject")
|
||||
relocate("net.kyori")
|
||||
relocate("cloud.commandframework")
|
||||
relocate("org.incendo.cloud")
|
||||
relocate("io.leangen.geantyref") // used in cloud
|
||||
// hack to make pre 1.12 work
|
||||
relocate("com.google.common")
|
||||
|
||||
@@ -25,15 +25,11 @@
|
||||
|
||||
package org.geysermc.floodgate.module;
|
||||
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.bukkit.BukkitCommandManager;
|
||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.geysermc.floodgate.SpigotPlugin;
|
||||
@@ -41,6 +37,10 @@ import org.geysermc.floodgate.command.util.Permission;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.player.FloodgateCommandPreprocessor;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.player.audience.FloodgateSenderMapper;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.execution.ExecutionCoordinator;
|
||||
import org.incendo.cloud.paper.PaperCommandManager;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class SpigotCommandModule extends CommandModule {
|
||||
@@ -56,11 +56,10 @@ public final class SpigotCommandModule extends CommandModule {
|
||||
@Singleton
|
||||
@SneakyThrows
|
||||
public CommandManager<UserAudience> commandManager(CommandUtil commandUtil) {
|
||||
CommandManager<UserAudience> commandManager = new BukkitCommandManager<>(
|
||||
CommandManager<UserAudience> commandManager = new PaperCommandManager<>(
|
||||
plugin,
|
||||
CommandExecutionCoordinator.simpleCoordinator(),
|
||||
commandUtil::getUserAudience,
|
||||
audience -> (CommandSender) audience.source()
|
||||
ExecutionCoordinator.simpleCoordinator(),
|
||||
new FloodgateSenderMapper<>(commandUtil)
|
||||
);
|
||||
commandManager.registerCommandPreProcessor(new FloodgateCommandPreprocessor<>(commandUtil));
|
||||
return commandManager;
|
||||
|
||||
@@ -12,10 +12,10 @@ indra {
|
||||
|
||||
dependencies {
|
||||
api(projects.core)
|
||||
implementation("cloud.commandframework", "cloud-velocity", Versions.cloudVersion)
|
||||
implementation("org.incendo", "cloud-velocity", Versions.cloudVersion)
|
||||
}
|
||||
|
||||
relocate("cloud.commandframework")
|
||||
relocate("org.incendo.cloud")
|
||||
// used in cloud
|
||||
relocate("io.leangen.geantyref")
|
||||
|
||||
|
||||
@@ -25,17 +25,12 @@
|
||||
|
||||
package org.geysermc.floodgate.module;
|
||||
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||
import cloud.commandframework.velocity.CloudInjectionModule;
|
||||
import cloud.commandframework.velocity.VelocityCommandManager;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.event.EventManager;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -51,6 +46,7 @@ import org.geysermc.floodgate.platform.pluginmessage.PluginMessageUtils;
|
||||
import org.geysermc.floodgate.platform.util.PlatformUtils;
|
||||
import org.geysermc.floodgate.player.FloodgateCommandPreprocessor;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.player.audience.FloodgateSenderMapper;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageRegistration;
|
||||
import org.geysermc.floodgate.pluginmessage.VelocityPluginMessageRegistration;
|
||||
@@ -59,6 +55,10 @@ import org.geysermc.floodgate.skin.SkinApplier;
|
||||
import org.geysermc.floodgate.util.VelocityCommandUtil;
|
||||
import org.geysermc.floodgate.util.VelocityPlatformUtils;
|
||||
import org.geysermc.floodgate.util.VelocitySkinApplier;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.execution.ExecutionCoordinator;
|
||||
import org.incendo.cloud.velocity.CloudInjectionModule;
|
||||
import org.incendo.cloud.velocity.VelocityCommandManager;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class VelocityPlatformModule extends AbstractModule {
|
||||
@@ -77,9 +77,8 @@ public final class VelocityPlatformModule extends AbstractModule {
|
||||
public CommandManager<UserAudience> commandManager(CommandUtil commandUtil) {
|
||||
Injector child = guice.createChildInjector(new CloudInjectionModule<>(
|
||||
UserAudience.class,
|
||||
CommandExecutionCoordinator.simpleCoordinator(),
|
||||
commandUtil::getUserAudience,
|
||||
audience -> (CommandSource) audience.source()
|
||||
ExecutionCoordinator.simpleCoordinator(),
|
||||
new FloodgateSenderMapper<>(commandUtil)
|
||||
));
|
||||
|
||||
CommandManager<UserAudience> commandManager =
|
||||
|
||||
Reference in New Issue
Block a user