forked from chipmunkmc/chipmunkbot
commands mabe
* Added commands (**might change later**) * Fixed in stringifying translatable components * Fixed the kaboom chat parser a tiny bit
This commit is contained in:
parent
d0ea9a159d
commit
eddbe38e0e
17 changed files with 399 additions and 104 deletions
|
@ -0,0 +1,82 @@
|
|||
package land.chipmunk.chipmunkbot.command;
|
||||
|
||||
import com.mojang.brigadier.Message;
|
||||
import com.mojang.brigadier.exceptions.BuiltInExceptionProvider;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.CommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class BuiltInExceptions implements BuiltInExceptionProvider {
|
||||
private static final Dynamic2CommandExceptionType DOUBLE_TOO_SMALL = new Dynamic2CommandExceptionType((found, min) -> message("argument.double.low", text(min), text(found)));
|
||||
private static final Dynamic2CommandExceptionType DOUBLE_TOO_BIG = new Dynamic2CommandExceptionType((found, max) -> message("argument.double.big", text(max), text(found)));
|
||||
|
||||
private static final Dynamic2CommandExceptionType FLOAT_TOO_SMALL = new Dynamic2CommandExceptionType((found, min) -> message("argument.float.low", text(min), text(found)));
|
||||
private static final Dynamic2CommandExceptionType FLOAT_TOO_BIG = new Dynamic2CommandExceptionType((found, max) -> message("argument.float.big", text(max), text(found)));
|
||||
|
||||
private static final Dynamic2CommandExceptionType INTEGER_TOO_SMALL = new Dynamic2CommandExceptionType((found, min) -> message("argument.integer.low", text(min), text(found)));
|
||||
private static final Dynamic2CommandExceptionType INTEGER_TOO_BIG = new Dynamic2CommandExceptionType((found, max) -> message("argument.integer.big", text(max), text(found)));
|
||||
|
||||
private static final Dynamic2CommandExceptionType LONG_TOO_SMALL = new Dynamic2CommandExceptionType((found, min) -> message("argument.long.low", text(min), text(found)));
|
||||
private static final Dynamic2CommandExceptionType LONG_TOO_BIG = new Dynamic2CommandExceptionType((found, max) -> message("argument.long.big", text(max), text(found)));
|
||||
|
||||
private static final DynamicCommandExceptionType LITERAL_INCORRECT = new DynamicCommandExceptionType(expected -> message("argument.literal.incorrect", text(expected)));
|
||||
|
||||
private static final SimpleCommandExceptionType READER_EXPECTED_START_OF_QUOTE = new SimpleCommandExceptionType(message("parsing.quote.expected.start"));
|
||||
private static final SimpleCommandExceptionType READER_EXPECTED_END_OF_QUOTE = new SimpleCommandExceptionType(message("parsing.quote.expected.end"));
|
||||
private static final DynamicCommandExceptionType READER_INVALID_ESCAPE = new DynamicCommandExceptionType(character -> message("parsing.quote.escape", text(character)));
|
||||
private static final DynamicCommandExceptionType READER_INVALID_BOOL = new DynamicCommandExceptionType(value -> message("parsing.bool.invalid", text(value)));
|
||||
private static final DynamicCommandExceptionType READER_INVALID_INT = new DynamicCommandExceptionType(value -> message("parsing.int.invalid", text(value)));
|
||||
private static final SimpleCommandExceptionType READER_EXPECTED_INT = new SimpleCommandExceptionType(message("parsing.int.expected"));
|
||||
private static final DynamicCommandExceptionType READER_INVALID_LONG = new DynamicCommandExceptionType(value -> message("parsing.long.invalid", text(value)));
|
||||
private static final SimpleCommandExceptionType READER_EXPECTED_LONG = new SimpleCommandExceptionType(message("parsing.long.expected"));
|
||||
private static final DynamicCommandExceptionType READER_INVALID_DOUBLE = new DynamicCommandExceptionType(value -> message("parsing.double.invalid", text(value)));
|
||||
private static final SimpleCommandExceptionType READER_EXPECTED_DOUBLE = new SimpleCommandExceptionType(message("parsing.double.expected"));
|
||||
private static final DynamicCommandExceptionType READER_INVALID_FLOAT = new DynamicCommandExceptionType(value -> message("parsing.float.invalid", text(value)));
|
||||
private static final SimpleCommandExceptionType READER_EXPECTED_FLOAT = new SimpleCommandExceptionType(message("parsing.float.expected"));
|
||||
private static final SimpleCommandExceptionType READER_EXPECTED_BOOL = new SimpleCommandExceptionType(message("parsing.bool.expected"));
|
||||
private static final DynamicCommandExceptionType READER_EXPECTED_SYMBOL = new DynamicCommandExceptionType(symbol -> message("parsing.expected", text(symbol)));
|
||||
|
||||
private static final SimpleCommandExceptionType DISPATCHER_UNKNOWN_COMMAND = new SimpleCommandExceptionType(message("command.unknown.command"));
|
||||
private static final SimpleCommandExceptionType DISPATCHER_UNKNOWN_ARGUMENT = new SimpleCommandExceptionType(message("command.unknown.argument"));
|
||||
private static final SimpleCommandExceptionType DISPATCHER_EXPECTED_ARGUMENT_SEPARATOR = new SimpleCommandExceptionType(message("command.expected.separator"));
|
||||
private static final DynamicCommandExceptionType DISPATCHER_PARSE_EXCEPTION = new DynamicCommandExceptionType(_message -> message("command.exception", text(_message)));
|
||||
|
||||
@Override public Dynamic2CommandExceptionType doubleTooLow () { return DOUBLE_TOO_SMALL; }
|
||||
@Override public Dynamic2CommandExceptionType doubleTooHigh () { return DOUBLE_TOO_BIG; }
|
||||
@Override public Dynamic2CommandExceptionType floatTooLow () { return FLOAT_TOO_SMALL; }
|
||||
@Override public Dynamic2CommandExceptionType floatTooHigh () { return FLOAT_TOO_BIG; }
|
||||
@Override public Dynamic2CommandExceptionType integerTooLow () { return INTEGER_TOO_SMALL; }
|
||||
@Override public Dynamic2CommandExceptionType integerTooHigh () { return INTEGER_TOO_BIG; }
|
||||
@Override public Dynamic2CommandExceptionType longTooLow () { return LONG_TOO_SMALL; }
|
||||
@Override public Dynamic2CommandExceptionType longTooHigh () { return LONG_TOO_BIG; }
|
||||
@Override public DynamicCommandExceptionType literalIncorrect () { return LITERAL_INCORRECT; }
|
||||
@Override public SimpleCommandExceptionType readerExpectedStartOfQuote () { return READER_EXPECTED_START_OF_QUOTE; }
|
||||
@Override public SimpleCommandExceptionType readerExpectedEndOfQuote () { return READER_EXPECTED_END_OF_QUOTE; }
|
||||
@Override public DynamicCommandExceptionType readerInvalidEscape () { return READER_INVALID_ESCAPE; }
|
||||
@Override public DynamicCommandExceptionType readerInvalidBool () { return READER_INVALID_BOOL; }
|
||||
@Override public DynamicCommandExceptionType readerInvalidInt () { return READER_INVALID_INT; }
|
||||
@Override public SimpleCommandExceptionType readerExpectedInt () { return READER_EXPECTED_INT; }
|
||||
@Override public DynamicCommandExceptionType readerInvalidLong () { return READER_INVALID_LONG; }
|
||||
@Override public SimpleCommandExceptionType readerExpectedLong () { return READER_EXPECTED_LONG; }
|
||||
@Override public DynamicCommandExceptionType readerInvalidDouble () { return READER_INVALID_DOUBLE; }
|
||||
@Override public SimpleCommandExceptionType readerExpectedDouble () { return READER_EXPECTED_DOUBLE; }
|
||||
@Override public DynamicCommandExceptionType readerInvalidFloat () { return READER_INVALID_FLOAT; }
|
||||
@Override public SimpleCommandExceptionType readerExpectedFloat () { return READER_EXPECTED_FLOAT; }
|
||||
@Override public SimpleCommandExceptionType readerExpectedBool () { return READER_EXPECTED_BOOL; }
|
||||
@Override public DynamicCommandExceptionType readerExpectedSymbol () { return READER_EXPECTED_SYMBOL; }
|
||||
@Override public SimpleCommandExceptionType dispatcherUnknownCommand () { return DISPATCHER_UNKNOWN_COMMAND; }
|
||||
@Override public SimpleCommandExceptionType dispatcherUnknownArgument () { return DISPATCHER_UNKNOWN_ARGUMENT; }
|
||||
@Override public SimpleCommandExceptionType dispatcherExpectedArgumentSeparator () { return DISPATCHER_EXPECTED_ARGUMENT_SEPARATOR; }
|
||||
@Override public DynamicCommandExceptionType dispatcherParseException () { return DISPATCHER_PARSE_EXCEPTION; }
|
||||
|
||||
private static Message message (final String key, final ComponentLike... args) { return ComponentMessage.wrap(Component.translatable(key, args)); }
|
||||
private static TextComponent text (final Object text) { return Component.text(String.valueOf(text)); }
|
||||
}
|
13
src/main/java/land/chipmunk/chipmunkbot/command/Command.java
Normal file
13
src/main/java/land/chipmunk/chipmunkbot/command/Command.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package land.chipmunk.chipmunkbot.command;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import lombok.Data;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Command {
|
||||
private LiteralArgumentBuilder<CommandSource> builder;
|
||||
}
|
|
@ -1,12 +1,27 @@
|
|||
package land.chipmunk.chipmunkbot.command;
|
||||
|
||||
import com.mojang.brigadier.Message;
|
||||
import land.chipmunk.chipmunkbot.data.MutablePlayerListEntry;
|
||||
import land.chipmunk.chipmunkbot.ChipmunkBot;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import lombok.Getter;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class CommandSource {
|
||||
@Getter private final ChipmunkBot client;
|
||||
|
||||
public interface CommandSource {
|
||||
// ? Should I support message objects?
|
||||
void sendOutput (Component message, boolean broadcast);
|
||||
void sendOutput (Component message);
|
||||
public void sendOutput (Component message, boolean broadcast) {}
|
||||
public void sendOutput (Component message) { sendOutput(message, true); }
|
||||
|
||||
Component displayName ();
|
||||
public Component displayName () { return Component.empty(); }
|
||||
|
||||
public MutablePlayerListEntry player () { return null; }
|
||||
|
||||
public MutablePlayerListEntry playerOrThrow () {
|
||||
MutablePlayerListEntry player = player();
|
||||
// if (player == null) throw new CommandSyntaxException(Component.text("Command must be executed by a player"));
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
package land.chipmunk.chipmunkbot.command;
|
||||
|
||||
import com.mojang.brigadier.Message;
|
||||
import com.mojang.brigadier.exceptions.BuiltInExceptionProvider;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.CommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CommandSyntaxErrorTypeMap {
|
||||
private CommandSyntaxErrorTypeMap () {
|
||||
}
|
||||
|
||||
// Just some methods for stuff repeated a lot
|
||||
private static Message message (final String key, final ComponentLike... args) { return ComponentMessage.wrap(Component.translatable(key, args)); }
|
||||
private static TextComponent text (final Object text) { return Component.text(String.valueOf(text)); }
|
||||
private static TextComponent text (final int text) { return Component.text(text); }
|
||||
private static TextComponent text (final char text) { return Component.text(String.valueOf(text)); }
|
||||
|
||||
public static Map<CommandExceptionType, CommandExceptionType> map = new HashMap<>();
|
||||
|
||||
static {
|
||||
final BuiltInExceptionProvider builtIn = CommandSyntaxException.BUILT_IN_EXCEPTIONS;
|
||||
|
||||
map.put(builtIn.doubleTooLow(), new Dynamic2CommandExceptionType((found, min) -> message("argument.double.low", text(min), text(found))));
|
||||
map.put(builtIn.doubleTooHigh(), new Dynamic2CommandExceptionType((found, max) -> message("argument.double.big", text(max), text(found))));
|
||||
|
||||
map.put(builtIn.floatTooLow(), new Dynamic2CommandExceptionType((found, min) -> message("argument.float.low", text(min), text(found))));
|
||||
map.put(builtIn.floatTooHigh(), new Dynamic2CommandExceptionType((found, max) -> message("argument.float.big", text(max), text(found))));
|
||||
|
||||
map.put(builtIn.integerTooLow(), new Dynamic2CommandExceptionType((found, min) -> message("argument.integer.low", text(min), text(found))));
|
||||
map.put(builtIn.integerTooHigh(), new Dynamic2CommandExceptionType((found, max) -> message("argument.integer.big", text(max), text(found))));
|
||||
|
||||
map.put(builtIn.longTooLow(), new Dynamic2CommandExceptionType((found, min) -> message("argument.long.low", text(min), text(found))));
|
||||
map.put(builtIn.longTooHigh(), new Dynamic2CommandExceptionType((found, max) -> message("argument.long.big", text(max), text(found))));
|
||||
|
||||
map.put(builtIn.literalIncorrect(), new DynamicCommandExceptionType(expected -> message("argument.literal.incorrect", text(expected))));
|
||||
|
||||
map.put(builtIn.readerExpectedStartOfQuote(), new SimpleCommandExceptionType(message("parsing.quote.expected.start")));
|
||||
map.put(builtIn.readerExpectedEndOfQuote(), new SimpleCommandExceptionType(message("parsing.quote.expected.end")));
|
||||
map.put(builtIn.readerInvalidEscape(), new DynamicCommandExceptionType(character -> message("parsing.quote.escape", text(character))));
|
||||
map.put(builtIn.readerInvalidBool(), new DynamicCommandExceptionType(value -> message("parsing.bool.invalid", text(value))));
|
||||
map.put(builtIn.readerInvalidInt(), new DynamicCommandExceptionType(value -> message("parsing.int.invalid", text(value))));
|
||||
map.put(builtIn.readerExpectedInt(), new SimpleCommandExceptionType(message("parsing.int.expected")));
|
||||
map.put(builtIn.readerInvalidLong(), new DynamicCommandExceptionType(value -> message("parsing.long.invalid", text(value))));
|
||||
map.put(builtIn.readerExpectedLong(), new SimpleCommandExceptionType(message("parsing.long.expected")));
|
||||
map.put(builtIn.readerInvalidDouble(), new DynamicCommandExceptionType(value -> message("parsing.double.invalid", text(value))));
|
||||
map.put(builtIn.readerExpectedDouble(), new SimpleCommandExceptionType(message("parsing.double.expected")));
|
||||
map.put(builtIn.readerInvalidFloat(), new DynamicCommandExceptionType(value -> message("parsing.float.invalid", text(value))));
|
||||
map.put(builtIn.readerExpectedFloat(), new SimpleCommandExceptionType(message("parsing.float.expected")));
|
||||
map.put(builtIn.readerExpectedBool(), new SimpleCommandExceptionType(message("parsing.bool.expected")));
|
||||
map.put(builtIn.readerExpectedSymbol(), new DynamicCommandExceptionType(symbol -> message("parsing.expected", text(symbol))));
|
||||
|
||||
map.put(builtIn.dispatcherUnknownCommand(), new SimpleCommandExceptionType(message("command.unknown.command")));
|
||||
map.put(builtIn.dispatcherUnknownArgument(), new SimpleCommandExceptionType(message("command.unknown.argument")));
|
||||
map.put(builtIn.dispatcherExpectedArgumentSeparator(), new SimpleCommandExceptionType(message("command.expected.separator")));
|
||||
map.put(builtIn.dispatcherParseException(), new SimpleCommandExceptionType(message("command.exception")));
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package land.chipmunk.chipmunkbot.command;
|
||||
|
||||
import land.chipmunk.chipmunkbot.util.ComponentUtilities;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import com.mojang.brigadier.Message;
|
||||
import lombok.Getter;
|
||||
|
@ -16,7 +17,7 @@ public class ComponentMessage implements Message {
|
|||
}
|
||||
|
||||
public String getString () {
|
||||
return component.toString(); // ? Is this the best way to get the string?
|
||||
return ComponentUtilities.stringify(component);
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package land.chipmunk.chipmunkbot.command;
|
||||
|
||||
import com.mojang.brigadier.Message;
|
||||
import land.chipmunk.chipmunkbot.ChipmunkBot;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
|
||||
public class ConsoleCommandSource extends CommandSource {
|
||||
public ConsoleCommandSource (ChipmunkBot client) { super(client); }
|
||||
|
||||
public class ConsoleCommandSource implements CommandSource {
|
||||
@Override
|
||||
public void sendOutput (Component message, boolean broadcast) {
|
||||
System.out.println(message);
|
||||
// TODO: broadcast
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendOutput (Component message) {
|
||||
sendOutput(message, true);
|
||||
if (broadcast) client().chat().tellraw(Component.translatable("chat.type.admin", displayName(), message).color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package land.chipmunk.chipmunkbot.command;
|
||||
|
||||
import land.chipmunk.chipmunkbot.data.MutablePlayerListEntry;
|
||||
import land.chipmunk.chipmunkbot.util.UUIDUtilities;
|
||||
import land.chipmunk.chipmunkbot.ChipmunkBot;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerCommandSource extends CommandSource {
|
||||
private final MutablePlayerListEntry player;
|
||||
|
||||
public PlayerCommandSource (ChipmunkBot client, MutablePlayerListEntry entry) {
|
||||
super(client);
|
||||
player = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendOutput (Component message, boolean broadcast) {
|
||||
final UUID uuid = player.profile().getId();
|
||||
|
||||
client().chat().tellraw(message, uuid);
|
||||
if (broadcast) client().chat().tellraw(Component.translatable("chat.type.admin", displayName(), message).color(NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, true), UUIDUtilities.exclusiveSelector(uuid));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component displayName () {
|
||||
final Component explicitDisplayName = player.displayName();
|
||||
final Component displayName = explicitDisplayName != null ? explicitDisplayName : Component.text(player.profile().getName());
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@Override public MutablePlayerListEntry player () { return this.player; }
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package land.chipmunk.chipmunkbot.commands;
|
||||
|
||||
import land.chipmunk.chipmunkbot.ChipmunkBot;
|
||||
import land.chipmunk.chipmunkbot.command.*;
|
||||
import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal;
|
||||
import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class HelpCommand extends Command {
|
||||
public HelpCommand () {
|
||||
super();
|
||||
|
||||
this.builder(
|
||||
literal("help")
|
||||
.executes(this::sendCommandList)
|
||||
);
|
||||
}
|
||||
|
||||
public int sendCommandList (CommandContext<CommandSource> context) {
|
||||
final CommandSource source = context.getSource();
|
||||
final ChipmunkBot client = source.client();
|
||||
|
||||
final CommandDispatcher dispatcher = client.commandManager().dispatcher();
|
||||
|
||||
source.sendOutput(generateCommandList(dispatcher), false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Component generateCommandList (CommandDispatcher<CommandSource> dispatcher) {
|
||||
final List<Component> list = new ArrayList<>();
|
||||
|
||||
for (CommandNode<CommandSource> node : dispatcher.getRoot().getChildren()) {
|
||||
final String name = node.getName();
|
||||
final List<Component> usages = new ArrayList<>();
|
||||
|
||||
for (String usage : dispatcher.getAllUsage(node, null, false)) {
|
||||
final String text = (name + " " + usage).trim();
|
||||
usages.add(Component.text(text));
|
||||
}
|
||||
|
||||
final HoverEvent hoverEvent = HoverEvent.showText(Component.join(JoinConfiguration.separator(Component.newline()), usages));
|
||||
|
||||
list.add(Component.text(name).hoverEvent(hoverEvent));
|
||||
}
|
||||
|
||||
return Component.translatable("Commands - %s", Component.join(JoinConfiguration.separator(Component.space()), list));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package land.chipmunk.chipmunkbot.commands;
|
||||
|
||||
import land.chipmunk.chipmunkbot.ChipmunkBot;
|
||||
import land.chipmunk.chipmunkbot.command.*;
|
||||
import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal;
|
||||
import static land.chipmunk.chipmunkbot.plugins.CommandManager.argument;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
||||
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
public class RunCommand extends Command {
|
||||
public RunCommand () {
|
||||
super();
|
||||
|
||||
this.builder(
|
||||
literal("run")
|
||||
.then(
|
||||
argument("command", greedyString())
|
||||
.executes(this::run)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public int run (CommandContext<CommandSource> context) {
|
||||
final CommandSource source = context.getSource();
|
||||
final ChipmunkBot client = source.client();
|
||||
|
||||
client.core().run(getString(context, "command"));
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package land.chipmunk.chipmunkbot.commands;
|
||||
|
||||
import land.chipmunk.chipmunkbot.command.*;
|
||||
import static land.chipmunk.chipmunkbot.plugins.CommandManager.literal;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
public class TestCommand extends Command {
|
||||
public TestCommand () {
|
||||
super();
|
||||
|
||||
this.builder(
|
||||
literal("test")
|
||||
.executes(this::helloWorld)
|
||||
);
|
||||
}
|
||||
|
||||
public int helloWorld (CommandContext<CommandSource> context) {
|
||||
CommandSource source = context.getSource();
|
||||
source.sendOutput(Component.text("Hello, world!"));
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -2,11 +2,17 @@ package land.chipmunk.chipmunkbot.plugins;
|
|||
|
||||
import land.chipmunk.chipmunkbot.ChipmunkBot;
|
||||
import land.chipmunk.chipmunkbot.command.CommandSource;
|
||||
import land.chipmunk.chipmunkbot.command.PlayerCommandSource;
|
||||
import land.chipmunk.chipmunkbot.command.ComponentMessage;
|
||||
import land.chipmunk.chipmunkbot.plugins.ChatPlugin;
|
||||
import land.chipmunk.chipmunkbot.data.chat.PlayerMessage;
|
||||
import land.chipmunk.chipmunkbot.chat.ComponentUtilities;
|
||||
import land.chipmunk.chipmunkbot.util.ComponentUtilities;
|
||||
import land.chipmunk.chipmunkbot.plugins.CommandManager;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.Message;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
@ -27,6 +33,16 @@ public class ChatCommandHandler extends ChatPlugin.Listener {
|
|||
if (!contentsString.startsWith(prefix)) return;
|
||||
final String commandString = contentsString.substring(prefix.length());
|
||||
|
||||
// System.out.println(ComponentUtilities.stringify(message.parameters().get("sender")) + " issued the command " + commandString);
|
||||
final PlayerCommandSource source = new PlayerCommandSource(client, message.sender());
|
||||
|
||||
try {
|
||||
CommandDispatcher dispatcher = client.commandManager().dispatcher();
|
||||
dispatcher.execute(commandString, source);
|
||||
} catch (CommandSyntaxException exception) {
|
||||
CommandManager.sendException(source, exception);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
source.sendOutput(Component.translatable("command.failed", NamedTextColor.RED), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package land.chipmunk.chipmunkbot.plugins;
|
|||
import land.chipmunk.chipmunkbot.ChipmunkBot;
|
||||
import land.chipmunk.chipmunkbot.data.chat.PlayerMessage;
|
||||
import land.chipmunk.chipmunkbot.data.chat.SystemChatParser;
|
||||
import land.chipmunk.chipmunkbot.util.UUIDUtilities;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerChatPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket;
|
||||
|
@ -12,9 +13,11 @@ import com.github.steveice10.packetlib.Session;
|
|||
import com.github.steveice10.packetlib.event.session.SessionAdapter;
|
||||
import com.github.steveice10.packetlib.event.session.SessionListener;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import java.util.BitSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.time.Instant;
|
||||
|
||||
import land.chipmunk.chipmunkbot.systemChat.*;
|
||||
|
@ -67,6 +70,13 @@ public class ChatPlugin extends SessionAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
// ? Should this be here?
|
||||
public void tellraw (Component message, String targets) {
|
||||
client.core.run("minecraft:tellraw " + targets + " " + GsonComponentSerializer.gson().serialize(message));
|
||||
}
|
||||
public void tellraw (Component message) { tellraw(message, "@a"); }
|
||||
public void tellraw (Component message, UUID uuid) { tellraw(message, UUIDUtilities.selector(uuid)); }
|
||||
|
||||
public void addListener (Listener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
|
|
@ -1,19 +1,77 @@
|
|||
package land.chipmunk.chipmunkbot.plugins;
|
||||
|
||||
import land.chipmunk.chipmunkbot.ChipmunkBot;
|
||||
import land.chipmunk.chipmunkbot.command.Command;
|
||||
import land.chipmunk.chipmunkbot.command.CommandSource;
|
||||
import land.chipmunk.chipmunkbot.chat.ComponentUtilities;
|
||||
import land.chipmunk.chipmunkbot.command.ComponentMessage;
|
||||
import land.chipmunk.chipmunkbot.command.BuiltInExceptions;
|
||||
import land.chipmunk.chipmunkbot.commands.*;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
import com.mojang.brigadier.Message;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class CommandManager {
|
||||
private ChipmunkBot client;
|
||||
@Getter @Setter private CommandDispatcher<CommandSource> dispatcher = new CommandDispatcher<>();
|
||||
@Getter @Setter private String prefix = "'"; // TODO: Don't hardcode this
|
||||
private final Command[] commands = {new TestCommand(), new HelpCommand(), new RunCommand()};
|
||||
|
||||
static {
|
||||
// ? Is messing with static properties a good idea?
|
||||
CommandSyntaxException.BUILT_IN_EXCEPTIONS = new BuiltInExceptions();
|
||||
}
|
||||
|
||||
public CommandManager (ChipmunkBot client) {
|
||||
this.client = client;
|
||||
|
||||
for (Command command : commands) dispatcher.register(command.builder());
|
||||
}
|
||||
|
||||
public static void sendException (CommandSource source, CommandSyntaxException exception) {
|
||||
final Message message = exception.getRawMessage();
|
||||
Component component;
|
||||
if (message instanceof ComponentMessage) component = ((ComponentMessage) message).component();
|
||||
else component = Component.text(message.getString());
|
||||
|
||||
source.sendOutput(component.color(NamedTextColor.RED), false);
|
||||
|
||||
final Component context = getContext(exception);
|
||||
if (context != null) source.sendOutput(context, false);
|
||||
}
|
||||
|
||||
public static Component getContext (CommandSyntaxException exception) {
|
||||
final int _cursor = exception.getCursor();
|
||||
final String input = exception.getInput();
|
||||
|
||||
if (input == null || _cursor < 0) {
|
||||
return null;
|
||||
}
|
||||
Component component = Component.empty()
|
||||
.color(NamedTextColor.GRAY)
|
||||
.clickEvent(ClickEvent.suggestCommand(input));
|
||||
|
||||
final int cursor = Math.min(input.length(), _cursor);
|
||||
|
||||
if (cursor > CommandSyntaxException.CONTEXT_AMOUNT) {
|
||||
component = component.append(Component.text("..."));
|
||||
}
|
||||
|
||||
component = component
|
||||
.append(Component.text(input.substring(Math.max(0, cursor - CommandSyntaxException.CONTEXT_AMOUNT), cursor)))
|
||||
.append(Component.text(input.substring(cursor), NamedTextColor.RED).decoration(TextDecoration.UNDERLINED, true))
|
||||
.append(Component.translatable("command.context.here", NamedTextColor.RED).decoration(TextDecoration.ITALIC, true));
|
||||
|
||||
return Component.empty().color(NamedTextColor.RED).append(component); // ? Should I Impostor Notchian here?
|
||||
}
|
||||
|
||||
public static LiteralArgumentBuilder<CommandSource> literal(String name) { return LiteralArgumentBuilder.<CommandSource>literal(name); }
|
||||
public static <T> RequiredArgumentBuilder<CommandSource, T> argument(String name, ArgumentType<T> type) { return RequiredArgumentBuilder.<CommandSource, T>argument(name, type); }
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
package land.chipmunk.chipmunkbot.plugins;
|
||||
|
||||
import land.chipmunk.chipmunkbot.ChipmunkBot;
|
||||
import land.chipmunk.chipmunkbot.command.CommandSource;
|
||||
import land.chipmunk.chipmunkbot.chat.ComponentUtilities;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class CommandManagerPlugin {
|
||||
private ChipmunkBot client;
|
||||
@Getter @Setter private CommandDispatcher<CommandSource> dispatcher = new CommandDispatcher<>();
|
||||
|
||||
public CommandManagerPlugin (ChipmunkBot client) {
|
||||
this.client = client;
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ public class KaboomChatParser implements SystemChatParser {
|
|||
}
|
||||
|
||||
public PlayerMessage parse (TranslatableComponent message) {
|
||||
if (!message.key().equals("%") || message.args() == null || message.args().size() != 1 || !message.style().equals(empty)) return parse(message.args().get(0));
|
||||
if (message.key().equals("%s") && message.args() != null && message.args().size() == 1 && message.style().equals(empty)) return parse(message.args().get(0));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package land.chipmunk.chipmunkbot.chat;
|
||||
package land.chipmunk.chipmunkbot.util;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
@ -80,7 +80,7 @@ public class ComponentUtilities {
|
|||
matcher.appendReplacement(sb, "%");
|
||||
} else {
|
||||
String idxStr = matcher.group(1);
|
||||
int idx = (idxStr == null ? i++ : Integer.parseInt(idxStr)) - 1;
|
||||
int idx = idxStr == null ? i++ : (Integer.parseInt(idxStr) - 1);
|
||||
if (idx >= 0 && idx < message.args().size()) {
|
||||
matcher.appendReplacement(sb, Matcher.quoteReplacement( stringify(message.args().get(idx)) ));
|
||||
} else {
|
|
@ -0,0 +1,33 @@
|
|||
package land.chipmunk.chipmunkbot.util;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
|
||||
import java.util.UUID;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class UUIDUtilities {
|
||||
private UUIDUtilities () {
|
||||
}
|
||||
|
||||
public static int[] intArray (UUID uuid) {
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(new byte[16]);
|
||||
buffer.putLong(0, uuid.getMostSignificantBits());
|
||||
buffer.putLong(8, uuid.getLeastSignificantBits());
|
||||
|
||||
final int[] intArray = new int[4];
|
||||
for (int i = 0; i < intArray.length; i++) intArray[i] = buffer.getInt();
|
||||
|
||||
return intArray;
|
||||
}
|
||||
|
||||
public static IntArrayTag tag (UUID uuid) {
|
||||
return new IntArrayTag("", intArray(uuid));
|
||||
}
|
||||
|
||||
public static String snbt (UUID uuid) {
|
||||
int[] array = intArray(uuid);
|
||||
return "[I;" + array[0] + "," + array[1] + "," + array[2] + "," + array[3] + "]"; // TODO: improve lol
|
||||
}
|
||||
|
||||
public static String selector (UUID uuid) { return "@a[limit=1,nbt={UUID:" + snbt(uuid) + "}]"; }
|
||||
public static String exclusiveSelector (UUID uuid) { return "@a[nbt=!{UUID:" + snbt(uuid) + "}]"; }
|
||||
}
|
Loading…
Reference in a new issue