diff --git a/build-number.txt b/build-number.txt index fc358d09..46922501 100644 --- a/build-number.txt +++ b/build-number.txt @@ -1 +1 @@ -2160 \ No newline at end of file +2195 \ No newline at end of file diff --git a/src/main/java/me/chayapak1/chomens_bot/Main.java b/src/main/java/me/chayapak1/chomens_bot/Main.java index d54ddb0f..8079d657 100644 --- a/src/main/java/me/chayapak1/chomens_bot/Main.java +++ b/src/main/java/me/chayapak1/chomens_bot/Main.java @@ -133,7 +133,7 @@ public class Main { // initialize plugins console = new ConsolePlugin(config); LoggerPlugin.init(); - AuthPlugin.init(config); + ChomeNSModIntegrationPlugin.init(); if (config.database.enabled) database = new DatabasePlugin(config); if (config.discord.enabled) discord = new DiscordPlugin(config); if (config.irc.enabled) new IRCPlugin(config); diff --git a/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/PacketHandler.java b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/PacketHandler.java new file mode 100644 index 00000000..b34dc54b --- /dev/null +++ b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/PacketHandler.java @@ -0,0 +1,65 @@ +package me.chayapak1.chomens_bot.chomeNSMod; + +import me.chayapak1.chomens_bot.Bot; +import me.chayapak1.chomens_bot.chomeNSMod.clientboundPackets.ClientboundCoreOutputPacket; +import me.chayapak1.chomens_bot.chomeNSMod.serverboundPackets.ServerboundRunCommandPacket; +import me.chayapak1.chomens_bot.chomeNSMod.serverboundPackets.ServerboundRunCoreCommandPacket; +import me.chayapak1.chomens_bot.command.ChomeNSModCommandContext; +import me.chayapak1.chomens_bot.data.player.PlayerEntry; +import net.kyori.adventure.text.Component; + +import java.util.concurrent.CompletableFuture; + +public class PacketHandler { + private final Bot bot; + + public PacketHandler (Bot bot) { + this.bot = bot; + } + + public void handlePacket (PlayerEntry player, Packet packet) { + if (packet instanceof ServerboundRunCoreCommandPacket t_packet) handlePacket(player, t_packet); + else if (packet instanceof ServerboundRunCommandPacket t_packet) handlePacket(player, t_packet); + } + + private void handlePacket (PlayerEntry player, ServerboundRunCoreCommandPacket packet) { + final CompletableFuture future = bot.core.runTracked(packet.command); + + if (future == null) { + bot.chomeNSMod.send( + player, + new ClientboundCoreOutputPacket( + packet.runID, + Component.empty() + ) + ); + + return; + } + + future.thenApply(output -> { + bot.chomeNSMod.send( + player, + new ClientboundCoreOutputPacket( + packet.runID, + output + ) + ); + + return null; + }); + } + + private void handlePacket (PlayerEntry player, ServerboundRunCommandPacket packet) { + final String input = packet.input; // the input is raw, no prefix included + + final ChomeNSModCommandContext context = new ChomeNSModCommandContext( + bot, + player + ); + + final Component component = bot.commandHandler.executeCommand(input, context, null); + + if (component != null) context.sendOutput(component); + } +} diff --git a/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/clientboundPackets/ClientboundCommandOutputPacket.java b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/clientboundPackets/ClientboundCommandOutputPacket.java new file mode 100644 index 00000000..f96aa705 --- /dev/null +++ b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/clientboundPackets/ClientboundCommandOutputPacket.java @@ -0,0 +1,28 @@ +package me.chayapak1.chomens_bot.chomeNSMod.clientboundPackets; + +import io.netty.buffer.ByteBuf; +import me.chayapak1.chomens_bot.chomeNSMod.Packet; +import me.chayapak1.chomens_bot.chomeNSMod.Types; +import net.kyori.adventure.text.Component; + +public class ClientboundCommandOutputPacket implements Packet { + public final Component output; + + public ClientboundCommandOutputPacket (Component output) { + this.output = output; + } + + public ClientboundCommandOutputPacket (ByteBuf buf) { + this.output = Types.readComponent(buf); + } + + @Override + public int getId () { + return 2; + } + + @Override + public void serialize (ByteBuf buf) { + Types.writeComponent(buf, this.output); + } +} diff --git a/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/clientboundPackets/ClientboundSuccessfulHandshakePacket.java b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/clientboundPackets/ClientboundHandshakePacket.java similarity index 55% rename from src/main/java/me/chayapak1/chomens_bot/chomeNSMod/clientboundPackets/ClientboundSuccessfulHandshakePacket.java rename to src/main/java/me/chayapak1/chomens_bot/chomeNSMod/clientboundPackets/ClientboundHandshakePacket.java index cb223542..b83fcfcf 100644 --- a/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/clientboundPackets/ClientboundSuccessfulHandshakePacket.java +++ b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/clientboundPackets/ClientboundHandshakePacket.java @@ -3,20 +3,19 @@ package me.chayapak1.chomens_bot.chomeNSMod.clientboundPackets; import io.netty.buffer.ByteBuf; import me.chayapak1.chomens_bot.chomeNSMod.Packet; -public class ClientboundSuccessfulHandshakePacket implements Packet { - public ClientboundSuccessfulHandshakePacket () { +public class ClientboundHandshakePacket implements Packet { + public ClientboundHandshakePacket() { } - public ClientboundSuccessfulHandshakePacket (ByteBuf buf) { + public ClientboundHandshakePacket(ByteBuf buf) { } @Override - public int getId() { + public int getId () { return 0; } @Override public void serialize (ByteBuf buf) { - } } diff --git a/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/serverboundPackets/ServerboundRunCommandPacket.java b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/serverboundPackets/ServerboundRunCommandPacket.java new file mode 100644 index 00000000..18a3810f --- /dev/null +++ b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/serverboundPackets/ServerboundRunCommandPacket.java @@ -0,0 +1,27 @@ +package me.chayapak1.chomens_bot.chomeNSMod.serverboundPackets; + +import io.netty.buffer.ByteBuf; +import me.chayapak1.chomens_bot.chomeNSMod.Packet; +import me.chayapak1.chomens_bot.chomeNSMod.Types; + +public class ServerboundRunCommandPacket implements Packet { + public final String input; + + public ServerboundRunCommandPacket (String input) { + this.input = input; + } + + public ServerboundRunCommandPacket (ByteBuf buf) { + this.input = Types.readString(buf); + } + + @Override + public int getId () { + return 2; + } + + @Override + public void serialize (ByteBuf buf) { + Types.writeString(buf, this.input); + } +} diff --git a/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/serverboundPackets/ServerboundHandshakePacket.java b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/serverboundPackets/ServerboundSuccessfulHandshakePacket.java similarity index 55% rename from src/main/java/me/chayapak1/chomens_bot/chomeNSMod/serverboundPackets/ServerboundHandshakePacket.java rename to src/main/java/me/chayapak1/chomens_bot/chomeNSMod/serverboundPackets/ServerboundSuccessfulHandshakePacket.java index 1bf04a99..0f865d90 100644 --- a/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/serverboundPackets/ServerboundHandshakePacket.java +++ b/src/main/java/me/chayapak1/chomens_bot/chomeNSMod/serverboundPackets/ServerboundSuccessfulHandshakePacket.java @@ -3,19 +3,20 @@ package me.chayapak1.chomens_bot.chomeNSMod.serverboundPackets; import io.netty.buffer.ByteBuf; import me.chayapak1.chomens_bot.chomeNSMod.Packet; -public class ServerboundHandshakePacket implements Packet { - public ServerboundHandshakePacket () { +public class ServerboundSuccessfulHandshakePacket implements Packet { + public ServerboundSuccessfulHandshakePacket() { } - public ServerboundHandshakePacket (ByteBuf buf) { + public ServerboundSuccessfulHandshakePacket(ByteBuf buf) { } @Override - public int getId () { + public int getId() { return 0; } @Override public void serialize (ByteBuf buf) { + } } diff --git a/src/main/java/me/chayapak1/chomens_bot/command/ChomeNSModCommandContext.java b/src/main/java/me/chayapak1/chomens_bot/command/ChomeNSModCommandContext.java new file mode 100644 index 00000000..77686e31 --- /dev/null +++ b/src/main/java/me/chayapak1/chomens_bot/command/ChomeNSModCommandContext.java @@ -0,0 +1,30 @@ +package me.chayapak1.chomens_bot.command; + +import me.chayapak1.chomens_bot.Bot; +import me.chayapak1.chomens_bot.chomeNSMod.clientboundPackets.ClientboundCommandOutputPacket; +import me.chayapak1.chomens_bot.data.player.PlayerEntry; +import net.kyori.adventure.text.Component; + +public class ChomeNSModCommandContext extends CommandContext { + public ChomeNSModCommandContext (Bot bot, PlayerEntry sender) { + super( + bot, + ".cbot ", // intentionally hardcoded + sender, + true + ); + } + + @Override + public void sendOutput (Component component) { + bot.chomeNSMod.send( + sender, + new ClientboundCommandOutputPacket(component) + ); + } + + @Override + public Component displayName () { + return sender.displayName; + } +} diff --git a/src/main/java/me/chayapak1/chomens_bot/plugins/AuthPlugin.java b/src/main/java/me/chayapak1/chomens_bot/plugins/AuthPlugin.java index 2a56a51c..59b3b954 100644 --- a/src/main/java/me/chayapak1/chomens_bot/plugins/AuthPlugin.java +++ b/src/main/java/me/chayapak1/chomens_bot/plugins/AuthPlugin.java @@ -1,87 +1,15 @@ package me.chayapak1.chomens_bot.plugins; import me.chayapak1.chomens_bot.Bot; -import me.chayapak1.chomens_bot.Configuration; import me.chayapak1.chomens_bot.data.logging.LogType; import me.chayapak1.chomens_bot.data.player.PlayerEntry; -import me.chayapak1.chomens_bot.util.LoggerUtilities; -import me.chayapak1.chomens_bot.util.UUIDUtilities; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.format.NamedTextColor; import org.geysermc.mcprotocollib.network.event.session.DisconnectedEvent; -import javax.crypto.Cipher; -import java.io.BufferedWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.*; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.util.Base64; import java.util.concurrent.TimeUnit; public class AuthPlugin implements PlayersPlugin.Listener, ChatPlugin.Listener { - private static final String ID = "chomens_bot_verify"; - - private static PrivateKey PRIVATE_KEY; - private static final Path PRIVATE_KEY_PATH = Path.of("private.key"); - private static final Path PUBLIC_KEY_PATH = Path.of("public.key"); - - private static final String BEGIN_PRIVATE_KEY = "-----BEGIN CHOMENS BOT PRIVATE KEY-----"; - private static final String END_PRIVATE_KEY = "-----END CHOMENS BOT PRIVATE KEY-----"; - - private static final String BEGIN_PUBLIC_KEY = "-----BEGIN CHOMENS BOT PUBLIC KEY-----"; - private static final String END_PUBLIC_KEY = "-----END CHOMENS BOT PUBLIC KEY-----"; - - public static void init (Configuration config) { - if (!config.ownerAuthentication.enabled) return; - - try { - // let's only check for the private key here - if (!Files.exists(PRIVATE_KEY_PATH)) { - final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); - keyGen.initialize(2048); - - final KeyPair pair = keyGen.generateKeyPair(); - - // write the keys - // (note: no newline split is intentional) - final String encodedPrivateKey = - BEGIN_PRIVATE_KEY + "\n" + - Base64.getEncoder().encodeToString(pair.getPrivate().getEncoded()) + - "\n" + END_PRIVATE_KEY; - final String encodedPublicKey = - BEGIN_PUBLIC_KEY + "\n" + - Base64.getEncoder().encodeToString(pair.getPublic().getEncoded()) + - "\n" + END_PUBLIC_KEY; - - final BufferedWriter privateKeyWriter = Files.newBufferedWriter(PRIVATE_KEY_PATH); - privateKeyWriter.write(encodedPrivateKey); - privateKeyWriter.close(); - - final BufferedWriter publicKeyWriter = Files.newBufferedWriter(PUBLIC_KEY_PATH); - publicKeyWriter.write(encodedPublicKey); - publicKeyWriter.close(); - } - - // is this a good way to remove the things? - final String privateKeyString = new String(Files.readAllBytes(PRIVATE_KEY_PATH)) - .replace(BEGIN_PRIVATE_KEY + "\n", "") - .replace("\n" + END_PRIVATE_KEY, "") - .replace("\n", "") - .trim(); - - final byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyString); - final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - - PRIVATE_KEY = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes)); - } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException | IllegalArgumentException e) { - LoggerUtilities.error(e); - } - } - private final Bot bot; public boolean isAuthenticating = false; @@ -95,8 +23,9 @@ public class AuthPlugin implements PlayersPlugin.Listener, ChatPlugin.Listener { bot.executor.scheduleAtFixedRate(() -> { if (!isAuthenticating || !bot.config.ownerAuthentication.enabled) return; + checkAuthenticated(); + timeoutCheck(); - sendAuthRequestMessage(); }, 500, 500, TimeUnit.MILLISECONDS); bot.addListener(new Bot.Listener() { @@ -110,13 +39,28 @@ public class AuthPlugin implements PlayersPlugin.Listener, ChatPlugin.Listener { bot.players.addListener(this); } - private String decrypt (byte[] data) throws Exception { - final Cipher cipher = Cipher.getInstance("RSA"); - cipher.init(Cipher.DECRYPT_MODE, PRIVATE_KEY); + private void checkAuthenticated () { + final PlayerEntry target = bot.players.getEntry(bot.config.ownerName); - final byte[] decryptedBytes = cipher.doFinal(data); + if (target == null) return; - return new String(decryptedBytes); + if (!bot.chomeNSMod.connectedPlayers.contains(target)) return; + + isAuthenticating = false; + + bot.logger.log( + LogType.AUTH, + Component + .text("Player has been verified") + .color(NamedTextColor.GREEN) + ); + + bot.chat.tellraw( + Component + .text("You have been verified") + .color(NamedTextColor.GREEN), + target.profile.getId() + ); } private void timeoutCheck () { @@ -129,18 +73,6 @@ public class AuthPlugin implements PlayersPlugin.Listener, ChatPlugin.Listener { bot.filterManager.add(target, "Authentication timed out"); } - private void sendAuthRequestMessage () { - final PlayerEntry target = bot.players.getEntry(bot.config.ownerName); - - if (target == null) return; - - final Component component = Component - .text(ID) - .append(Component.text(UUIDUtilities.selector(bot.profile.getId()))); - - bot.chat.tellraw(component, target.profile.getId()); - } - @Override public void playerJoined (PlayerEntry target) { if (!target.profile.getName().equals(bot.config.ownerName) || !bot.options.useCore) return; @@ -149,55 +81,6 @@ public class AuthPlugin implements PlayersPlugin.Listener, ChatPlugin.Listener { isAuthenticating = true; } - @Override - public boolean systemMessageReceived (Component component, String string, String ansi) { - if (!bot.config.ownerAuthentication.enabled) return true; - - if (!(component instanceof TextComponent textComponent)) return true; - - final String id = textComponent.content(); - - if (!id.equals(ID)) return true; - - if (!isAuthenticating) return false; - - if (component.children().size() != 1) return true; - - if (!(component.children().getFirst() instanceof TextComponent dataComponent)) return true; - - final String data = dataComponent.content(); - - try { - final String decrypted = decrypt(Base64.getDecoder().decode(data)); - - // what should i use here? should it be the ID? - // or does it even matter? - if (!decrypted.equals(ID)) return false; - - isAuthenticating = false; - - bot.logger.log( - LogType.AUTH, - Component - .text("Player has been verified") - .color(NamedTextColor.GREEN) - ); - - final PlayerEntry target = bot.players.getEntry(bot.config.ownerName); - - if (target == null) return false; // sad :( - - bot.chat.tellraw( - Component - .text("You have been verified") - .color(NamedTextColor.GREEN), - target.profile.getId() - ); - } catch (Exception ignored) {} - - return false; - } - @Override public void playerLeft (PlayerEntry target) { if (!target.profile.getName().equals(bot.config.ownerName)) return; diff --git a/src/main/java/me/chayapak1/chomens_bot/plugins/ChomeNSModIntegrationPlugin.java b/src/main/java/me/chayapak1/chomens_bot/plugins/ChomeNSModIntegrationPlugin.java index 28e8d935..70551bc6 100644 --- a/src/main/java/me/chayapak1/chomens_bot/plugins/ChomeNSModIntegrationPlugin.java +++ b/src/main/java/me/chayapak1/chomens_bot/plugins/ChomeNSModIntegrationPlugin.java @@ -3,14 +3,15 @@ package me.chayapak1.chomens_bot.plugins; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import me.chayapak1.chomens_bot.Bot; -import me.chayapak1.chomens_bot.Configuration; import me.chayapak1.chomens_bot.chomeNSMod.Packet; +import me.chayapak1.chomens_bot.chomeNSMod.PacketHandler; import me.chayapak1.chomens_bot.chomeNSMod.Types; -import me.chayapak1.chomens_bot.chomeNSMod.clientboundPackets.ClientboundCoreOutputPacket; -import me.chayapak1.chomens_bot.chomeNSMod.clientboundPackets.ClientboundSuccessfulHandshakePacket; -import me.chayapak1.chomens_bot.chomeNSMod.serverboundPackets.ServerboundHandshakePacket; +import me.chayapak1.chomens_bot.chomeNSMod.clientboundPackets.ClientboundHandshakePacket; +import me.chayapak1.chomens_bot.chomeNSMod.serverboundPackets.ServerboundRunCommandPacket; import me.chayapak1.chomens_bot.chomeNSMod.serverboundPackets.ServerboundRunCoreCommandPacket; +import me.chayapak1.chomens_bot.chomeNSMod.serverboundPackets.ServerboundSuccessfulHandshakePacket; import me.chayapak1.chomens_bot.data.player.PlayerEntry; +import me.chayapak1.chomens_bot.util.Ascii85; import me.chayapak1.chomens_bot.util.LoggerUtilities; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; @@ -27,19 +28,19 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.*; -import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import java.util.stream.Stream; // This is inspired from the ChomeNS Bot Proxy which is in the JavaScript version of ChomeNS Bot. -// Right now it is not really used anywhere, so you'll see duplicate codes from AuthPlugin public class ChomeNSModIntegrationPlugin implements ChatPlugin.Listener, PlayersPlugin.Listener { private static final String ID = "chomens_mod"; public static final List> SERVERBOUND_PACKETS = new ArrayList<>(); static { - SERVERBOUND_PACKETS.add(ServerboundHandshakePacket.class); + SERVERBOUND_PACKETS.add(ServerboundSuccessfulHandshakePacket.class); SERVERBOUND_PACKETS.add(ServerboundRunCoreCommandPacket.class); + SERVERBOUND_PACKETS.add(ServerboundRunCommandPacket.class); } private static PrivateKey PRIVATE_KEY; @@ -56,9 +57,7 @@ public class ChomeNSModIntegrationPlugin implements ChatPlugin.Listener, Players private static final String BEGIN_PUBLIC_KEY = "-----BEGIN CHOMENS BOT PUBLIC KEY-----"; private static final String END_PUBLIC_KEY = "-----END CHOMENS BOT PUBLIC KEY-----"; - public static void init (Configuration config) { - if (!config.ownerAuthentication.enabled) return; - + public static void init () { try { // let's only check for the private key here if (!Files.exists(PRIVATE_KEY_PATH)) { @@ -132,15 +131,20 @@ public class ChomeNSModIntegrationPlugin implements ChatPlugin.Listener, Players private final Bot bot; + private final PacketHandler handler; + private final List listeners = new ArrayList<>(); public final List connectedPlayers = new ArrayList<>(); public ChomeNSModIntegrationPlugin (Bot bot) { this.bot = bot; + this.handler = new PacketHandler(bot); bot.chat.addListener(this); bot.players.addListener(this); + + bot.executor.scheduleAtFixedRate(this::tryHandshaking, 1, 1, TimeUnit.SECONDS); } public byte[] decrypt (byte[] data) throws Exception { @@ -160,11 +164,11 @@ public class ChomeNSModIntegrationPlugin implements ChatPlugin.Listener, Players final byte[] encryptedBytes = cipher.doFinal(data); - return Base64.getEncoder().encodeToString(encryptedBytes); + return Ascii85.encode(encryptedBytes); } public void send (PlayerEntry target, Packet packet) { - if (!connectedPlayers.contains(target)) return; + if (!connectedPlayers.contains(target) && !(packet instanceof ClientboundHandshakePacket)) return; // LoL sus check final ByteBuf buf = Unpooled.buffer(); @@ -177,11 +181,13 @@ public class ChomeNSModIntegrationPlugin implements ChatPlugin.Listener, Players try { final String encrypted = encrypt(target.profile.getName(), bytes); - final Component component = Component - .text(ID) - .append(Component.text(encrypted)); + final Component component = Component.translatable( + "", + Component.text(ID), + Component.text(encrypted) + ); - bot.chat.tellraw(component, target.profile.getId()); + bot.chat.actionBar(component, target.profile.getId()); } catch (Exception ignored) {} } @@ -222,7 +228,7 @@ public class ChomeNSModIntegrationPlugin implements ChatPlugin.Listener, Players final String data = dataComponent.content(); try { - final byte[] decrypted = decrypt(Base64.getDecoder().decode(data)); + final byte[] decrypted = decrypt(Ascii85.decode(data)); final Pair deserialized = deserialize(decrypted); @@ -232,72 +238,31 @@ public class ChomeNSModIntegrationPlugin implements ChatPlugin.Listener, Players final Packet packet = deserialized.getValue(); handlePacket(player, packet); - -// isAuthenticating = false; -// -// bot.logger.log( -// LogType.AUTH, -// Component -// .text("Player has been verified") -// .color(NamedTextColor.GREEN) -// ); -// -// final PlayerEntry target = bot.players.getEntry(bot.config.ownerName); -// -// if (target == null) return false; // sad :( -// -// bot.chat.tellraw( -// Component -// .text("You have been verified") -// .color(NamedTextColor.GREEN), -// target.profile.getId() -// ); } catch (Exception ignored) {} return false; } + private void tryHandshaking () { + // is looping through the usernames from the client public keys list a good idea? + for (String username : CLIENT_PUBLIC_KEYS.keySet()) { + final PlayerEntry target = bot.players.getEntry(username); + + if (target == null || connectedPlayers.contains(target)) continue; + + send(target, new ClientboundHandshakePacket()); + } + } + private void handlePacket (PlayerEntry player, Packet packet) { - if (packet instanceof ServerboundHandshakePacket t_packet) handlePacket(player, t_packet); - else if (packet instanceof ServerboundRunCoreCommandPacket t_packet) handlePacket(player, t_packet); - - for (Listener listener : listeners) listener.packetReceived(player, packet); - } - - private void handlePacket (PlayerEntry player, ServerboundHandshakePacket ignoredPacket) { - connectedPlayers.remove(player); - - connectedPlayers.add(player); - - send(player, new ClientboundSuccessfulHandshakePacket()); - } - - private void handlePacket (PlayerEntry player, ServerboundRunCoreCommandPacket packet) { - final CompletableFuture future = bot.core.runTracked(packet.command); - - if (future == null) { - send( - player, - new ClientboundCoreOutputPacket( - packet.runID, - Component.empty() - ) - ); - - return; + if (packet instanceof ServerboundSuccessfulHandshakePacket) { + connectedPlayers.remove(player); + connectedPlayers.add(player); } - future.thenApply(output -> { - send( - player, - new ClientboundCoreOutputPacket( - packet.runID, - output - ) - ); + handler.handlePacket(player, packet); - return null; - }); + for (Listener listener : listeners) listener.packetReceived(player, packet); } @Override diff --git a/src/main/java/me/chayapak1/chomens_bot/plugins/CommandHandlerPlugin.java b/src/main/java/me/chayapak1/chomens_bot/plugins/CommandHandlerPlugin.java index 6592b49f..22541ec2 100644 --- a/src/main/java/me/chayapak1/chomens_bot/plugins/CommandHandlerPlugin.java +++ b/src/main/java/me/chayapak1/chomens_bot/plugins/CommandHandlerPlugin.java @@ -86,7 +86,8 @@ public class CommandHandlerPlugin { ) { final boolean inGame = context instanceof PlayerCommandContext; final boolean discord = context instanceof DiscordCommandContext; - final boolean console = context instanceof ConsoleCommandContext; + + final boolean bypass = context instanceof ConsoleCommandContext || context instanceof ChomeNSModCommandContext; if (commandPerSecond > 100) return null; @@ -105,7 +106,7 @@ public class CommandHandlerPlugin { if (command == null && !inGame) return Component.text("Unknown command: " + commandName).color(NamedTextColor.RED); else if (command == null) return null; - if (!console && disabled) return Component.text("ChomeNS Bot is currently disabled").color(NamedTextColor.RED); + if (!bypass && disabled) return Component.text("ChomeNS Bot is currently disabled").color(NamedTextColor.RED); final TrustLevel trustLevel = command.trustLevel; @@ -118,7 +119,7 @@ public class CommandHandlerPlugin { final String[] args = Arrays.copyOfRange(splitInput, (trustLevel != TrustLevel.PUBLIC && inGame) ? 2 : 1, splitInput.length); - if (command.trustLevel != TrustLevel.PUBLIC && !console) { + if (command.trustLevel != TrustLevel.PUBLIC && !bypass) { if (discord) { final Member member = event.getMember(); @@ -167,7 +168,8 @@ public class CommandHandlerPlugin { } } - if (!console && command.consoleOnly) return Component.text("This command can only be run via console").color(NamedTextColor.RED); + // should i give access to all bypass contexts instead of only console? + if (!bypass && command.consoleOnly) return Component.text("This command can only be run via console").color(NamedTextColor.RED); // should these be here? context.fullArgs = fullArgs;