218 lines
7.6 KiB
Java
218 lines
7.6 KiB
Java
|
package cutthecord.commands;
|
||
|
|
||
|
import androidx.annotation.Nullable;
|
||
|
|
||
|
import com.discord.models.domain.ModelUser;
|
||
|
import com.discord.stores.StoreMessages;
|
||
|
import com.discord.stores.StoreStream;
|
||
|
|
||
|
import java.util.HashMap;
|
||
|
import java.util.Map;
|
||
|
import java.util.Set;
|
||
|
import java.util.regex.Pattern;
|
||
|
|
||
|
import cutthecord.commands.commands.CmdBold;
|
||
|
import cutthecord.commands.commands.CmdClap;
|
||
|
import cutthecord.commands.commands.CmdCtc;
|
||
|
import cutthecord.commands.commands.CmdFlip;
|
||
|
import cutthecord.commands.commands.CmdFullWidth;
|
||
|
import cutthecord.commands.commands.CmdGordon;
|
||
|
import cutthecord.commands.commands.CmdLenny;
|
||
|
import cutthecord.commands.commands.CmdLower;
|
||
|
import cutthecord.commands.commands.CmdMe;
|
||
|
import cutthecord.commands.commands.CmdMorse;
|
||
|
import cutthecord.commands.commands.CmdOwo;
|
||
|
import cutthecord.commands.commands.CmdSlap;
|
||
|
import cutthecord.commands.commands.CmdSmall;
|
||
|
import cutthecord.commands.commands.CmdSmaller;
|
||
|
import cutthecord.commands.commands.CmdSpoiler;
|
||
|
import cutthecord.commands.commands.CmdSpoilerImg;
|
||
|
import cutthecord.commands.commands.CmdStrikethrough;
|
||
|
import cutthecord.commands.commands.CmdUpper;
|
||
|
import lanchon.dexpatcher.annotation.DexAdd;
|
||
|
|
||
|
|
||
|
// Helper class for additional commands (slashcommands)
|
||
|
@DexAdd
|
||
|
public class CommandHandler {
|
||
|
|
||
|
@DexAdd
|
||
|
private static final HashMap<String, Command> commands = registerCommands();
|
||
|
|
||
|
@DexAdd
|
||
|
public abstract static class Command {
|
||
|
|
||
|
@DexAdd
|
||
|
private final HashMap<String, Command> subcommands = new HashMap<>();
|
||
|
|
||
|
@DexAdd
|
||
|
public void registerSubCommand(String subCmdName, Command command) {
|
||
|
subcommands.put(subCmdName, command);
|
||
|
}
|
||
|
|
||
|
@DexAdd
|
||
|
public Set<String> getSubCommandNames() {
|
||
|
return subcommands.keySet();
|
||
|
}
|
||
|
|
||
|
@DexAdd
|
||
|
public String process(String args) {
|
||
|
// Check for possible subcommands
|
||
|
if (!subcommands.isEmpty()) {
|
||
|
final String[] split = args.split(Pattern.quote(" "));
|
||
|
if (split.length > 0) {
|
||
|
final String possibleSubCmd = split[0].toLowerCase();
|
||
|
for (Map.Entry<String, Command> subCommand : subcommands.entrySet()) {
|
||
|
if (subCommand.getKey().equals(possibleSubCmd)) {
|
||
|
|
||
|
// Account for simple commands with no args
|
||
|
String newArgs = "";
|
||
|
int i = args.indexOf(" ");
|
||
|
if (i == -1) {
|
||
|
newArgs = "";
|
||
|
} else {
|
||
|
// Has args
|
||
|
int newSubPos = i + 1;
|
||
|
newArgs = args.substring(newSubPos);
|
||
|
}
|
||
|
|
||
|
return subCommand.getValue().process(newArgs);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Handle command
|
||
|
return handleCommand(args);
|
||
|
}
|
||
|
|
||
|
@DexAdd
|
||
|
public abstract String handleCommand(String msg);
|
||
|
|
||
|
@DexAdd
|
||
|
@Nullable
|
||
|
public abstract String getPopupInfo();
|
||
|
}
|
||
|
|
||
|
// Like a normal command, but the output is only viewable to the sender
|
||
|
@DexAdd
|
||
|
public abstract static class PrivateCommand extends Command {
|
||
|
|
||
|
}
|
||
|
|
||
|
@DexAdd
|
||
|
public static HashMap<String, Command> registerCommands() {
|
||
|
HashMap<String, Command> cmds = new HashMap<>();
|
||
|
|
||
|
cmds.put("upper", new CmdUpper());
|
||
|
cmds.put("lower", new CmdLower());
|
||
|
cmds.put("bold", new CmdBold());
|
||
|
cmds.put("clap", new CmdClap());
|
||
|
cmds.put("flip", new CmdFlip());
|
||
|
cmds.put("slap", new CmdSlap());
|
||
|
cmds.put("fw", new CmdFullWidth());
|
||
|
cmds.put("gordon", new CmdGordon());
|
||
|
cmds.put("me", new CmdMe());
|
||
|
cmds.put("lenny", new CmdLenny());
|
||
|
cmds.put("morse", new CmdMorse());
|
||
|
cmds.put("owo", new CmdOwo());
|
||
|
cmds.put("spoiler", new CmdSpoiler());
|
||
|
cmds.put("spoilerimg", new CmdSpoilerImg());
|
||
|
cmds.put("small", new CmdSmall());
|
||
|
cmds.put("smaller", new CmdSmaller());
|
||
|
cmds.put("st", new CmdStrikethrough());
|
||
|
|
||
|
// TODO can we add an CTC user that responds for these?
|
||
|
Command ctcCommand = new CmdCtc();
|
||
|
ctcCommand.registerSubCommand("channelleak", new CmdCtc.CmdCtcChannelLeak());
|
||
|
ctcCommand.registerSubCommand("showtyping", new CmdCtc.CmdCtcShowTyping());
|
||
|
ctcCommand.registerSubCommand("token", new CmdCtc.CmdCtcToken());
|
||
|
ctcCommand.registerSubCommand("account", new CmdCtc.CmdCtcAccount());
|
||
|
ctcCommand.registerSubCommand("addaccount", new CmdCtc.CmdCtcAddAccount());
|
||
|
ctcCommand.registerSubCommand("nodelete", new CmdCtc.CmdCtcNoDelete());
|
||
|
ctcCommand.registerSubCommand("gifautoplay", new CmdCtc.CmdCtcGifAutoPlay());
|
||
|
cmds.put("ctc", ctcCommand);
|
||
|
|
||
|
return cmds;
|
||
|
}
|
||
|
|
||
|
@DexAdd
|
||
|
public static HashMap<String, String> getPopupInfo() {
|
||
|
HashMap<String, String> infoPopups = new HashMap<>(); // Static init order makes things a pain so init in here
|
||
|
for (Map.Entry<String, Command> command : commands.entrySet()) {
|
||
|
String name = command.getKey();
|
||
|
Command cmd = command.getValue();
|
||
|
infoPopups.put(name, cmd.getPopupInfo());
|
||
|
registerPopupInfoChildren(infoPopups, name, cmd);
|
||
|
}
|
||
|
|
||
|
return infoPopups;
|
||
|
}
|
||
|
|
||
|
@DexAdd
|
||
|
private static void registerPopupInfoChildren(HashMap<String, String> infoPopups, String parent, Command parentCmd) {
|
||
|
for (Map.Entry<String, Command> subCommand : parentCmd.subcommands.entrySet()) {
|
||
|
String name = parent+" "+subCommand.getKey();
|
||
|
infoPopups.put(name, subCommand.getValue().getPopupInfo());
|
||
|
registerPopupInfoChildren(infoPopups, name, subCommand.getValue());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
@DexAdd
|
||
|
public static String slashCommands(StoreMessages storeMessages, long channelId, String str) {
|
||
|
String msg = str.trim();
|
||
|
|
||
|
// TODO check for edge cases like /meh parsing to /me
|
||
|
// TODO don't allow invalid commaands to end up in chat
|
||
|
|
||
|
// Trim off "/"
|
||
|
msg = msg.substring(1);
|
||
|
|
||
|
for (Map.Entry<String, Command> commandEntry : commands.entrySet()) {
|
||
|
if (msg.startsWith(commandEntry.getKey())) {
|
||
|
String newArgs = msg;
|
||
|
|
||
|
// Account for simple commands with no args
|
||
|
int i = msg.indexOf(" ");
|
||
|
if (i == -1) {
|
||
|
newArgs = "";
|
||
|
} else {
|
||
|
// Has args
|
||
|
int newSubPos = i + 1;
|
||
|
newArgs = msg.substring(newSubPos);
|
||
|
}
|
||
|
|
||
|
String output = commandEntry.getValue().process(newArgs);
|
||
|
if (commandEntry.getValue() instanceof PrivateCommand) {
|
||
|
// Show message from ctcbot
|
||
|
storeMessages.sendCTCBotMessageToChannel(channelId, output);
|
||
|
|
||
|
// This is naughty but discord handles it sanely
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return output;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return str.trim();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
@DexAdd
|
||
|
public static String interceptEditMessage(StoreMessages storeMessages, long channelId, String str) {
|
||
|
return str.startsWith("/") ? slashCommands(storeMessages, channelId, str) : str;
|
||
|
}
|
||
|
|
||
|
@DexAdd
|
||
|
public static String interceptSendMessage(StoreMessages storeMessages, long channelId, String str) {
|
||
|
StoreStream.getUserSettings().setImageSpoiler(false);
|
||
|
return str.startsWith("/") ? slashCommands(storeMessages, channelId, str) : str;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|