mirror of
https://github.com/FancyInnovations/FancyPlugins.git
synced 2025-12-06 07:43:36 +00:00
fancydialogs: Setup cloud command manager
This commit is contained in:
@@ -55,6 +55,10 @@ dependencies {
|
||||
implementation("de.oliver.FancyAnalytics:logger:0.0.6")
|
||||
|
||||
compileOnly("org.lushplugins:ChatColorHandler:5.1.3")
|
||||
implementation("org.incendo:cloud-core:2.1.0-SNAPSHOT")
|
||||
implementation("org.incendo:cloud-paper:2.0.0-SNAPSHOT")
|
||||
implementation("org.incendo:cloud-annotations:2.1.0-SNAPSHOT")
|
||||
annotationProcessor("org.incendo:cloud-annotations:2.1.0-SNAPSHOT")
|
||||
|
||||
implementation("org.jetbrains:annotations:24.0.0")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.fancyinnovations.fancydialogs;
|
||||
|
||||
import com.fancyinnovations.fancydialogs.api.Dialog;
|
||||
import com.fancyinnovations.fancydialogs.commands.CloudCommandManager;
|
||||
import com.fancyinnovations.fancydialogs.config.FancyDialogsConfig;
|
||||
import com.fancyinnovations.fancydialogs.listener.PlayerJoinListener;
|
||||
import com.fancyinnovations.fancydialogs.registry.DialogRegistry;
|
||||
@@ -92,6 +93,11 @@ public class FancyDialogsPlugin extends JavaPlugin {
|
||||
|
||||
registerListeners();
|
||||
|
||||
new CloudCommandManager(this, false)
|
||||
.registerArguments()
|
||||
.registerExceptionHandlers()
|
||||
.registerCommands();
|
||||
|
||||
fancyLogger.info("Successfully enabled FancyDialogs version %s".formatted(getDescription().getVersion()));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.fancyinnovations.fancydialogs.commands;
|
||||
|
||||
import com.fancyinnovations.fancydialogs.FancyDialogsPlugin;
|
||||
import de.oliver.fancylib.translations.Translator;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.annotations.AnnotationParser;
|
||||
import org.incendo.cloud.bukkit.CloudBukkitCapabilities;
|
||||
import org.incendo.cloud.bukkit.parser.WorldParser;
|
||||
import org.incendo.cloud.bukkit.parser.location.LocationParser;
|
||||
import org.incendo.cloud.exception.ArgumentParseException;
|
||||
import org.incendo.cloud.exception.InvalidCommandSenderException;
|
||||
import org.incendo.cloud.exception.NoPermissionException;
|
||||
import org.incendo.cloud.exception.handling.ExceptionHandlerRegistration;
|
||||
import org.incendo.cloud.exception.parsing.NumberParseException;
|
||||
import org.incendo.cloud.exception.parsing.ParserException;
|
||||
import org.incendo.cloud.execution.ExecutionCoordinator;
|
||||
import org.incendo.cloud.paper.LegacyPaperCommandManager;
|
||||
import org.incendo.cloud.parser.standard.BooleanParser;
|
||||
import org.incendo.cloud.parser.standard.EnumParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static org.incendo.cloud.exception.handling.ExceptionHandler.unwrappingHandler;
|
||||
|
||||
public class CloudCommandManager {
|
||||
|
||||
private final @NotNull FancyDialogsPlugin plugin;
|
||||
|
||||
private final @NotNull LegacyPaperCommandManager<CommandSender> commandManager;
|
||||
private final @NotNull AnnotationParser<CommandSender> annotationParser;
|
||||
|
||||
public CloudCommandManager(final @NotNull FancyDialogsPlugin plugin, final boolean isBrigadier) {
|
||||
this.plugin = plugin;
|
||||
// Creating instance of Cloud's LegacyPaperCommandManager, which is used for anything command-related.
|
||||
this.commandManager = LegacyPaperCommandManager.createNative(plugin, ExecutionCoordinator.simpleCoordinator());
|
||||
// Registering Brigadier, if available.
|
||||
if (isBrigadier && commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER))
|
||||
commandManager.registerBrigadier();
|
||||
// Creating instance of AnnotationParser, which is used for parsing and registering commands.
|
||||
this.annotationParser = new AnnotationParser<>(commandManager, CommandSender.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers arguments (parsers and suggestion providers) to the {@link LegacyPaperCommandManager}.
|
||||
*/
|
||||
public @NotNull CloudCommandManager registerArguments() {
|
||||
// annotationParser.parse(NpcArgument.INSTANCE);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers exception handlers to the {@link LegacyPaperCommandManager}.
|
||||
*/
|
||||
public @NotNull CloudCommandManager registerExceptionHandlers() {
|
||||
final Translator translator = plugin.getTranslator();
|
||||
// Unwrapping some causes of ArgumentParseException to be handled in standalone exception handlers.
|
||||
commandManager.exceptionController().registerHandler(ArgumentParseException.class, unwrappingHandler(NumberParseException.class));
|
||||
commandManager.exceptionController().registerHandler(ArgumentParseException.class, unwrappingHandler(BooleanParser.BooleanParseException.class));
|
||||
commandManager.exceptionController().registerHandler(ArgumentParseException.class, unwrappingHandler(EnumParser.EnumParseException.class));
|
||||
commandManager.exceptionController().registerHandler(ArgumentParseException.class, unwrappingHandler(WorldParser.WorldParseException.class));
|
||||
// Overriding some default handlers to send specialized messages.
|
||||
commandManager.exceptionController().registerHandler(NoPermissionException.class, (exceptionContext) -> {
|
||||
translator.translate("command_missing_permissions").send(exceptionContext.context().sender());
|
||||
});
|
||||
// DEV NOTE: No need to compare sender types until we decide to make a console-only command. Should get the job done for the time being.
|
||||
commandManager.exceptionController().registerHandler(InvalidCommandSenderException.class, (exceptionContext) -> {
|
||||
translator.translate("command_player_only").send(exceptionContext.context().sender());
|
||||
});
|
||||
commandManager.exceptionController().registerHandler(NumberParseException.class, (exceptionContext) -> {
|
||||
translator.translate("command_invalid_number")
|
||||
.replaceStripped("input", exceptionContext.exception().input())
|
||||
.replace("min", exceptionContext.exception().range().min().toString())
|
||||
.replace("max", exceptionContext.exception().range().max().toString())
|
||||
.send(exceptionContext.context().sender());
|
||||
});
|
||||
commandManager.exceptionController().registerHandler(BooleanParser.BooleanParseException.class, (exceptionContext) -> {
|
||||
translator.translate("command_invalid_boolean")
|
||||
.replaceStripped("input", exceptionContext.exception().input())
|
||||
.send(exceptionContext.context().sender());
|
||||
});
|
||||
commandManager.exceptionController().registerHandler(WorldParser.WorldParseException.class, (exceptionContext) -> {
|
||||
translator.translate("command_invalid_world")
|
||||
.replaceStripped("input", exceptionContext.exception().input())
|
||||
.send(exceptionContext.context().sender());
|
||||
});
|
||||
// DEV NOTE: Temporary solution until https://github.com/Incendo/cloud-minecraft/pull/70 is merged.
|
||||
commandManager.exceptionController().register(ExceptionHandlerRegistration.<CommandSender, ArgumentParseException>builder(TypeToken.get(ArgumentParseException.class))
|
||||
.exceptionFilter(exception -> exception.getCause() instanceof ParserException parserException && parserException.argumentParserClass() == LocationParser.class)
|
||||
.exceptionHandler(exceptionContext -> {
|
||||
final ParserException exception = (ParserException) exceptionContext.exception().getCause();
|
||||
final String input = exception.captionVariables()[0].value(); // Should never throw.
|
||||
translator.translate("command_invalid_location")
|
||||
.replaceStripped("input", !input.isBlank() ? input : "N/A") // Under certain conditions, input is not passed to the exception.
|
||||
.send(exceptionContext.context().sender());
|
||||
}).build()
|
||||
);
|
||||
// commandManager.exceptionController().registerHandler(EnumParser.EnumParseException.class, (exceptionContext) -> {
|
||||
// String translationKey = "command_invalid_enum_generic";
|
||||
// // Comparing exception enum class and choosing specialized messages.
|
||||
// if (exceptionContext.exception().enumClass() == ListCMD.SortType.class)
|
||||
// translationKey = "command_invalid_list_sort_type";
|
||||
// else if (exceptionContext.exception().enumClass() == NearbyCMD.SortType.class)
|
||||
// translationKey = "command_invalid_nearby_sort_type";
|
||||
// else if (exceptionContext.exception().enumClass() == EntityType.class)
|
||||
// translationKey = "command_invalid_entity_type";
|
||||
// else if (exceptionContext.exception().enumClass() == GlowingColor.class)
|
||||
// translationKey = "command_invalid_glowing_color";
|
||||
// // Sending error message to the sender. In case no specialized message has been found, a generic one is used instead.
|
||||
// translator.translate(translationKey)
|
||||
// .replaceStripped("input", exceptionContext.exception().input())
|
||||
// .replace("enum", exceptionContext.exception().enumClass().getSimpleName().toLowerCase())
|
||||
// .send(exceptionContext.context().sender());
|
||||
// });
|
||||
// // ReplyingParseException is thrown from custom argument types and is handled there.
|
||||
// commandManager.exceptionController().registerHandler(ReplyingParseException.class, context -> context.exception().runnable().run());
|
||||
// // InvalidSyntaxException is thrown when user specified syntax don't match any command.
|
||||
// commandManager.exceptionController().registerHandler(InvalidSyntaxException.class, (exceptionContext) -> {
|
||||
// // Creating a StringBuilder which is then appended with (known/existing) command literals.
|
||||
// final StringBuilder translationKeyBuilder = new StringBuilder("command_syntax.");
|
||||
// // Iterating over current command chain and appending literals, as described above.
|
||||
// exceptionContext.exception().currentChain().stream()
|
||||
// .filter(c -> c.type() == CommandComponent.ComponentType.LITERAL)
|
||||
// .forEach(literal -> translationKeyBuilder.append(literal.name()).append(' '));
|
||||
// // Trimming input (last character ends up being blank) and replacing whitespaces with underscores, as that's how translations are defined inside the language file.
|
||||
// final String translationKey = translationKeyBuilder.toString().trim().replace(' ', '_');
|
||||
// // Getting the message, it's not finished as there we need to handle fallback language etc.
|
||||
// final @Nullable Message message = Optional.ofNullable(plugin.getTranslator().getSelectedLanguage().getMessage(translationKey))
|
||||
// .orElse(plugin.getTranslator().getFallbackLanguage().getMessage(translationKey));
|
||||
// // "Fall-backing" to generic syntax error, if no specialized syntax message has been defined in the language file.
|
||||
// if (message == null) {
|
||||
// plugin.getTranslator().translate("command_invalid_syntax_generic")
|
||||
// .replace("syntax", exceptionContext.exception().correctSyntax())
|
||||
// .send(exceptionContext.context().sender());
|
||||
// return;
|
||||
// }
|
||||
// message.send(exceptionContext.context().sender());
|
||||
// });
|
||||
// Returning this instance of CloudCommandManager to keep "builder-like" flow.
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers plugin commands to the {@link LegacyPaperCommandManager}.
|
||||
*/
|
||||
public @NotNull CloudCommandManager registerCommands() {
|
||||
// annotationParser.parse(AttributeCMD.INSTANCE);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internal {@link LegacyPaperCommandManager} associated with this instance of {@link CloudCommandManager}.
|
||||
*/
|
||||
public @NotNull LegacyPaperCommandManager<CommandSender> getCommandManager() {
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internal {@link AnnotationParser} associated with this instance of {@link CloudCommandManager}.
|
||||
*/
|
||||
public @NotNull AnnotationParser<CommandSender> getAnnotationParser() {
|
||||
return annotationParser;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user