Refactor commands a bit

This commit is contained in:
Chipmunk 2023-03-12 20:51:15 -04:00
parent 9c1cd7096d
commit afa6f7ec8a
10 changed files with 100 additions and 87 deletions

View file

@ -1,15 +0,0 @@
package land.chipmunk.chipmunkbot.command;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import lombok.Getter;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
public class Command {
@Getter private LiteralCommandNode<CommandSource> node;
protected void node (LiteralCommandNode<CommandSource> node) { this.node = node; }
protected void node (LiteralArgumentBuilder<CommandSource> builder) { this.node = builder.build(); }
}

View file

@ -6,18 +6,19 @@ import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal;
import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument; import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
public class EchoCommand extends Command { public class EchoCommand {
public EchoCommand () { public static void register (CommandDispatcher dispatcher) {
super(); final EchoCommand instance = new EchoCommand();
this.node( dispatcher.register(
literal("echo") literal("echo")
.then( .then(
argument("text", greedyString()) argument("text", greedyString())
.executes(this::echo) .executes(instance::echo)
) )
); );
} }

View file

@ -6,22 +6,27 @@ import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal;
import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument; import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.JoinConfiguration; import net.kyori.adventure.text.JoinConfiguration;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
public class HelpCommand extends Command { public class HelpCommand {
public HelpCommand () { public static void register (CommandDispatcher dispatcher) {
super(); final HelpCommand instance = new HelpCommand();
this.node( dispatcher.register(
literal("help") literal("help")
.executes(this::sendCommandList) .executes(instance::sendCommandList)
.then(
argument("command", greedyString())
.executes(instance::sendUsage)
)
); );
} }
@ -29,30 +34,53 @@ public class HelpCommand extends Command {
final CommandSource source = context.getSource(); final CommandSource source = context.getSource();
final ChipmunkBot client = source.client(); final ChipmunkBot client = source.client();
final CommandDispatcher dispatcher = client.commandManager().dispatcher(); final CommandDispatcher<CommandSource> dispatcher = client.commandManager().dispatcher();
source.sendOutput(generateCommandList(dispatcher), false); source.sendOutput(generateCommandList(dispatcher), false);
return 1; return 1;
} }
public int sendUsage (CommandContext<CommandSource> context) throws CommandSyntaxException {
final CommandSource source = context.getSource();
final ChipmunkBot client = source.client();
final String commandName = getString(context, "command");
final CommandDispatcher<CommandSource> dispatcher = client.commandManager().dispatcher();
for (CommandNode<CommandSource> node : dispatcher.getRoot().getChildren()) {
if (!node.getName().equals(commandName)) continue;
source.sendOutput(generateUsages(dispatcher, node), false);
return 1;
}
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand().create();
}
public Component generateCommandList (CommandDispatcher<CommandSource> dispatcher) { public Component generateCommandList (CommandDispatcher<CommandSource> dispatcher) {
final List<Component> list = new ArrayList<>(); final List<Component> list = new ArrayList<>();
for (CommandNode<CommandSource> node : dispatcher.getRoot().getChildren()) { for (CommandNode<CommandSource> node : dispatcher.getRoot().getChildren()) {
final String name = node.getName(); final String name = node.getName();
final List<Component> usages = new ArrayList<>();
for (String usage : dispatcher.getAllUsage(node, null, false)) { final Component usages = generateUsages(dispatcher, node);
final String text = (name + " " + usage).trim(); final HoverEvent hoverEvent = HoverEvent.showText(usages);
usages.add(Component.text(text));
}
final HoverEvent hoverEvent = HoverEvent.showText(Component.join(JoinConfiguration.separator(Component.newline()), usages));
list.add(Component.text(name).hoverEvent(hoverEvent)); list.add(Component.text(name).hoverEvent(hoverEvent));
} }
return Component.translatable("Commands - %s", Component.join(JoinConfiguration.separator(Component.space()), list)); return Component.translatable("Commands - %s", Component.join(JoinConfiguration.separator(Component.space()), list));
} }
public Component generateUsages (CommandDispatcher dispatcher, CommandNode<CommandSource> node) {
final List<Component> usages = new ArrayList<>();
for (String usage : dispatcher.getAllUsage(node, null, true)) {
final String text = (node.getName() + " " + usage).trim();
usages.add(Component.text(text));
}
return Component.join(JoinConfiguration.separator(Component.newline()), usages);
}
} }

View file

@ -7,7 +7,6 @@ import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -18,18 +17,18 @@ import java.net.InetAddress;
import java.lang.management.*; import java.lang.management.*;
import java.io.IOException; import java.io.IOException;
public class InfoCommand extends Command { public class InfoCommand {
private static final String REPOSITORY_URL = "https://code.chipmunk.land/ChipmunkMC/chipmunkbot"; private static final String REPOSITORY_URL = "https://code.chipmunk.land/ChipmunkMC/chipmunkbot";
public InfoCommand () { public static void register (CommandDispatcher dispatcher) {
super(); final InfoCommand instance = new InfoCommand();
this.node( dispatcher.register(
literal("info") literal("info")
.executes(this::sendBotInfo) .executes(instance::sendBotInfo)
.then( .then(
literal("server") literal("server")
.executes(this::sendServerInfo) .executes(instance::sendServerInfo)
) )
); );
} }

View file

@ -15,6 +15,7 @@ import static land.chipmunk.chipmunkbot.command.arguments.LocationArgumentType.g
import static land.chipmunk.chipmunkbot.command.arguments.LocationArgumentType.getUrl; import static land.chipmunk.chipmunkbot.command.arguments.LocationArgumentType.getUrl;
import static land.chipmunk.chipmunkbot.command.arguments.TimestampArgumentType.timestamp; import static land.chipmunk.chipmunkbot.command.arguments.TimestampArgumentType.timestamp;
import static com.mojang.brigadier.arguments.LongArgumentType.getLong; import static com.mojang.brigadier.arguments.LongArgumentType.getLong;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
@ -25,45 +26,45 @@ import java.nio.file.Path;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
public class MusicCommand extends Command { public class MusicCommand {
private static SimpleCommandExceptionType NO_SONG_IS_CURRENTLY_PLAYING = new SimpleCommandExceptionType(ComponentMessage.wrap(Component.translatable("No song is currently playing"))); private static SimpleCommandExceptionType NO_SONG_IS_CURRENTLY_PLAYING = new SimpleCommandExceptionType(ComponentMessage.wrap(Component.translatable("No song is currently playing")));
private static SimpleCommandExceptionType OOB_TIMESTAMP = new SimpleCommandExceptionType(ComponentMessage.wrap(Component.translatable("Invalid timestamp for the current song"))); private static SimpleCommandExceptionType OOB_TIMESTAMP = new SimpleCommandExceptionType(ComponentMessage.wrap(Component.translatable("Invalid timestamp for the current song")));
private static SimpleCommandExceptionType DIRECTORY_DOES_NOT_EXIST = new SimpleCommandExceptionType(ComponentMessage.wrap(Component.translatable("The specified directory does not exist"))); private static SimpleCommandExceptionType DIRECTORY_DOES_NOT_EXIST = new SimpleCommandExceptionType(ComponentMessage.wrap(Component.translatable("The specified directory does not exist")));
public MusicCommand () { public static void register (CommandDispatcher dispatcher) {
super(); final MusicCommand instance = new MusicCommand();
Path root = Path.of(SongPlayer.SONG_DIR.getPath()); Path root = Path.of(SongPlayer.SONG_DIR.getPath());
this.node( dispatcher.register(
literal("music") literal("music")
.then( .then(
literal("play") literal("play")
.then( .then(
argument("location", location(root)) argument("location", location(root))
.executes(this::play) .executes(instance::play)
) )
) )
.then(literal("stop").executes(this::stop)) .then(literal("stop").executes(instance::stop))
.then(literal("skip").executes(this::skip)) .then(literal("skip").executes(instance::skip))
.then(literal("pause").executes(this::pause)) .then(literal("pause").executes(instance::pause))
.then( .then(
literal("list") literal("list")
.executes(c -> list(c, root)) .executes(c -> instance.list(c, root))
.then( .then(
argument("location", filepath(root)) argument("location", filepath(root))
.executes(c -> list(c, getPath(c, "location"))) .executes(c -> instance.list(c, getPath(c, "location")))
) )
) )
.then( .then(
literal("loop") literal("loop")
.executes(this::toggleLoop) .executes(instance::toggleLoop)
.then( .then(
argument("count", integer()) argument("count", integer())
.executes(this::loop) .executes(instance::loop)
) )
) )
@ -71,7 +72,7 @@ public class MusicCommand extends Command {
literal("goto") literal("goto")
.then( .then(
argument("timestamp", timestamp()) argument("timestamp", timestamp())
.executes(this::gotoCommand) .executes(instance::gotoCommand)
) )
) )
); );

View file

@ -7,6 +7,7 @@ import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal;
import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument; import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.github.steveice10.packetlib.Session; import com.github.steveice10.packetlib.Session;
import com.github.steveice10.packetlib.packet.PacketProtocol; import com.github.steveice10.packetlib.packet.PacketProtocol;
@ -15,15 +16,15 @@ import com.github.steveice10.mc.protocol.data.ProtocolState;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
public class NetMsgCommand extends Command { public class NetMsgCommand {
public NetMsgCommand () { public static void register (CommandDispatcher dispatcher) {
super(); final NetMsgCommand instance = new NetMsgCommand();
this.node( dispatcher.register(
literal("netmsg") literal("netmsg")
.then( .then(
argument("message", greedyString()) argument("message", greedyString())
.executes(this::netmsg) .executes(instance::netmsg)
) )
); );
} }

View file

@ -3,16 +3,17 @@ package land.chipmunk.chipmunkbot.commands;
import land.chipmunk.chipmunkbot.ChipmunkBot; import land.chipmunk.chipmunkbot.ChipmunkBot;
import land.chipmunk.chipmunkbot.command.*; import land.chipmunk.chipmunkbot.command.*;
import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal; import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
public class ReconnectCommand extends Command { public class ReconnectCommand {
public ReconnectCommand () { public static void register (CommandDispatcher dispatcher) {
super(); final ReconnectCommand instance = new ReconnectCommand();
this.node( dispatcher.register(
literal("reconnect") literal("reconnect")
.executes(this::reconnect) .executes(instance::reconnect)
); );
} }

View file

@ -6,6 +6,7 @@ import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal;
import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument; import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
@ -13,15 +14,15 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.StringTag;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class RunCommand extends Command { public class RunCommand {
public RunCommand () { public static void register (CommandDispatcher dispatcher) {
super(); final RunCommand instance = new RunCommand();
this.node( dispatcher.register(
literal("run") literal("run")
.then( .then(
argument("command", greedyString()) argument("command", greedyString())
.executes(this::run) .executes(instance::run)
) )
); );
} }

View file

@ -2,16 +2,17 @@ package land.chipmunk.chipmunkbot.commands;
import land.chipmunk.chipmunkbot.command.*; import land.chipmunk.chipmunkbot.command.*;
import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal; import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
public class TestCommand extends Command { public class TestCommand {
public TestCommand () { public static void register (CommandDispatcher dispatcher) {
super(); final TestCommand instance = new TestCommand();
this.node( dispatcher.register(
literal("test") literal("test")
.executes(this::helloWorld) .executes(instance::helloWorld)
); );
} }

View file

@ -1,7 +1,6 @@
package land.chipmunk.chipmunkbot.plugins; package land.chipmunk.chipmunkbot.plugins;
import land.chipmunk.chipmunkbot.ChipmunkBot; import land.chipmunk.chipmunkbot.ChipmunkBot;
import land.chipmunk.chipmunkbot.command.Command;
import land.chipmunk.chipmunkbot.command.CommandSource; import land.chipmunk.chipmunkbot.command.CommandSource;
import land.chipmunk.chipmunkbot.command.ComponentMessage; import land.chipmunk.chipmunkbot.command.ComponentMessage;
import land.chipmunk.chipmunkbot.command.BuiltInExceptions; import land.chipmunk.chipmunkbot.command.BuiltInExceptions;
@ -23,16 +22,6 @@ import lombok.Setter;
public class CommandManager { public class CommandManager {
private ChipmunkBot client; private ChipmunkBot client;
@Getter @Setter private CommandDispatcher<CommandSource> dispatcher = new CommandDispatcher<>(); @Getter @Setter private CommandDispatcher<CommandSource> dispatcher = new CommandDispatcher<>();
private final Command[] commands = {
new TestCommand(),
new HelpCommand(),
new RunCommand(),
new EchoCommand(),
new InfoCommand(),
new ReconnectCommand(),
new NetMsgCommand(),
new MusicCommand()
};
static { static {
// ? Is messing with static properties a good idea? // ? Is messing with static properties a good idea?
@ -42,8 +31,14 @@ public class CommandManager {
public CommandManager (ChipmunkBot client) { public CommandManager (ChipmunkBot client) {
this.client = client; this.client = client;
final RootCommandNode root = dispatcher.getRoot(); TestCommand.register(dispatcher);
for (Command command : commands) root.addChild(command.node()); HelpCommand.register(dispatcher);
RunCommand.register(dispatcher);
EchoCommand.register(dispatcher);
InfoCommand.register(dispatcher);
ReconnectCommand.register(dispatcher);
NetMsgCommand.register(dispatcher);
MusicCommand.register(dispatcher);
} }
public static void sendException (CommandSource source, CommandSyntaxException exception) { public static void sendException (CommandSource source, CommandSyntaxException exception) {