From 36a13443db39d17bca65e022390bfc7c36236c30 Mon Sep 17 00:00:00 2001 From: kento2 Date: Sat, 21 Feb 2026 00:43:28 +0100 Subject: [PATCH] commands work but i think ill refactor --- build.gradle.kts | 3 - core-bukkit-api/build.gradle.kts | 7 -- ...CommandReader.java => ArgumentReader.java} | 4 +- .../services/command/CommandArgument.java | 16 ---- .../services/command/CommandExecutor.java | 2 +- .../services/command/CommandManager.java | 4 +- .../command/cmds2/CommandArgument.java | 10 ++- .../{context => cmds2}/CommandContext.java | 16 ++-- .../command/cmds2/CommandFactory.java | 16 ++++ .../services/command/cmds2/Commands.java | 41 +++++++++ .../command/cmds2/SuggestionProvider.java | 2 - .../cmds2/node/ArgumentCommandNode.java | 14 --- .../command/cmds2/node/CommandNode.java | 24 ------ .../services/command/cmds2/node/Literal.java | 43 ++++++++++ .../cmds2/node/LiteralCommandNode.java | 10 --- ...{RootCommandNode.java => RootLiteral.java} | 2 +- ...n.java => CommandInvocationException.java} | 6 +- .../services/command/node/CommandNode.java | 51 ----------- .../command/node/CommandNodeFactory.java | 10 --- .../command/node/CommandNodeRepository.java | 24 ------ .../node/CommandNodeWithArguments.java | 34 -------- .../node/CommandNodeWithSubCommand.java | 20 ----- .../services/command/type/ArgumentType.java | 12 +-- .../command/type/EntityArgumentType.java | 47 ---------- .../command/type/NumberArgumentType.java | 43 ++++++++++ .../command/type/PlayerArgumentType.java | 79 +++++++++++++++++ .../bukkit/util/command/PlayerArgument.java | 30 ------- .../kentoj/scrow/bukkit/CoreImplPlugin.java | 4 +- .../kentoj/scrow/bukkit/ScrowAPISurface.java | 8 +- .../scrow/bukkit/cmds2/BukkitCommand.java | 57 ------------ .../scrow/bukkit/cmds2/CoinsCommand.java | 53 ------------ .../bukkit/cmds2/CommandContextImpl.java | 39 +++++++++ .../bukkit/cmds2/CommandFactoryImpl.java | 31 +++++++ .../bukkit => cmds2}/CommandManagerImpl.java | 20 ++--- .../cmds2/parsing/ArgumentReaderImpl.java | 62 +++++++++++++ .../bukkit/cmds2/parsing/BukkitCommand.java | 36 ++++++++ .../cmds2/parsing/BukkitTabCompleter.java | 23 +++++ .../cmds2/parsing/CommandProcessor.java | 67 +++++++++++++++ .../cmds2/types/CommandArgumentImpl.java | 34 ++++++++ .../scrow/bukkit/cmds2/types/LiteralImpl.java | 58 +++++++++++++ .../bukkit/cmds2/types/RootLiteralImpl.java | 25 ++++++ .../bukkit/command/CommandContextImpl.java | 25 ------ .../command/CommandExecutionContextImpl.java | 48 ----------- .../bukkit/command/bukkit/ArgumentData.java | 11 --- .../bukkit/command/bukkit/BukkitCommand.java | 34 -------- .../command/bukkit/CommandProcessor.java | 62 ------------- .../command/node/CommandNodeFactoryImpl.java | 23 ----- .../bukkit/command/node/CommandNodeImpl.java | 36 -------- .../node/CommandNodeWithArgumentsImpl.java | 50 ----------- .../node/CommandNodeWithSubCommandImpl.java | 32 ------- .../bukkit/economy/MongoEconomyService.java | 1 + .../bukkit/economy/command/CoinsCommand.java | 86 +++++++++++++++++++ .../bukkit/friends/command/FriendCommand.java | 13 --- .../bukkit/friends/command/LaunchCommand.java | 30 ------- 54 files changed, 726 insertions(+), 812 deletions(-) rename core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/{CommandReader.java => ArgumentReader.java} (70%) delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandArgument.java rename core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/{context => cmds2}/CommandContext.java (52%) create mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandFactory.java create mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/Commands.java delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/ArgumentCommandNode.java delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/CommandNode.java create mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/Literal.java delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/LiteralCommandNode.java rename core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/{RootCommandNode.java => RootLiteral.java} (70%) rename core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/exception/{CommandSyntaxException.java => CommandInvocationException.java} (68%) delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNode.java delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeFactory.java delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeRepository.java delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeWithArguments.java delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeWithSubCommand.java delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/EntityArgumentType.java create mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/NumberArgumentType.java create mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/PlayerArgumentType.java delete mode 100644 core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/util/command/PlayerArgument.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/BukkitCommand.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CoinsCommand.java create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandContextImpl.java create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandFactoryImpl.java rename core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/{command/bukkit => cmds2}/CommandManagerImpl.java (56%) create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/ArgumentReaderImpl.java create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/BukkitCommand.java create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/BukkitTabCompleter.java create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/CommandProcessor.java create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/CommandArgumentImpl.java create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/LiteralImpl.java create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/RootLiteralImpl.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/CommandContextImpl.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/CommandExecutionContextImpl.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/ArgumentData.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/BukkitCommand.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/CommandProcessor.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeFactoryImpl.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeImpl.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeWithArgumentsImpl.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeWithSubCommandImpl.java create mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsCommand.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java delete mode 100644 core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/LaunchCommand.java diff --git a/build.gradle.kts b/build.gradle.kts index deb6ac1..41dd70c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,9 +19,6 @@ subprojects { maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") { name = "spigotmc-repo" } - maven("https://libraries.minecraft.net") { - name = "Minecraft Libraries" - } } dependencies { diff --git a/core-bukkit-api/build.gradle.kts b/core-bukkit-api/build.gradle.kts index 3fbeb64..56c737d 100644 --- a/core-bukkit-api/build.gradle.kts +++ b/core-bukkit-api/build.gradle.kts @@ -18,17 +18,10 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter") testRuntimeOnly("org.junit.platform:junit-platform-launcher") - api("me.lucko:commodore:2.2") api("org.spigotmc:spigot-api:1.21.11-R0.1-SNAPSHOT") api("net.kyori:adventure-platform-bukkit:4.4.1") } -tasks.findByName("shadowJar")?.let { - dependencies { - "exclude"("dependency"("com.mojang.brigadier")!!) - } -} - publishing { publications { create("CoreBukkitApi") { diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandReader.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/ArgumentReader.java similarity index 70% rename from core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandReader.java rename to core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/ArgumentReader.java index 1554289..fc4d803 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandReader.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/ArgumentReader.java @@ -1,12 +1,12 @@ package de.kentoj.scrow.bukkit.services.command; -public interface CommandReader { +public interface ArgumentReader { boolean isEOF(); String readWord(); - String readQuotedString(); + String readQuotedWord(); int getCursor(); diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandArgument.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandArgument.java deleted file mode 100644 index 082a2cb..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandArgument.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command; - -import de.kentoj.scrow.bukkit.services.command.type.ArgumentType; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import lombok.Value; - -import java.util.function.Function; - -// TODO convert to interface -@Value -public class CommandArgument { - int index; - String name; - ArgumentType type; - Function defaultValue; -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandExecutor.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandExecutor.java index 3421389..e6248b4 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandExecutor.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandExecutor.java @@ -1,6 +1,6 @@ package de.kentoj.scrow.bukkit.services.command; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandContext; public interface CommandExecutor { diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandManager.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandManager.java index 19480f8..b2dee80 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandManager.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/CommandManager.java @@ -1,9 +1,9 @@ package de.kentoj.scrow.bukkit.services.command; -import de.kentoj.scrow.bukkit.services.command.node.CommandNode; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; import org.bukkit.plugin.Plugin; public interface CommandManager { - void register(CommandNode rootCommandNode, Plugin plugin); + void register(RootLiteral rootLiteral, Plugin plugin); } diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandArgument.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandArgument.java index 70029d2..b0d31ec 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandArgument.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandArgument.java @@ -1,12 +1,20 @@ package de.kentoj.scrow.bukkit.services.command.cmds2; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; import de.kentoj.scrow.bukkit.services.command.type.ArgumentType; import org.jetbrains.annotations.Nullable; public interface CommandArgument { + String getName(); + ArgumentType getType(); @Nullable T getDefaultValue(CommandContext ctx); + + void setSuggestionProvider(@Nullable SuggestionProvider suggestionProvider); + + /** + * @return the explicitly set SuggestionProvider or the suggestions for the type if unset/null + */ + SuggestionProvider getSuggestionProvider(); } diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/context/CommandContext.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandContext.java similarity index 52% rename from core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/context/CommandContext.java rename to core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandContext.java index dc50762..21f35de 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/context/CommandContext.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandContext.java @@ -1,10 +1,9 @@ -package de.kentoj.scrow.bukkit.services.command.context; +package de.kentoj.scrow.bukkit.services.command.cmds2; -import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException; +import de.kentoj.scrow.bukkit.services.command.exception.CommandInvocationException; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import org.jetbrains.annotations.Nullable; public interface CommandContext { @@ -16,12 +15,11 @@ public interface CommandContext { /** * @return Object that is parsed from the raw argument - * @throws CommandSyntaxException if no value given and no default value supplied + * @throws CommandInvocationException if no value given and no default value supplied */ - T getArg(String key); + T getArg(String name); - /** - * @return string argument used at invocation - */ - @Nullable String getRawArgument(String key); + default T getArg(CommandArgument arg) { + return getArg(arg.getName()); + } } diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandFactory.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandFactory.java new file mode 100644 index 0000000..e5b46d2 --- /dev/null +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/CommandFactory.java @@ -0,0 +1,16 @@ +package de.kentoj.scrow.bukkit.services.command.cmds2; + +import de.kentoj.scrow.bukkit.services.command.cmds2.node.Literal; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; +import de.kentoj.scrow.bukkit.services.command.type.ArgumentType; + +import java.util.function.Function; + +public interface CommandFactory { + + Literal literal(String name); + + RootLiteral root(String name); + + CommandArgument argument(String name, ArgumentType type, Function defaultValueFun); +} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/Commands.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/Commands.java new file mode 100644 index 0000000..dbeb3d0 --- /dev/null +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/Commands.java @@ -0,0 +1,41 @@ +package de.kentoj.scrow.bukkit.services.command.cmds2; + +import de.kentoj.scrow.bukkit.services.command.cmds2.node.Literal; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; +import de.kentoj.scrow.bukkit.services.command.type.ArgumentType; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.jetbrains.annotations.ApiStatus; + +import java.util.function.Function; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class Commands { + + private static CommandFactory factory; + + public static Literal literal(String name) { + return factory.literal(name); + } + + public static RootLiteral root(String name) { + return factory.root(name); + } + + public static CommandArgument argument0(String name, ArgumentType type, Function defaultValueFun) { + return factory.argument(name, type, defaultValueFun); + } + + public static CommandArgument argument1(String name, ArgumentType type, T defaultValue) { + return factory.argument(name, type, __ -> defaultValue); + } + + public static CommandArgument argument0(String name, ArgumentType type) { + return factory.argument(name, type, __ -> null); + } + + @ApiStatus.Internal + public static void setFactory(CommandFactory factory) { + Commands.factory = factory; + } +} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/SuggestionProvider.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/SuggestionProvider.java index 008a833..09c6120 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/SuggestionProvider.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/SuggestionProvider.java @@ -1,7 +1,5 @@ package de.kentoj.scrow.bukkit.services.command.cmds2; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; - import java.util.Set; public interface SuggestionProvider { diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/ArgumentCommandNode.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/ArgumentCommandNode.java deleted file mode 100644 index f48b9e5..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/ArgumentCommandNode.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command.cmds2.node; - -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import de.kentoj.scrow.bukkit.services.command.type.ArgumentType; - -import java.util.function.Function; - -public non-sealed interface ArgumentCommandNode extends CommandNode { - - ArgumentType getArgument(String name); - - void addArgument(String name, ArgumentType arg); - void addArgument(String name, ArgumentType arg, Function getDefault); -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/CommandNode.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/CommandNode.java deleted file mode 100644 index 43dc85a..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/CommandNode.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command.cmds2.node; - -import de.kentoj.scrow.bukkit.services.command.CommandExecutor; -import de.kentoj.scrow.bukkit.services.command.cmds2.SuggestionProvider; -import org.jetbrains.annotations.Nullable; - -public sealed interface CommandNode permits LiteralCommandNode, ArgumentCommandNode, RootCommandNode { - - void setName(String name); - String getName(); - - void addSubNode(CommandNode node); - @Nullable CommandNode getSubNode(String rawArg); - boolean hasNextNode(); - - void setExecutor(@Nullable CommandExecutor executor); - @Nullable CommandExecutor getExecutor(); - - void setSuggestionProvider(SuggestionProvider suggestionProvider); - SuggestionProvider getSuggestionProvider(); - - void setDescription(@Nullable String description); - @Nullable String getDescription(); -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/Literal.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/Literal.java new file mode 100644 index 0000000..e2abcf9 --- /dev/null +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/Literal.java @@ -0,0 +1,43 @@ +package de.kentoj.scrow.bukkit.services.command.cmds2.node; + +import de.kentoj.scrow.bukkit.services.command.CommandExecutor; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandArgument; +import org.bukkit.permissions.Permission; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public interface Literal { + + /** + * String with no spaces! + */ + void setName(String name); + + /** + * String with no spaces! + */ + String getName(); + + void addLiteral(Literal node); + + @Nullable Literal getLiteral(String rawArg); + + boolean hasLiteral(); + + void setExecutor(@Nullable CommandExecutor executor); + + @Nullable CommandExecutor getExecutor(); + + void setDescription(@Nullable String description); + + @Nullable String getDescription(); + + Permission getRequiredPermission(); + + void setRequiredPermission(Permission permission); + + void addArgument(CommandArgument argument); + + List> getArguments(); +} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/LiteralCommandNode.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/LiteralCommandNode.java deleted file mode 100644 index c3f96ac..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/LiteralCommandNode.java +++ /dev/null @@ -1,10 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command.cmds2.node; - -import org.bukkit.permissions.Permission; - -public non-sealed interface LiteralCommandNode extends CommandNode { - - Permission getRequiredPermission(); - - void setRequiredPermission(Permission permission); -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/RootCommandNode.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/RootLiteral.java similarity index 70% rename from core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/RootCommandNode.java rename to core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/RootLiteral.java index 9dde42e..bd85233 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/RootCommandNode.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/cmds2/node/RootLiteral.java @@ -2,7 +2,7 @@ package de.kentoj.scrow.bukkit.services.command.cmds2.node; import java.util.Set; -public non-sealed interface RootCommandNode extends CommandNode, LiteralCommandNode { +public interface RootLiteral extends Literal { Set getAliases(); diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/exception/CommandSyntaxException.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/exception/CommandInvocationException.java similarity index 68% rename from core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/exception/CommandSyntaxException.java rename to core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/exception/CommandInvocationException.java index 39fde35..e28fe57 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/exception/CommandSyntaxException.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/exception/CommandInvocationException.java @@ -4,19 +4,19 @@ package de.kentoj.scrow.bukkit.services.command.exception; * When a command has a syntax issue. * {@code CommandSyntaxException::getMessage} should return a user-friendly message explaining the issue. */ -public class CommandSyntaxException extends RuntimeException { +public class CommandInvocationException extends RuntimeException { /** * @param message user-friendly message */ - public CommandSyntaxException(String message) { + public CommandInvocationException(String message) { super(message); } /** * @param message user-friendly message */ - public CommandSyntaxException(String message, Throwable throwable) { + public CommandInvocationException(String message, Throwable throwable) { super(message + ": " + throwable.getMessage()); } } diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNode.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNode.java deleted file mode 100644 index e35d0ab..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNode.java +++ /dev/null @@ -1,51 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command.node; - -import de.kentoj.scrow.bukkit.services.command.CommandExecutor; -import org.bukkit.permissions.Permission; -import org.jetbrains.annotations.Nullable; - -import java.util.Set; - -// TODO javadoc -public interface CommandNode { - - void setPermission(@Nullable Permission permission); - - default void setPermission(String permission) { - setPermission(new Permission(permission)); - } - - void setDescription(String description); - - void setAliases(Set aliases); - - void addAlias(String... aliases); - - void setExecutor(@Nullable CommandExecutor executor); - - @Nullable Permission getPermission(); - - String getName(); - - Set getAliases(); - - String getDescription(); - - /** - * Function that should be called when invoking this command. - * The executor shall only be called when this node is the last CommandNode in the invocation. - *
-     * - RootCommand(CommandNode)
-     *   - has executor
-     *   - has sub-command(CommandNode)
-     *     - has executor
-     * 
- * In this case, the sub-command is optional. If the sub-command is used, the sub-command's executor will be used. - * Else the RootCommand's executor will be used. - */ - @Nullable CommandExecutor getExecutor(); - - default boolean hasExecutor() { - return getExecutor() != null; - } -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeFactory.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeFactory.java deleted file mode 100644 index d6cb179..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeFactory.java +++ /dev/null @@ -1,10 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command.node; - -public interface CommandNodeFactory { - - CommandNodeWithSubCommand createNodeWithSubCommands(String name); - - CommandNodeWithArguments createNodeWithArguments(String name); - - CommandNode createRootNode(String name); -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeRepository.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeRepository.java deleted file mode 100644 index 9ac039b..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command.node; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.jetbrains.annotations.ApiStatus; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CommandNodeRepository { - - private static CommandNodeFactory commandNodeFactory; - - public static CommandNodeWithArguments withArguments(String name) { - return commandNodeFactory.createNodeWithArguments(name); - } - - public static CommandNodeWithSubCommand withSubCommands(String name) { - return commandNodeFactory.createNodeWithSubCommands(name); - } - - @ApiStatus.Internal - public static void setCommandNodeFactory(CommandNodeFactory commandNodeFactory) { - CommandNodeRepository.commandNodeFactory = commandNodeFactory; - } -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeWithArguments.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeWithArguments.java deleted file mode 100644 index 78577af..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeWithArguments.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command.node; - -import de.kentoj.scrow.bukkit.services.command.CommandArgument; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import de.kentoj.scrow.bukkit.services.command.type.ArgumentType; -import org.jetbrains.annotations.Nullable; - -import java.util.function.Function; - -/** - * A CommandNode which can have arguments - */ -public interface CommandNodeWithArguments extends CommandNode { - - /** - * Adds an argument to the node. - * @param defaultValue Function returning a defaultValue if no value is given at invocation. \ - * May be null if the argument should be required and not optional. - * @throws IllegalStateException if the previous argument is optional(defaultValue is set) and this is not. - */ - void addArg(String name, ArgumentType type, @Nullable Function defaultValue); - - /** - * Adds a required argument to the node - * @throws IllegalStateException if the previous argument is optional(defaultValue is set) and this is not. - */ - default void addArg(String name, ArgumentType type) { - addArg(name, type, null); - } - - @Nullable CommandArgument getArg(int index); - - @Nullable CommandArgument getArg(String name); -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeWithSubCommand.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeWithSubCommand.java deleted file mode 100644 index 733206e..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/node/CommandNodeWithSubCommand.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command.node; - -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -/** - * A CommandNode which can have sub-commands - */ -public interface CommandNodeWithSubCommand extends CommandNode { - - List getSubCommands(); - - void addSubCommand(CommandNode subCommand); - - /** - * @return SubCommand node where a name or alias matches label - */ - @Nullable CommandNode getSubCommand(String label); -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/ArgumentType.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/ArgumentType.java index acb9ac8..e79ffd1 100644 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/ArgumentType.java +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/ArgumentType.java @@ -1,19 +1,19 @@ package de.kentoj.scrow.bukkit.services.command.type; -import de.kentoj.scrow.bukkit.services.command.CommandReader; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException; +import de.kentoj.scrow.bukkit.services.command.ArgumentReader; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandContext; +import de.kentoj.scrow.bukkit.services.command.exception.CommandInvocationException; import java.util.Set; public interface ArgumentType { /** - * @throws CommandSyntaxException if the given value may not be used + * @throws CommandInvocationException if the given value may not be used */ - void checkValue(CommandContext ctx, T value, String rawValue) throws CommandSyntaxException; + void checkValue(CommandContext ctx, T value) throws CommandInvocationException; Set getDefaultSuggestions(CommandContext ctx); - T parseInput(CommandReader reader); + T parseInput(ArgumentReader reader); } diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/EntityArgumentType.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/EntityArgumentType.java deleted file mode 100644 index 5c46ce2..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/EntityArgumentType.java +++ /dev/null @@ -1,47 +0,0 @@ -package de.kentoj.scrow.bukkit.services.command.type; - -import de.kentoj.scrow.bukkit.services.command.CommandReader; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -// TODO add livingEntity - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class EntityArgumentType { - - private static final ArgumentType player = new ArgumentType<>() { - @Override - public void checkValue(CommandContext ctx, Player value, String rawValue) throws CommandSyntaxException { - if (value == null) - throw new CommandSyntaxException("Player is not online -- " + rawValue); - } - - @Override - public Set getDefaultSuggestions(CommandContext ctx) { - return Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toSet()); - } - - @Override - public Player parseInput(CommandReader reader) { - final var word = reader.readWord(); - if (word.length() == 36) { - var uuid = UUID.fromString(word); - return Bukkit.getPlayer(uuid); - } else { - return Bukkit.getPlayerExact(word); - } - } - }; - - public static ArgumentType player() { - return player; - } -} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/NumberArgumentType.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/NumberArgumentType.java new file mode 100644 index 0000000..3791587 --- /dev/null +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/NumberArgumentType.java @@ -0,0 +1,43 @@ +package de.kentoj.scrow.bukkit.services.command.type; + +import com.google.common.base.Preconditions; +import de.kentoj.scrow.bukkit.services.command.ArgumentReader; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandContext; +import de.kentoj.scrow.bukkit.services.command.exception.CommandInvocationException; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +import java.util.Set; + +// TODO add livingEntity + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class NumberArgumentType { + + public static ArgumentType integer(int min, int max) { + Preconditions.checkArgument(min < max, "min is greater than max"); + + return new ArgumentType<>() { + @Override + public void checkValue(CommandContext ctx, Integer value) throws CommandInvocationException { + if (value < min) throw new CommandInvocationException("Value too small -- " + value); + if (value > max) throw new CommandInvocationException("Value too large -- " + value); + } + + @Override + public Set getDefaultSuggestions(CommandContext ctx) { + return Set.of(); + } + + @Override + public Integer parseInput(ArgumentReader reader) { + final var str = reader.readWord(); + try { + return Integer.parseInt(str); + } catch (NumberFormatException ex) { + throw new CommandInvocationException("Invalid number -- " + str); + } + } + }; + } +} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/PlayerArgumentType.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/PlayerArgumentType.java new file mode 100644 index 0000000..fde23fc --- /dev/null +++ b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/services/command/type/PlayerArgumentType.java @@ -0,0 +1,79 @@ +package de.kentoj.scrow.bukkit.services.command.type; + +import de.kentoj.scrow.bukkit.services.command.ArgumentReader; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandContext; +import de.kentoj.scrow.bukkit.services.command.exception.CommandInvocationException; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +// TODO add livingEntity + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class PlayerArgumentType { + + private static final ArgumentType player = new ArgumentType<>() { + @Override + public void checkValue(CommandContext ctx, Player value) throws CommandInvocationException { + if (value == null) + throw new CommandInvocationException("Player is not online"); + } + + @Override + public Set getDefaultSuggestions(CommandContext ctx) { + return Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toSet()); + } + + @Override + public Player parseInput(ArgumentReader reader) { + final var word = reader.readWord(); + if (word.length() == 36) { + var uuid = UUID.fromString(word); + return Bukkit.getPlayer(uuid); + } else { + return Bukkit.getPlayerExact(word); + } + } + }; + + private static final ArgumentType offlinePlayer = new ArgumentType<>() { + @Override + public OfflinePlayer parseInput(ArgumentReader reader) { + final var str = reader.readWord(); + OfflinePlayer player; + + player = Bukkit.getPlayerExact(str); + if (player == null) { + try { + player = Bukkit.getOfflinePlayer(UUID.fromString(str)); + } catch (IllegalArgumentException ex) { + throw new CommandInvocationException("Not a UUID or name of an online player"); + } + } + return player; + } + + @Override + public Set getDefaultSuggestions(CommandContext ctx) { + return Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toSet()); + } + + @Override + public void checkValue(CommandContext ctx, OfflinePlayer value) throws CommandInvocationException { + } + }; + + public static ArgumentType player() { + return player; + } + + public static ArgumentType offlinePlayer() { + return offlinePlayer; + } +} diff --git a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/util/command/PlayerArgument.java b/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/util/command/PlayerArgument.java deleted file mode 100644 index 9c090ca..0000000 --- a/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/util/command/PlayerArgument.java +++ /dev/null @@ -1,30 +0,0 @@ -package de.kentoj.scrow.bukkit.util.command; - -import com.mojang.brigadier.LiteralMessage; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.util.UUID; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class PlayerArgument { - - public static Player resolve(CommandContext ctx, String argumentName) throws CommandSyntaxException { - var str = ctx.getArgument(argumentName, String.class); - boolean isUUID = str.length() == 36; - return isUUID ? Bukkit.getPlayer(parseUUID(str)) : Bukkit.getPlayerExact(str); - } - - private static UUID parseUUID(String string) throws CommandSyntaxException { - try { - return UUID.fromString(string); - } catch (IllegalArgumentException ex) { - throw new SimpleCommandExceptionType(new LiteralMessage("Invalid UUID")).create(); - } - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java index 59c9bec..1123d67 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java @@ -1,6 +1,6 @@ package de.kentoj.scrow.bukkit; -import de.kentoj.scrow.bukkit.friends.command.LaunchCommand; +import de.kentoj.scrow.bukkit.economy.command.CoinsCommand; import org.bukkit.plugin.java.JavaPlugin; import reactor.core.publisher.Mono; @@ -13,7 +13,7 @@ public class CoreImplPlugin extends JavaPlugin { ScrowAPISurface.initScrowAPI(this, false); { - ScrowAPI.getCommandManager().register(new LaunchCommand(), this); + ScrowAPI.getCommandManager().register(new CoinsCommand().create(), this); } { diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java index 506ecdf..631eb69 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java @@ -4,11 +4,11 @@ import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClients; -import de.kentoj.scrow.bukkit.command.bukkit.CommandManagerImpl; -import de.kentoj.scrow.bukkit.command.node.CommandNodeFactoryImpl; +import de.kentoj.scrow.bukkit.cmds2.CommandFactoryImpl; +import de.kentoj.scrow.bukkit.cmds2.CommandManagerImpl; import de.kentoj.scrow.bukkit.economy.InMemoryEconomyService; import de.kentoj.scrow.bukkit.economy.MongoEconomyService; -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeRepository; +import de.kentoj.scrow.bukkit.services.command.cmds2.Commands; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.bson.UuidRepresentation; @@ -48,7 +48,7 @@ public class ScrowAPISurface { new MongoEconomyService(ScrowAPI.getDatabase()) : new InMemoryEconomyService() ); - CommandNodeRepository.setCommandNodeFactory(new CommandNodeFactoryImpl()); + Commands.setFactory(new CommandFactoryImpl()); ScrowAPI.setCommandManager(new CommandManagerImpl()); } diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/BukkitCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/BukkitCommand.java deleted file mode 100644 index 8688cab..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/BukkitCommand.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.kentoj.scrow.bukkit.cmds2; - -import de.kentoj.scrow.bukkit.services.command.cmds2.node.ArgumentCommandNode; -import de.kentoj.scrow.bukkit.services.command.cmds2.node.CommandNode; -import de.kentoj.scrow.bukkit.services.command.cmds2.node.LiteralCommandNode; -import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootCommandNode; -import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; - -public class BukkitCommand extends Command { - - private final RootCommandNode rootCommandNode; - - protected BukkitCommand(RootCommandNode rootCommandNode) { - super(rootCommandNode.getName()); - this.rootCommandNode = rootCommandNode; - - if (rootCommandNode.getDescription() != null) { - super.setDescription(rootCommandNode.getDescription()); - } - if (rootCommandNode.getAliases() != null) { - super.setAliases(rootCommandNode.getAliases().stream().toList()); - } - // TODO usage string? - } - - private void processCommand(@NotNull CommandSender sender, @NotNull String commandLabel, - @NotNull String[] args) throws CommandSyntaxException { - CommandNode node = rootCommandNode; - int argsIndex = 0; - - while (node.hasNextNode()) { - if (args.length - 1 < argsIndex) { - if (node) - } - - if (node instanceof LiteralCommandNode literal) { - - node = literal.getSubNode(args[argsIndex]); - if (node == null) { - throw new CommandSyntaxException("Invalid argument -- " + args[argsIndex]) - } - } else if (node instanceof ArgumentCommandNode) { - - } - - argsIndex++; - } - } - - @Override - public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) { - return true; - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CoinsCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CoinsCommand.java deleted file mode 100644 index 76992ae..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CoinsCommand.java +++ /dev/null @@ -1,53 +0,0 @@ -package de.kentoj.scrow.bukkit.cmds2; - -import de.kentoj.scrow.bukkit.ScrowAPI; -import de.kentoj.scrow.bukkit.services.command.CommandExecutor; -import de.kentoj.scrow.bukkit.services.command.cmds2.node.ArgumentCommandNode; -import de.kentoj.scrow.bukkit.services.command.cmds2.node.LiteralCommandNode; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import de.kentoj.scrow.bukkit.services.command.type.EntityArgumentType; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import reactor.core.scheduler.Schedulers; - -import java.util.logging.Level; - -@SuppressWarnings("DataFlowIssue") -public class CoinsCommand implements CommandExecutor { - - public CoinsCommand() { - final ArgumentCommandNode node = null; - node.addArgument("player", EntityArgumentType.player(), CommandContext::getSenderPlayer); - node.setExecutor(this::displayCoins); - - final LiteralCommandNode setLiteral; - node.addSubNode(setLiteral); - setLiteral - { - final ArgumentCommandNode specifyPlayerNode = null /* TODO */; - - node.addSubNode(specifyPlayerNode); - specifyPlayerNode.addArgument("player", EntityArgumentType.player(), CommandContext::getSenderPlayer); - specifyPlayerNode.setExecutor(this::setCoins); - } - } - - private void displayCoins(CommandContext ctx) { - final Player player = ctx.getArg("player"); - - ScrowAPI.getEconomyService() - .getCoins(player.getUniqueId()) - .subscribeOn(Schedulers.boundedElastic()) - .publishOn(ScrowAPI.getMinecraftScheduler()) - .subscribe(coins -> { - player.sendMessage("You have " + coins + "$"); - }, err -> { - player.sendMessage("Error fetching coins: " + err.getMessage()); - Bukkit.getLogger().log(Level.SEVERE, "Failed fetching coins for " + player.getUniqueId(), err); - }); - } - - public void setCoins(CommandContext ctx) { - - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandContextImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandContextImpl.java new file mode 100644 index 0000000..bb321c5 --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandContextImpl.java @@ -0,0 +1,39 @@ +package de.kentoj.scrow.bukkit.cmds2; + +import com.google.common.base.Preconditions; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandContext; +import de.kentoj.scrow.bukkit.services.command.exception.CommandInvocationException; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.Map; + +@RequiredArgsConstructor +public class CommandContextImpl implements CommandContext { + + @Getter + private final CommandSender sender; + private final Map arguments; + + @SuppressWarnings("unchecked") + public T getArg(String name) { + final T value = (T) arguments.get(name); + Preconditions.checkState(value != null, "no value for '" + name + "'-argument"); + return value; + } + + @Override + public Player getSenderPlayer() { + if (!(sender instanceof Player)) throw new CommandInvocationException("This command can only be used by players"); + return (Player) sender; + } + + @Override + public Entity getSenderEntity() { + if (!(sender instanceof Entity)) throw new CommandInvocationException("This command can only be used by entities"); + return (Entity) sender; + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandFactoryImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandFactoryImpl.java new file mode 100644 index 0000000..a52b14a --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandFactoryImpl.java @@ -0,0 +1,31 @@ +package de.kentoj.scrow.bukkit.cmds2; + +import de.kentoj.scrow.bukkit.cmds2.types.CommandArgumentImpl; +import de.kentoj.scrow.bukkit.cmds2.types.LiteralImpl; +import de.kentoj.scrow.bukkit.cmds2.types.RootLiteralImpl; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandArgument; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandContext; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandFactory; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.Literal; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; +import de.kentoj.scrow.bukkit.services.command.type.ArgumentType; + +import java.util.function.Function; + +public class CommandFactoryImpl implements CommandFactory { + + @Override + public Literal literal(String name) { + return new LiteralImpl(name); + } + + @Override + public RootLiteral root(String name) { + return new RootLiteralImpl(name); + } + + @Override + public CommandArgument argument(String name, ArgumentType type, Function defaultValueFun) { + return new CommandArgumentImpl<>(name, type, defaultValueFun); + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/CommandManagerImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandManagerImpl.java similarity index 56% rename from core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/CommandManagerImpl.java rename to core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandManagerImpl.java index d03deab..6419497 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/CommandManagerImpl.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/CommandManagerImpl.java @@ -1,9 +1,9 @@ -package de.kentoj.scrow.bukkit.command.bukkit; +package de.kentoj.scrow.bukkit.cmds2; +import de.kentoj.scrow.bukkit.cmds2.parsing.BukkitCommand; import de.kentoj.scrow.bukkit.services.command.CommandManager; -import de.kentoj.scrow.bukkit.services.command.node.CommandNode; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; import org.bukkit.Bukkit; -import org.bukkit.command.Command; import org.bukkit.command.CommandMap; import org.bukkit.plugin.Plugin; @@ -22,18 +22,8 @@ public class CommandManagerImpl implements CommandManager { } @Override - public void register(CommandNode rootCommandNode, Plugin plugin) { - var bukkitCommand = toBukkitCommand(rootCommandNode); + public void register(RootLiteral rootLiteral, Plugin plugin) { + var bukkitCommand = new BukkitCommand(rootLiteral); commandMap.register(plugin.getName(), bukkitCommand); } - - private Command toBukkitCommand(CommandNode commandNode) { - return new BukkitCommand( - commandNode, - commandNode.getName(), - commandNode.getDescription(), - "", - commandNode.getAliases() - ); - } } diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/ArgumentReaderImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/ArgumentReaderImpl.java new file mode 100644 index 0000000..18d6a9a --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/ArgumentReaderImpl.java @@ -0,0 +1,62 @@ +package de.kentoj.scrow.bukkit.cmds2.parsing; + +import de.kentoj.scrow.bukkit.services.command.ArgumentReader; +import de.kentoj.scrow.bukkit.services.command.exception.CommandInvocationException; + +import java.nio.CharBuffer; + +public class ArgumentReaderImpl implements ArgumentReader { + + private final CharBuffer buf; + + public ArgumentReaderImpl(String string) { + buf = CharBuffer.wrap(string); + } + + public ArgumentReaderImpl(String[] args) { + this(String.join(" ", args)); + } + + @Override + public boolean isEOF() { + return buf.position() >= buf.limit(); + } + + @Override + public String readWord() { + final var str = new StringBuilder(); + while (true) { + if (buf.position() >= buf.limit()) break; + char c = buf.get(); + if (c == ' ') break; + str.append(c); + } + return str.toString(); + } + + @Override + public String readQuotedWord() { + final var str = new StringBuilder(); + var quoting = false; + while (true) { + if (buf.position() >= buf.limit()) break; + char c = buf.get(); + if (c == '"') quoting = !quoting; + if (c == ' ' && !quoting) break; + str.append(c); + } + + if (quoting) throw new CommandInvocationException("Missing matching \" to terminate quote"); + return str.toString(); + } + + @Override + public int getCursor() { + return buf.position(); + } + + @Override + public void setCursor(int cursor) { + buf.position(cursor); + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/BukkitCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/BukkitCommand.java new file mode 100644 index 0000000..77b0096 --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/BukkitCommand.java @@ -0,0 +1,36 @@ +package de.kentoj.scrow.bukkit.cmds2.parsing; + +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; +import de.kentoj.scrow.bukkit.services.command.exception.CommandInvocationException; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class BukkitCommand extends Command { + + private final RootLiteral rootLiteral; + + public BukkitCommand(RootLiteral rootLiteral) { + super(rootLiteral.getName()); + this.rootLiteral = rootLiteral; + + if (rootLiteral.getDescription() != null) { + super.setDescription(rootLiteral.getDescription()); + } + if (rootLiteral.getAliases() != null) { + super.setAliases(rootLiteral.getAliases().stream().toList()); + } + // TODO usage string? + } + + @Override + public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) { + try { + new CommandProcessor(sender, new ArgumentReaderImpl(args)).execute(rootLiteral); + } catch (CommandInvocationException syntaxException) { + sender.sendMessage(ChatColor.RED + syntaxException.getMessage()); + } + return true; + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/BukkitTabCompleter.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/BukkitTabCompleter.java new file mode 100644 index 0000000..71373fe --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/BukkitTabCompleter.java @@ -0,0 +1,23 @@ +package de.kentoj.scrow.bukkit.cmds2.parsing; + +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; +import lombok.RequiredArgsConstructor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +@RequiredArgsConstructor +public class BukkitTabCompleter implements TabCompleter { + + private final RootLiteral rootLiteral; + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + + return List.of(); + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/CommandProcessor.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/CommandProcessor.java new file mode 100644 index 0000000..1dd3d68 --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/parsing/CommandProcessor.java @@ -0,0 +1,67 @@ +package de.kentoj.scrow.bukkit.cmds2.parsing; + +import de.kentoj.scrow.bukkit.cmds2.CommandContextImpl; +import de.kentoj.scrow.bukkit.services.command.ArgumentReader; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandArgument; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.Literal; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; +import de.kentoj.scrow.bukkit.services.command.exception.CommandInvocationException; +import lombok.RequiredArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; + +import java.util.HashMap; +import java.util.Map; + +@RequiredArgsConstructor +public class CommandProcessor { + + private final Map arguments = new HashMap<>(); + + private final CommandSender sender; + private final ArgumentReader argumentReader; + + public void execute(RootLiteral rootLiteral) { + Literal lastLiteral = rootLiteral; + do { + processArguments(lastLiteral); + + if (argumentReader.isEOF()) { + if (lastLiteral.getExecutor() == null) throw new CommandInvocationException("Incomplete command -- literal expected"); + lastLiteral.getExecutor().execute(new CommandContextImpl(sender, arguments)); + return; + } + + final var literalName = argumentReader.readWord(); + lastLiteral = lastLiteral.getLiteral(literalName); + if (lastLiteral == null) throw new CommandInvocationException("Unknown literal -- " + literalName); + + final boolean hasSenderPermission = lastLiteral.getRequiredPermission() == null || sender.hasPermission(lastLiteral.getRequiredPermission()); + if (!hasSenderPermission) throw new CommandInvocationException("No permission"); + } while (lastLiteral.hasLiteral()); + + processArguments(lastLiteral); + + if (lastLiteral.getExecutor() == null) throw new CommandInvocationException("Incomplete command."); + lastLiteral.getExecutor().execute(new CommandContextImpl(sender, arguments)); + } + + private void processArguments(Literal node) { + node.getArguments().forEach(arg -> { + Object parsed = parseArgument(arg); + arguments.put(arg.getName(), parsed); + }); + } + + private Object parseArgument(CommandArgument argument) { + if (argumentReader.isEOF()) { + var defaultValue = argument.getDefaultValue(new CommandContextImpl(sender, arguments)); + if (defaultValue == null) throw new CommandInvocationException("Missing argument -- " + argument.getName()); + return defaultValue; + } + + T value = argument.getType().parseInput(argumentReader); + argument.getType().checkValue(new CommandContextImpl(sender, arguments), value); + return value; + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/CommandArgumentImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/CommandArgumentImpl.java new file mode 100644 index 0000000..b7319ce --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/CommandArgumentImpl.java @@ -0,0 +1,34 @@ +package de.kentoj.scrow.bukkit.cmds2.types; + +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandArgument; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandContext; +import de.kentoj.scrow.bukkit.services.command.cmds2.SuggestionProvider; +import de.kentoj.scrow.bukkit.services.command.type.ArgumentType; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Function; + +@Getter +@RequiredArgsConstructor +public class CommandArgumentImpl implements CommandArgument { + + private final String name; + private final ArgumentType type; + private final Function defaultValueFun; + @Setter + private @Nullable SuggestionProvider suggestionProvider; + + @Override + public @Nullable T getDefaultValue(CommandContext ctx) { + return defaultValueFun.apply(ctx); + } + + public SuggestionProvider getSuggestionProvider() { + if (suggestionProvider == null) + return type::getDefaultSuggestions; + return suggestionProvider; + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/LiteralImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/LiteralImpl.java new file mode 100644 index 0000000..eed641c --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/LiteralImpl.java @@ -0,0 +1,58 @@ +package de.kentoj.scrow.bukkit.cmds2.types; + +import de.kentoj.scrow.bukkit.services.command.CommandExecutor; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandArgument; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.Literal; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.Bukkit; +import org.bukkit.permissions.Permission; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Getter +public class LiteralImpl implements Literal { + + @Setter + private String name; + + @Setter + private @Nullable Permission requiredPermission = null; + @Setter + private @Nullable String description = null; + @Setter + private @Nullable CommandExecutor executor = null; + private final List> arguments = new ArrayList<>(); + private final Map literals = new HashMap<>(); + + public LiteralImpl(String name) { + this.name = name; + } + + @Override + public void addLiteral(Literal node) { + if (literals.containsKey(node.getName())) { + Bukkit.getLogger().warning("Literal " + node.getName() + " is overwritten by literal with same name"); + } + literals.put(node.getName(), node); + } + + @Override + public @Nullable Literal getLiteral(String name) { + return literals.get(name); + } + + @Override + public boolean hasLiteral() { + return !literals.isEmpty(); + } + + @Override + public void addArgument(CommandArgument argument) { + arguments.add(argument); + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/RootLiteralImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/RootLiteralImpl.java new file mode 100644 index 0000000..e456ca0 --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/cmds2/types/RootLiteralImpl.java @@ -0,0 +1,25 @@ +package de.kentoj.scrow.bukkit.cmds2.types; + +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; +import lombok.Getter; +import lombok.Setter; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class RootLiteralImpl extends LiteralImpl implements RootLiteral { + + @Getter + @Setter + private Set aliases = new HashSet<>(); + + public RootLiteralImpl(String name) { + super(name); + } + + @Override + public void addAliases(String... aliases) { + this.aliases.addAll(List.of(aliases)); + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/CommandContextImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/CommandContextImpl.java deleted file mode 100644 index 262872d..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/CommandContextImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package de.kentoj.scrow.bukkit.command; - -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; - -@RequiredArgsConstructor -public class CommandContextImpl implements CommandContext { - - @Getter - private final CommandSender sender; - - @Override - public Player getSenderPlayer() { - return (Player) sender; - } - - @Override - public Entity getSenderEntity() { - return (Entity) sender; - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/CommandExecutionContextImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/CommandExecutionContextImpl.java deleted file mode 100644 index be2a85a..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/CommandExecutionContextImpl.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.kentoj.scrow.bukkit.command; - -import de.kentoj.scrow.bukkit.command.bukkit.ArgumentData; -import de.kentoj.scrow.bukkit.services.command.CommandArgument; -import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.Nullable; - -import java.util.Map; - -public class CommandExecutionContextImpl extends CommandContextImpl implements CommadContext { - - private final Map argumentDataMap; - - public CommandExecutionContextImpl(CommandSender sender, Map argumentDataMap) { - super(sender); - this.argumentDataMap = argumentDataMap; - } - - @Override - public @Nullable String getRawArgument(String key) { - var data = argumentDataMap.get(key); - if (data.getRawValue() == null) { - if (data.getArgument().getDefaultValue() == null) { - throw new CommandSyntaxException("usage: missing arg value for " + key); - } - return null; - } - return data.getRawValue(); - } - - @SuppressWarnings("unchecked") - public T getArg(String key) { - var data = argumentDataMap.get(key); - var arg = (CommandArgument) data.getArgument(); - var raw = getRawArgument(key); - - T value; - if (raw != null) { - value = arg.getType().parseInput(raw); - } else { - value = arg.getDefaultValue().apply(this); - } - - arg.getType().checkValue(this, value, raw); - return value; - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/ArgumentData.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/ArgumentData.java deleted file mode 100644 index 3fe8a21..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/ArgumentData.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.kentoj.scrow.bukkit.command.bukkit; - -import de.kentoj.scrow.bukkit.services.command.CommandArgument; -import lombok.Value; -import org.jetbrains.annotations.Nullable; - -@Value -public class ArgumentData { - CommandArgument argument; - @Nullable String rawValue; -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/BukkitCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/BukkitCommand.java deleted file mode 100644 index 43b6cae..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/BukkitCommand.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.kentoj.scrow.bukkit.command.bukkit; - -import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException; -import de.kentoj.scrow.bukkit.services.command.node.CommandNode; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; - -import java.util.Set; - -public class BukkitCommand extends Command { - - private final CommandNode rootCommandNode; - - protected BukkitCommand(CommandNode rootCommandNode, @NotNull String name, @NotNull String description, @NotNull String usageMessage, @NotNull Set aliases) { - super(name, description, usageMessage, aliases.stream().toList()); - this.rootCommandNode = rootCommandNode; - } - - @Override - public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) { - final var commandProcessor = new CommandProcessor(rootCommandNode, sender, args); - - try { - commandProcessor.process(); - } catch (CommandSyntaxException e) { - sender.sendMessage("error: " + e.getMessage()); - return true; - } catch (IllegalStateException e) { - throw new RuntimeException("failed processing command " + rootCommandNode.getName(), e); - } - return true; - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/CommandProcessor.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/CommandProcessor.java deleted file mode 100644 index ba3ddff..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/bukkit/CommandProcessor.java +++ /dev/null @@ -1,62 +0,0 @@ -package de.kentoj.scrow.bukkit.command.bukkit; - -import de.kentoj.scrow.bukkit.command.CommandExecutionContextImpl; -import de.kentoj.scrow.bukkit.services.command.CommandArgument; -import de.kentoj.scrow.bukkit.services.command.CommandExecutor; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException; -import de.kentoj.scrow.bukkit.services.command.node.CommandNode; -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithArguments; -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithSubCommand; -import lombok.AllArgsConstructor; -import lombok.RequiredArgsConstructor; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - -@AllArgsConstructor -public class CommandProcessor { - - private final Map argumentDataMap = new HashMap<>(); - - private CommandNode node; - private final CommandSender sender; - private final String[] args; - - public void process() throws CommandSyntaxException { - for (int cursor = 0; true; cursor++) { - if (args.length - 1 < cursor) { - if (node.getExecutor() == null) throw new CommandSyntaxException("Incomplete command"); - execute(node.getExecutor()); - return; - } - - if (node instanceof CommandNodeWithArguments nodeWA) { - final var arg = nodeWA.getArg(cursor); - assert arg != null; - final var data = new ArgumentData(arg, args[cursor]); - argumentDataMap.put(arg.getName(), data); - } else if (node instanceof CommandNodeWithSubCommand nodeWS) { - if (nodeWS.getSubCommands().isEmpty()) break; - final var subcommand = nodeWS.getSubCommand(args[cursor]); - if (subcommand == null) { - final var subcommands = nodeWS.getSubCommands().stream().map(CommandNode::getName).toList(); - throw new CommandSyntaxException("Illegal argument -- " + args[cursor] + "\nExpected arguments: " + String.join(", ", subcommands)); - } - - this.node = nodeWS; - } - } - - if (node.getExecutor() == null) throw new IllegalStateException("Last CommandNode must have an executor"); - execute(node.getExecutor()); - } - - private void execute(CommandExecutor executor) { - var ctx = new CommandExecutionContextImpl(sender, argumentDataMap); - executor.execute(ctx); - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeFactoryImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeFactoryImpl.java deleted file mode 100644 index 864aa19..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeFactoryImpl.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.kentoj.scrow.bukkit.command.node; - -import de.kentoj.scrow.bukkit.services.command.node.CommandNode; -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeFactory; -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithArguments; -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithSubCommand; - -public class CommandNodeFactoryImpl implements CommandNodeFactory { - @Override - public CommandNodeWithSubCommand createNodeWithSubCommands(String name) { - return new CommandNodeWithSubCommandImpl(name); - } - - @Override - public CommandNodeWithArguments createNodeWithArguments(String name) { - return new CommandNodeWithArgumentsImpl(name); - } - - @Override - public CommandNode createRootNode(String name) { - return new CommandNodeImpl(name); - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeImpl.java deleted file mode 100644 index 2dad138..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.kentoj.scrow.bukkit.command.node; - -import de.kentoj.scrow.bukkit.services.command.CommandExecutor; -import de.kentoj.scrow.bukkit.services.command.node.CommandNode; -import lombok.Getter; -import lombok.Setter; -import org.bukkit.permissions.Permission; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -@Getter -public class CommandNodeImpl implements CommandNode { - - private final String name; - - @Setter - private Set aliases = new HashSet<>(); - @Setter - private @Nullable Permission permission = null; - @Setter - private @Nullable String description; - @Setter - private @Nullable CommandExecutor executor = null; - - public CommandNodeImpl(String name) { - this.name = name; - } - - @Override - public void addAlias(String... aliases) { - this.aliases.addAll(Arrays.asList(aliases)); - } -} \ No newline at end of file diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeWithArgumentsImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeWithArgumentsImpl.java deleted file mode 100644 index e0ef60a..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeWithArgumentsImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -package de.kentoj.scrow.bukkit.command.node; - - -import de.kentoj.scrow.bukkit.services.command.CommandArgument; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithArguments; -import de.kentoj.scrow.bukkit.services.command.type.ArgumentType; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -public class CommandNodeWithArgumentsImpl extends CommandNodeImpl implements CommandNodeWithArguments { - - private final List> args = new ArrayList<>(); - - public CommandNodeWithArgumentsImpl(String name) { - super(name); - } - - @Override - public void addArg(String name, ArgumentType type, Function defaultValue) { - var index = args.size(); - if (index > 0) { - boolean isPreviousArgumentOptional = args.get(index - 1).getDefaultValue() != null; - boolean isNewArgumentOptional = defaultValue != null; - if (isPreviousArgumentOptional && !isNewArgumentOptional) { - throw new IllegalStateException("an optional argument(an argument with a defaultValue set) may not be followed by a required argument"); - } - } - args.add(new CommandArgument<>(index, name, type, defaultValue)); - } - - @Override - public @Nullable CommandArgument getArg(String name) { - return args.stream() - .filter(ra -> ra.getName().equals(name)) - .findFirst() - .orElse(null); - } - - @Override - public @Nullable CommandArgument getArg(int index) { - return args.stream() - .filter(ra -> ra.getIndex() == index) - .findFirst() - .orElse(null); - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeWithSubCommandImpl.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeWithSubCommandImpl.java deleted file mode 100644 index 842a1f9..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/node/CommandNodeWithSubCommandImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -package de.kentoj.scrow.bukkit.command.node; - -import de.kentoj.scrow.bukkit.services.command.node.CommandNode; -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithSubCommand; -import lombok.Getter; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; - -public class CommandNodeWithSubCommandImpl extends CommandNodeImpl implements CommandNodeWithSubCommand { - - @Getter - private final List subCommands = new ArrayList<>(); - - public CommandNodeWithSubCommandImpl(String name) { - super(name); - } - - @Override - public void addSubCommand(CommandNode subCommand) { - subCommands.add(subCommand); - } - - @Override - public @Nullable CommandNode getSubCommand(String label) { - return subCommands.stream() - .filter(n -> n.getName().equals(label) || n.getAliases().contains(label)) - .findFirst() - .orElse(null); - } -} \ No newline at end of file diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/MongoEconomyService.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/MongoEconomyService.java index ba7f830..96c80ad 100644 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/MongoEconomyService.java +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/MongoEconomyService.java @@ -14,6 +14,7 @@ import reactor.core.publisher.Mono; import java.util.UUID; +// TODO log public class MongoEconomyService implements EconomyService { private static final String COLLECTION_NAME = "economy"; diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsCommand.java new file mode 100644 index 0000000..ef1c2d3 --- /dev/null +++ b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsCommand.java @@ -0,0 +1,86 @@ +package de.kentoj.scrow.bukkit.economy.command; + +import de.kentoj.scrow.bukkit.ScrowAPI; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandArgument; +import de.kentoj.scrow.bukkit.services.command.cmds2.CommandContext; +import de.kentoj.scrow.bukkit.services.command.cmds2.Commands; +import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootLiteral; +import de.kentoj.scrow.bukkit.services.command.type.NumberArgumentType; +import de.kentoj.scrow.bukkit.services.command.type.PlayerArgumentType; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import reactor.core.scheduler.Schedulers; + +import java.util.logging.Level; + +public class CoinsCommand { + + private final RootLiteral rootCommand; + private final CommandArgument playerArg; + private final CommandArgument amountArg; + + /* + /coins steve + /coins steve set 0 + /coins steve get + */ + public CoinsCommand() { + playerArg = Commands.argument0("player", PlayerArgumentType.offlinePlayer(), CommandContext::getSenderPlayer); + + amountArg = Commands.argument0("amount", NumberArgumentType.integer(0, Integer.MAX_VALUE)); + + rootCommand = Commands.root("coins"); + rootCommand.addArgument(playerArg); + rootCommand.setExecutor(this::getCoins); + { + final var setLiteral = Commands.literal("set"); + setLiteral.addArgument(amountArg); + setLiteral.setExecutor(this::setCoins); + rootCommand.addLiteral(setLiteral); + } + { + final var getLiteral = Commands.literal("get"); + getLiteral.setExecutor(this::getCoins); + rootCommand.addLiteral(getLiteral); + } + } + + public RootLiteral create() { + return rootCommand; + } + + private void getCoins(CommandContext ctx) { + final var player = ctx.getArg(playerArg); + + ScrowAPI.getEconomyService() + .getCoins(player.getUniqueId()) + .subscribeOn(Schedulers.boundedElastic()) + .publishOn(ScrowAPI.getMinecraftScheduler()) + .subscribe(amount -> { + if (player == ctx.getSender()) { + ctx.getSender().sendMessage("You have " + amount + "$"); + } else { + ctx.getSender().sendMessage(player.getName() + " has " + amount + "$"); + } + }, err -> { + ctx.getSender().sendMessage("Unable to get coins: " + err.getMessage()); + Bukkit.getLogger().log(Level.SEVERE, "Unable to get coins of " + player.getUniqueId(), err); + }); + } + + public void setCoins(CommandContext ctx) { + final var player = ctx.getArg(playerArg); + final int amount = ctx.getArg(amountArg); + + ScrowAPI.getEconomyService() + .setCoins(player.getUniqueId(), amount) + .subscribeOn(Schedulers.boundedElastic()) + .publishOn(ScrowAPI.getMinecraftScheduler()) + .subscribe(__ -> { + ctx.getSender().sendMessage(player.getName() + " now has " + amount + "$"); + }, err -> { + ctx.getSender().sendMessage("Unable to set coins: " + err.getMessage()); + Bukkit.getLogger().log(Level.SEVERE, "Unable to set coins of " + player.getUniqueId() + " to " + amount, err); + }); + } +} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java deleted file mode 100644 index 6307f31..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.kentoj.scrow.bukkit.friends.command; - -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeRepository; -import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithSubCommand; - -public class FriendCommand { - - private final CommandNodeWithSubCommand node = CommandNodeRepository.withSubCommands("friend"); - - public FriendCommand() { - this.node.addAlias("f"); - } -} diff --git a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/LaunchCommand.java b/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/LaunchCommand.java deleted file mode 100644 index efd2ff0..0000000 --- a/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/LaunchCommand.java +++ /dev/null @@ -1,30 +0,0 @@ -package de.kentoj.scrow.bukkit.friends.command; - -import de.kentoj.scrow.bukkit.command.node.CommandNodeWithArgumentsImpl; -import de.kentoj.scrow.bukkit.services.command.CommandExecutor; -import de.kentoj.scrow.bukkit.services.command.context.CommandContext; -import de.kentoj.scrow.bukkit.services.command.type.EntityArgumentType; -import net.md_5.bungee.api.chat.TranslatableComponent; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; -import org.bukkit.util.Vector; - -public class LaunchCommand extends CommandNodeWithArgumentsImpl implements CommandExecutor { - - public LaunchCommand() { - super("launch"); - this.setDescription("launches a player in the air"); - this.setPermission(new Permission("bukkitcore.cmd.launch")); - - this.addArg("player", EntityArgumentType.player(), CommandContext::getSenderPlayer); - this.setExecutor(this); - } - - @Override - public void execute(CommandExecutionContext ctx) { - final Player player = ctx.getArg("player"); - player.spigot().sendMessage(new TranslatableComponent("")); - player.setVelocity(new Vector(0, 2, 0)); - player.sendMessage("Launched " + player.getName() + "."); - } -}