Merge remote-tracking branch 'original/main'

# Conflicts:
#	src/main/java/land/chipmunk/chipmunkbot/Options.java
#	src/main/java/land/chipmunk/chipmunkbot/plugins/PlayerCommandHandler.java
This commit is contained in:
Chayapak 2023-05-23 19:29:36 +07:00
commit ae837c897c
7 changed files with 164 additions and 51 deletions

View file

@ -13,8 +13,9 @@ public class ChipmunkBot extends Client {
@Getter private final TabCompletePlugin tabComplete; @Getter private final TabCompletePlugin tabComplete;
@Getter private final QueryPlugin query; @Getter private final QueryPlugin query;
@Getter private final PlayerListPlugin playerList; @Getter private final PlayerListPlugin playerList;
@Getter private final CommandSpyPlugin commandSpy;
@Getter private final CommandManager commandManager; @Getter private final CommandManager commandManager;
@Getter private final ChatCommandHandler chatCommandHandler; @Getter private final PlayerCommandHandler playerCommandHandler;
@Getter private final PositionManager position; @Getter private final PositionManager position;
@Getter private final CommandCore core; @Getter private final CommandCore core;
@Getter private final SelfCarePlugin selfCare; @Getter private final SelfCarePlugin selfCare;
@ -30,8 +31,9 @@ public class ChipmunkBot extends Client {
this.tabComplete = new TabCompletePlugin(this); this.tabComplete = new TabCompletePlugin(this);
this.query = new QueryPlugin(this); this.query = new QueryPlugin(this);
this.playerList = new PlayerListPlugin(this); this.playerList = new PlayerListPlugin(this);
this.commandSpy = new CommandSpyPlugin(this);
this.commandManager = new CommandManager(this); this.commandManager = new CommandManager(this);
this.chatCommandHandler = new ChatCommandHandler(this, options); this.playerCommandHandler = new PlayerCommandHandler(this, options);
this.position = new PositionManager(this); this.position = new PositionManager(this);
this.core = new CommandCore(this, options); this.core = new CommandCore(this, options);
this.selfCare = new SelfCarePlugin(this); this.selfCare = new SelfCarePlugin(this);

View file

@ -149,7 +149,7 @@ public class MusicCommand {
public int list (CommandContext<CommandSource> context, Path path) throws CommandSyntaxException { public int list (CommandContext<CommandSource> context, Path path) throws CommandSyntaxException {
final CommandSource source = context.getSource(); final CommandSource source = context.getSource();
final ChipmunkBot client = source.client(); final ChipmunkBot client = source.client();
final String prefix = client.chatCommandHandler().prefix(); final String prefix = client.playerCommandHandler().prefix();
final File directory = path.toFile(); final File directory = path.toFile();
final String[] filenames = directory.list(); final String[] filenames = directory.list();

View file

@ -1,45 +0,0 @@
package land.chipmunk.chipmunkbot.plugins;
import land.chipmunk.chipmunkbot.ChipmunkBot;
import land.chipmunk.chipmunkbot.Configuration;
import land.chipmunk.chipmunkbot.command.PlayerCommandSource;
import land.chipmunk.chipmunkbot.data.chat.PlayerMessage;
import land.chipmunk.chipmunkbot.util.ComponentUtilities;
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 lombok.Getter;
import lombok.Setter;
public class ChatCommandHandler extends ChatPlugin.Listener {
private ChipmunkBot client;
@Getter @Setter private String prefix;
public ChatCommandHandler (ChipmunkBot client, Configuration.Bot options) {
this.client = client;
this.prefix = options.commands.prefix;
client.chat().addListener((ChatPlugin.Listener) this);
}
@Override
public void playerMessageReceived (PlayerMessage message) {
final Component contents = message.contents();
if (contents == null) return;
final String contentsString = ComponentUtilities.stringify(contents);
if (!contentsString.startsWith(prefix)) return;
final String commandString = contentsString.substring(prefix.length());
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);
}
}
}

View file

@ -0,0 +1,88 @@
package land.chipmunk.chipmunkbot.plugins;
import land.chipmunk.chipmunkbot.ChipmunkBot;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.NamedTextColor;
import land.chipmunk.chipmunkbot.data.MutablePlayerListEntry;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.ArrayList;
public class CommandSpyPlugin extends ChatPlugin.Listener {
private final ChipmunkBot client;
@Getter private List<Listener> listeners = new ArrayList<>();
@Getter @Setter private boolean enabled = false;
private static final Style ENABLED_STYLE = Style.style(NamedTextColor.YELLOW);
private static final Style DISABLED_STYLE = Style.style(NamedTextColor.AQUA);
private static final Component COMMANDSPY_ENABLED_COMPONENT = Component.text("Successfully enabled CommandSpy");
private static final Component COMMANDSPY_DISABLED_COMPONENT = Component.text("Successfully disabled CommandSpy");
private static final Component COMMAND_SEPARATOR_COMPONENT = Component.text(": ");
private static final Component SIGN_CREATED_TEXT_COMPONENT = Component.text(" created a sign with contents:");
private static final Component SIGN_LINE_SEPARATOR_COMPONENT = Component.text("\n ");
public CommandSpyPlugin (ChipmunkBot client) {
this.client = client;
client.chat().addListener((ChatPlugin.Listener) this);
}
@Override
public void systemMessageReceived (Component component, boolean overlay) {
if (overlay || !(component instanceof final TextComponent t_component)) return;
if (component.equals(COMMANDSPY_ENABLED_COMPONENT)) { this.enabled = true; return; }
if (component.equals(COMMANDSPY_DISABLED_COMPONENT)) { this.enabled = false; return; }
final boolean enabled = component.style().equals(ENABLED_STYLE);
if (!enabled && !component.style().equals(DISABLED_STYLE)) return;
final String username = t_component.content();
final MutablePlayerListEntry sender = client.playerList().getEntry(username);
if (sender == null) return;
final List<Component> children = component.children();
if (children.size() == 2) {
// Command
final Component separator = children.get(0);
final Component prefixedCommand = children.get(1);
if (
!(separator instanceof final TextComponent t_separator) ||
!(prefixedCommand instanceof final TextComponent t_prefixedCommand) ||
!separator.equals(COMMAND_SEPARATOR_COMPONENT) ||
!prefixedCommand.style().isEmpty()
) return;
final String command = t_prefixedCommand.content();
if (command.length() < 1 || command.charAt(0) != '/') return;
final String rawCommand = command.substring(1);
for (Listener listener : listeners) listener.commandReceived(sender, rawCommand, enabled);
} else if (children.size() == 9) {
// Sign created
final Component[] lines = new Component[4];
if (!children.get(0).equals(SIGN_CREATED_TEXT_COMPONENT)) return;
for (int i = 0; i < lines.length; i++) {
int separatorChildIndex = (i * 2) + 1;
if (!children.get(separatorChildIndex).equals(SIGN_LINE_SEPARATOR_COMPONENT)) return;
lines[i] = children.get(separatorChildIndex + 1);
}
for (Listener listener : listeners) listener.signCreated(sender, lines, enabled);
}
}
public static class Listener {
public void commandReceived (MutablePlayerListEntry sender, String command, boolean senderHasCommandSpy) {}
public void signCreated (MutablePlayerListEntry sender, Component[] lines, boolean senderHasCommandSpy) {}
}
public void addListener (Listener listener) { listeners.add(listener); }
public void removeListener (Listener listener) { listeners.remove(listener); }
}

View file

@ -0,0 +1,66 @@
package land.chipmunk.chipmunkbot.plugins;
import land.chipmunk.chipmunkbot.ChipmunkBot;
import land.chipmunk.chipmunkbot.Options;
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.util.ComponentUtilities;
import land.chipmunk.chipmunkbot.plugins.CommandManager;
import land.chipmunk.chipmunkbot.data.MutablePlayerListEntry;
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;
public class PlayerCommandHandler {
private ChipmunkBot client;
@Getter @Setter private String prefix;
@Getter @Setter private String cspyPrefix;
public PlayerCommandHandler (ChipmunkBot client, Options options) {
this.client = client;
this.prefix = options.commands.prefix;
this.cspyPrefix = options.commands.cspyPrefix != null ? options.commands.cspyPrefix : this.prefix;
// TODO: Make this less messy (I might just rewrite how I do events eventually)
client.chat().addListener(new ChatPlugin.Listener() { @Override public void playerMessageReceived (PlayerMessage message) { handleMessage(message); } });
client.commandSpy().addListener(new CommandSpyPlugin.Listener() { @Override public void commandReceived (MutablePlayerListEntry sender, String command, boolean senderHasCommandSpy) { handleCommand(sender, command); } });
}
public void handleMessage (PlayerMessage message) {
final Component contents = message.contents();
if (contents == null) return;
final String contentsString = ComponentUtilities.stringify(contents);
if (!contentsString.startsWith(prefix)) return;
final String commandString = contentsString.substring(prefix.length());
final PlayerCommandSource source = new PlayerCommandSource(client, message.sender());
this.tryExecuteCommand(source, commandString);
}
public void handleCommand (MutablePlayerListEntry sender, String command) {
if (!command.startsWith(cspyPrefix)) return;
final String commandString = command.substring(cspyPrefix.length());
final PlayerCommandSource source = new PlayerCommandSource(client, sender);
this.tryExecuteCommand(source, commandString);
}
private void tryExecuteCommand (CommandSource source, String command) {
try {
CommandDispatcher dispatcher = client.commandManager().dispatcher();
dispatcher.execute(command, source);
} catch (CommandSyntaxException exception) {
CommandManager.sendException(source, exception);
} catch (Exception exception) {
exception.printStackTrace();
source.sendOutput(Component.translatable("command.failed", NamedTextColor.RED), false);
}
}
}

View file

@ -48,12 +48,13 @@ public class SelfCarePlugin extends SessionAdapter {
}; };
timer = new Timer(); timer = new Timer();
timer.schedule(task, 70, 70); timer.schedule(task, 75, 75);
} }
public void tick () { public void tick () {
if (gamemode != GameMode.CREATIVE) client.chat().command("minecraft:gamemode creative");
if (permissionLevel < 2) client.chat().command("minecraft:op @s[type=player]"); if (permissionLevel < 2) client.chat().command("minecraft:op @s[type=player]");
else if (gamemode != GameMode.CREATIVE) client.chat().command("minecraft:gamemode creative");
else if (!client.commandSpy().enabled()) client.chat().command("c on");
} }
@Override @Override

View file

@ -11,7 +11,8 @@
"reconnectDelay": 1000, "reconnectDelay": 1000,
"commands": { "commands": {
"prefix": "default." "prefix": "default.",
"cspyPrefix": "default."
}, },
"core": { "core": {