diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 78094d4..cb9b8c1 100644 --- a/pom.xml +++ b/pom.xml @@ -47,6 +47,12 @@ 2.10.1 + + com.google.guava + guava + 31.1-jre + + org.projectlombok lombok diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/Bot.java b/src/main/java/me/chayapak1/chomensbot_mabe/Bot.java index 44bf0ea..f3107d7 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/Bot.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/Bot.java @@ -32,6 +32,7 @@ public class Bot { @Getter private final CorePlugin core = new CorePlugin(this); @Getter private final CommandHandlerPlugin commandHandler = new CommandHandlerPlugin(); @Getter private final ChatCommandHandlerPlugin chatCommandHandler = new ChatCommandHandlerPlugin(this); + @Getter private final HashingPlugin hashing = new HashingPlugin(this); public Bot (String host, int port, String username) { this.host = host; diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/command/Command.java b/src/main/java/me/chayapak1/chomensbot_mabe/command/Command.java index 20bb6e8..81b7d42 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/command/Command.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/command/Command.java @@ -7,5 +7,7 @@ import java.util.List; public interface Command { String description(); List usage(); - Component execute(CommandContext context, String[] args) throws Exception; + int trustLevel(); + + Component execute(CommandContext context, String[] args, String[] fullArgs) throws Exception; } diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/commands/CommandBlockCommand.java b/src/main/java/me/chayapak1/chomensbot_mabe/commands/CommandBlockCommand.java index 4554f80..f9d40fc 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/commands/CommandBlockCommand.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/commands/CommandBlockCommand.java @@ -20,7 +20,11 @@ public class CommandBlockCommand implements Command { return usages; } - public Component execute(CommandContext context, String[] args) { + public int trustLevel() { + return 0; + } + + public Component execute(CommandContext context, String[] args, String[] fullArgs) { final Bot bot = context.bot(); bot.core().run(String.join(" ", args)); diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/commands/CowsayCommand.java b/src/main/java/me/chayapak1/chomensbot_mabe/commands/CowsayCommand.java index 388bd0f..5456eea 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/commands/CowsayCommand.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/commands/CowsayCommand.java @@ -21,7 +21,11 @@ public class CowsayCommand implements Command { return usages; } - public Component execute(CommandContext context, String[] args) { + public int trustLevel() { + return 0; + } + + public Component execute(CommandContext context, String[] args, String[] fullArgs) { final String cow = args[0]; final String message = String.join(" ", Arrays.copyOfRange(args, 1, args.length)); diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/commands/EchoCommand.java b/src/main/java/me/chayapak1/chomensbot_mabe/commands/EchoCommand.java index 029821d..a7e8900 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/commands/EchoCommand.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/commands/EchoCommand.java @@ -20,7 +20,11 @@ public class EchoCommand implements Command { return usages; } - public Component execute (CommandContext context, String[] args) { + public int trustLevel() { + return 0; + } + + public Component execute(CommandContext context, String[] args, String[] fullArgs) { final Bot bot = context.bot(); bot.chat().send(String.join(" ", args)); diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/commands/HelpCommand.java b/src/main/java/me/chayapak1/chomensbot_mabe/commands/HelpCommand.java index 5d9e69f..f59d211 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/commands/HelpCommand.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/commands/HelpCommand.java @@ -24,7 +24,11 @@ public class HelpCommand implements Command { return usages; } - public Component execute (CommandContext context, String[] args) { + public int trustLevel() { + return 0; + } + + public Component execute(CommandContext context, String[] args, String[] fullArgs) { if (args.length == 0) { sendCommandList(context); return Component.text("success"); @@ -35,24 +39,49 @@ public class HelpCommand implements Command { public void sendCommandList(CommandContext context) { final List list = new ArrayList<>(); - - for (Map.Entry entry : CommandHandlerPlugin.commands().entrySet()) { - final String name = entry.getKey(); - - list.add(Component.text(name)); - } + list.addAll(getCommandListByTrustLevel(0)); + list.addAll(getCommandListByTrustLevel(1)); + list.addAll(getCommandListByTrustLevel(2)); final Component component = Component.empty() .append(Component.text("Commands ").color(NamedTextColor.GRAY)) .append(Component.text("(").color(NamedTextColor.DARK_GRAY)) .append(Component.text("Length: ").color(NamedTextColor.GRAY)) .append(Component.text(list.size()).color(NamedTextColor.GREEN)) + .append(Component.text(") ").color(NamedTextColor.DARK_GRAY)) + .append(Component.text("(").color(NamedTextColor.DARK_GRAY)) + .append(Component.text("Public ").color(NamedTextColor.GREEN)) + .append(Component.text("Trusted ").color(NamedTextColor.RED)) + .append(Component.text("Owner").color(NamedTextColor.DARK_RED)) .append(Component.text(") - ").color(NamedTextColor.DARK_GRAY)) - .append(Component.join(JoinConfiguration.separator(Component.space()), list).color(NamedTextColor.GREEN)); + .append(Component.join(JoinConfiguration.separator(Component.space()), list)); context.sendOutput(component); } + public List getCommandListByTrustLevel (int trustLevel) { + final List list = new ArrayList<>(); + + for (Map.Entry entry : CommandHandlerPlugin.commands().entrySet()) { + final String name = entry.getKey(); + final Command command = entry.getValue(); + + if (command.trustLevel() != trustLevel) continue; + list.add(Component.text(name).color(getColorByTrustLevel(trustLevel))); + } + + return list; + } + + public NamedTextColor getColorByTrustLevel (int trustLevel) { + return switch (trustLevel) { + case 0 -> NamedTextColor.GREEN; + case 1 -> NamedTextColor.RED; + case 2 -> NamedTextColor.DARK_RED; + default -> NamedTextColor.WHITE; // hm? + }; + } + public Component sendUsages (CommandContext context, String[] args) { final Bot bot = context.bot(); diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/commands/TestCommand.java b/src/main/java/me/chayapak1/chomensbot_mabe/commands/TestCommand.java index 37e0f3f..cd9ec5a 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/commands/TestCommand.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/commands/TestCommand.java @@ -20,7 +20,11 @@ public class TestCommand implements Command { return usages; } - public Component execute(CommandContext context, String[] args) { + public int trustLevel() { + return 0; + } + + public Component execute(CommandContext context, String[] args, String[] fullArgs) { context.sendOutput( Component.empty() .append(Component.text("Hello, World! Username: ")) diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/commands/ThrowCommand.java b/src/main/java/me/chayapak1/chomensbot_mabe/commands/ThrowCommand.java index 31dfbfb..a5b1e5b 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/commands/ThrowCommand.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/commands/ThrowCommand.java @@ -19,7 +19,11 @@ public class ThrowCommand implements Command { return usages; } - public Component execute(CommandContext context, String[] args) throws Exception { + public int trustLevel() { + return 0; + } + + public Component execute(CommandContext context, String[] args, String[] fullArgs) throws Exception { final String message = String.join(" ", args); throw new Exception(message.equals("") ? "among us" : message); diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/commands/ValidateCommand.java b/src/main/java/me/chayapak1/chomensbot_mabe/commands/ValidateCommand.java new file mode 100644 index 0000000..b6f5373 --- /dev/null +++ b/src/main/java/me/chayapak1/chomensbot_mabe/commands/ValidateCommand.java @@ -0,0 +1,42 @@ +package me.chayapak1.chomensbot_mabe.commands; + +import me.chayapak1.chomensbot_mabe.Bot; +import me.chayapak1.chomensbot_mabe.command.Command; +import me.chayapak1.chomensbot_mabe.command.CommandContext; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; + +import java.util.ArrayList; +import java.util.List; + +public class ValidateCommand implements Command { + + @Override + public String description() { + return "Validates a hash"; + } + + @Override + public List usage() { + final List usages = new ArrayList<>(); + usages.add(""); + + return usages; + } + + @Override + public int trustLevel() { + return 1; + } + + @Override + public Component execute(CommandContext context, String[] args, String[] fullArgs) { + final Bot bot = context.bot(); + final String hash = fullArgs[0]; + + if (hash.equals(bot.hashing().hash())) context.sendOutput(Component.text("Valid hash").color(NamedTextColor.GREEN)); + else if (hash.equals(bot.hashing().ownerHash())) context.sendOutput(Component.text("Valid OwnerHash").color(NamedTextColor.GREEN)); + + return Component.text("success"); + } +} diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/plugins/ChatCommandHandlerPlugin.java b/src/main/java/me/chayapak1/chomensbot_mabe/plugins/ChatCommandHandlerPlugin.java index 67aeae0..fc4d173 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/plugins/ChatCommandHandlerPlugin.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/plugins/ChatCommandHandlerPlugin.java @@ -33,7 +33,7 @@ public class ChatCommandHandlerPlugin extends ChatPlugin.ChatListener { final PlayerCommandContext context = new PlayerCommandContext(bot, displayName); - final Component output = CommandHandlerPlugin.executeCommand(commandString, context); + final Component output = CommandHandlerPlugin.executeCommand(commandString, context, bot.hashing().hash(), bot.hashing().ownerHash()); final String textOutput = ((TextComponent) output).content(); if (!textOutput.equals("success")) { diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/plugins/CommandHandlerPlugin.java b/src/main/java/me/chayapak1/chomensbot_mabe/plugins/CommandHandlerPlugin.java index b5758a4..b14873e 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/plugins/CommandHandlerPlugin.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/plugins/CommandHandlerPlugin.java @@ -11,6 +11,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; public class CommandHandlerPlugin { @@ -23,39 +24,98 @@ public class CommandHandlerPlugin { registerCommand("help", new HelpCommand()); registerCommand("test", new TestCommand()); registerCommand("throw", new ThrowCommand()); + registerCommand("validate", new ValidateCommand()); } public void registerCommand (String commandName, Command command) { commands.put(commandName, command); } - public static Component executeCommand (String input, CommandContext context) { - final String[] splitInput = input.split(" "); + public static Component executeCommand (String input, CommandContext context, String hash, String ownerHash) { + final String[] splitInput = input.split("\\s+"); final String commandName = splitInput[0]; - final String[] args = Arrays.copyOfRange(splitInput, 1, splitInput.length); final Command command = commands.get(commandName); - if (command != null) { - try { - return command.execute(context, args); - } catch (Exception exception) { - exception.printStackTrace(); + // idea told this as "Condition 'command == null' is always 'false'" and its not true LMFAO + if (command == null) return Component.text("Unknown command: " + commandName).color(NamedTextColor.RED); - final String stackTrace = ExceptionUtils.getStackTrace(exception); - return Component - .text("An error occurred while trying to execute the command, hover here for more details", NamedTextColor.RED) - .hoverEvent( - HoverEvent.showText( - Component - .text(stackTrace) - .color(NamedTextColor.RED) - ) - ); - } - } else { - return Component.text("Unknown command: " + commandName).color(NamedTextColor.RED); + final int trustLevel = command.trustLevel(); + + final String[] fullArgs = Arrays.copyOfRange(splitInput, 1, splitInput.length); + final int longestUsageIndex = getLongestUsageIndex(command.usage()); + final int minimumArgs = getMinimumArgs(command.usage().get(longestUsageIndex)); + final int maximumArgs = getMaximumArgs(command.usage().get(longestUsageIndex)); + if (fullArgs.length < minimumArgs) return Component.text("Excepted minimum of " + minimumArgs + " argument(s), got " + fullArgs.length).color(NamedTextColor.RED); + if (fullArgs.length > maximumArgs) return Component.text("Too much arguments, expected " + maximumArgs).color(NamedTextColor.RED); + + String userHash = ""; + if (trustLevel > 0 && splitInput.length >= 2) userHash = splitInput[1]; + + final String[] args = Arrays.copyOfRange(splitInput, (trustLevel > 0) ? 2 : 1, splitInput.length); + + if (command.trustLevel() > 0) { + if ( + command.trustLevel() == 1 && + !userHash.equals(hash) && + !userHash.equals(ownerHash) + ) return Component.text("Invalid hash").color(NamedTextColor.RED); + + if ( + command.trustLevel() == 2 && + !userHash.equals(ownerHash) + ) return Component.text("Invalid OwnerHash").color(NamedTextColor.RED); + } + + try { + return command.execute(context, args, fullArgs); + } catch (Exception exception) { + exception.printStackTrace(); + + final String stackTrace = ExceptionUtils.getStackTrace(exception); + return Component + .text("An error occurred while trying to execute the command, hover here for more details", NamedTextColor.RED) + .hoverEvent( + HoverEvent.showText( + Component + .text(stackTrace) + .color(NamedTextColor.RED) + ) + ); } } + + private static int getLongestUsageIndex(List usages) { + int longestIndex = 0; + int maxLength = 0; + for (int i = 0; i < usages.size(); i++) { + String[] args = usages.get(i).split("\\s+"); + if (args.length > maxLength) { + longestIndex = i; + maxLength = args.length; + } + } + return longestIndex; + } + + private static int getMinimumArgs(String usage) { + int count = 0; + for (int i = 0; i < usage.length(); i++) { + if (usage.charAt(i) == '<') { + count++; + } + } + return count; + } + + private static int getMaximumArgs(String usage) { + int count = 0; + for (int i = 0; i < usage.length(); i++) { + if (usage.charAt(i) == '<' || usage.charAt(i) == '[') { + count++; + } + } + return count; + } } diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/plugins/ConsolePlugin.java b/src/main/java/me/chayapak1/chomensbot_mabe/plugins/ConsolePlugin.java index 896a411..b37024c 100644 --- a/src/main/java/me/chayapak1/chomensbot_mabe/plugins/ConsolePlugin.java +++ b/src/main/java/me/chayapak1/chomensbot_mabe/plugins/ConsolePlugin.java @@ -9,7 +9,6 @@ import net.kyori.adventure.text.format.NamedTextColor; import org.jline.reader.EndOfFileException; import org.jline.reader.LineReader; import org.jline.reader.LineReaderBuilder; -import org.jline.reader.UserInterruptException; public class ConsolePlugin { private final Bot bot; @@ -29,8 +28,6 @@ public class ConsolePlugin { String line = null; try { line = reader.readLine(prompt); - } catch (UserInterruptException e) { - System.exit(1); // yup } catch (EndOfFileException e) { return; } catch (Exception e) { @@ -48,7 +45,7 @@ public class ConsolePlugin { if (line.startsWith(prefix)) { final ConsoleCommandContext context = new ConsoleCommandContext(bot); - final Component output = CommandHandlerPlugin.executeCommand(line.substring(prefix.length()), context); + final Component output = CommandHandlerPlugin.executeCommand(line.substring(prefix.length()), context, "h", "o"); final String textOutput = ((TextComponent) output).content(); if (!textOutput.equals("success")) { diff --git a/src/main/java/me/chayapak1/chomensbot_mabe/plugins/HashingPlugin.java b/src/main/java/me/chayapak1/chomensbot_mabe/plugins/HashingPlugin.java new file mode 100644 index 0000000..2e4a5b5 --- /dev/null +++ b/src/main/java/me/chayapak1/chomensbot_mabe/plugins/HashingPlugin.java @@ -0,0 +1,34 @@ +package me.chayapak1.chomensbot_mabe.plugins; + +import lombok.Getter; +import me.chayapak1.chomensbot_mabe.Bot; + +import com.google.common.hash.Hashing; + +import java.nio.charset.StandardCharsets; +import java.util.concurrent.TimeUnit; + +public class HashingPlugin { + @Getter private String hash; + @Getter private String ownerHash; + + public HashingPlugin (Bot bot) { + + bot.executor().schedule(this::update, 2, TimeUnit.SECONDS); + } + + public void update () { + final String ownerHashKey = "b)R��nF�CW���#�\\[�S*8\"t^eia�Z��k����K1�8zȢ�"; + final String normalHashKey = "�iB_D���k��j8H�{?[/ڭ�f�}Ѣ�^-=�Ț��v]��g>��=c"; + + final String hashValue = System.currentTimeMillis() / 10_000 + normalHashKey; + hash = Hashing.sha256() + .hashString(hashValue, StandardCharsets.UTF_8) + .toString().substring(0, 16); + + final String ownerHashValue = System.currentTimeMillis() / 10_000 + ownerHashKey; + ownerHash = Hashing.sha256() + .hashString(ownerHashValue, StandardCharsets.UTF_8) + .toString().substring(0, 16); + } +}