diff --git a/src/main/java/net/pistonmaster/serverwrecker/addons/AutoRegister.java b/src/main/java/net/pistonmaster/serverwrecker/addons/AutoRegister.java index 6600fe1d8..1d3f47037 100644 --- a/src/main/java/net/pistonmaster/serverwrecker/addons/AutoRegister.java +++ b/src/main/java/net/pistonmaster/serverwrecker/addons/AutoRegister.java @@ -58,15 +58,18 @@ public void onChat(ChatMessageReceiveEvent event) { // TODO: Add more password options if (plainMessage.contains("/register")) { - event.connection().sendMessage(autoRegisterSettings.registerCommand().replace("%password%", password)); + event.connection().botControl() + .sendMessage(autoRegisterSettings.registerCommand().replace("%password%", password)); } else if (plainMessage.contains("/login")) { - event.connection().sendMessage(autoRegisterSettings.loginCommand().replace("%password%", password)); + event.connection().botControl() + .sendMessage(autoRegisterSettings.loginCommand().replace("%password%", password)); } else if (plainMessage.contains("/captcha")) { String[] split = plainMessage.split(" "); for (int i = 0; i < split.length; i++) { if (split[i].equals("/captcha")) { - event.connection().sendMessage(autoRegisterSettings.captchaCommand().replace("%captcha%", split[i + 1])); + event.connection().botControl() + .sendMessage(autoRegisterSettings.captchaCommand().replace("%captcha%", split[i + 1])); } } } diff --git a/src/main/java/net/pistonmaster/serverwrecker/logging/CommandManager.java b/src/main/java/net/pistonmaster/serverwrecker/logging/CommandManager.java index 309e7768b..bf958d2bf 100644 --- a/src/main/java/net/pistonmaster/serverwrecker/logging/CommandManager.java +++ b/src/main/java/net/pistonmaster/serverwrecker/logging/CommandManager.java @@ -75,7 +75,7 @@ public void postConstruct() { String message = StringArgumentType.getString(c, "message"); serverWrecker.getBotConnections().forEach(client -> { if (client.isOnline()) { - client.sendMessage(message); + client.botControl().sendMessage(message); } }); return 1; diff --git a/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnection.java b/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnection.java index 2e0e43514..26f5eb8aa 100644 --- a/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnection.java +++ b/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnection.java @@ -25,6 +25,7 @@ import io.netty.handler.traffic.GlobalTrafficShapingHandler; import net.pistonmaster.serverwrecker.ServerWrecker; import net.pistonmaster.serverwrecker.api.event.UnregisterCleanup; +import net.pistonmaster.serverwrecker.protocol.bot.BotControlAPI; import net.pistonmaster.serverwrecker.protocol.bot.SessionDataManager; import net.pistonmaster.serverwrecker.protocol.netty.ViaClientSession; import net.pistonmaster.serverwrecker.settings.lib.SettingsHolder; @@ -37,14 +38,6 @@ public record BotConnection(BotConnectionFactory factory, ServerWrecker serverWrecker, SettingsHolder settingsHolder, Logger logger, MinecraftProtocol protocol, ViaClientSession session, BotConnectionMeta meta) { - public void sendMessage(String message) { - if (message.startsWith("/")) { - session.send(new ServerboundChatCommandPacket(message.substring(1), Instant.now().toEpochMilli(), 0, Collections.emptyList(), 0, new BitSet())); - } else { - session.send(new ServerboundChatPacket(message, Instant.now().toEpochMilli(), 0, new byte[0], 0, new BitSet())); - } - } - public boolean isOnline() { return session.isConnected(); } @@ -54,7 +47,11 @@ public void disconnect() { } public SessionDataManager sessionDataManager() { - return session.getFlag(SWProtocolConstants.SESSION_DATA_MANAGER); + return meta.getSessionDataManager(); + } + + public BotControlAPI botControl() { + return meta.getBotControlAPI(); } public T cleanup(T instance) { diff --git a/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnectionFactory.java b/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnectionFactory.java index cf8d72158..5a99db232 100644 --- a/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnectionFactory.java +++ b/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnectionFactory.java @@ -28,6 +28,7 @@ import net.pistonmaster.serverwrecker.api.event.UnregisterCleanup; import net.pistonmaster.serverwrecker.api.event.bot.PreBotConnectEvent; import net.pistonmaster.serverwrecker.auth.MinecraftAccount; +import net.pistonmaster.serverwrecker.protocol.bot.BotControlAPI; import net.pistonmaster.serverwrecker.protocol.bot.SessionDataManager; import net.pistonmaster.serverwrecker.protocol.netty.ViaClientSession; import net.pistonmaster.serverwrecker.proxy.SWProxy; @@ -55,7 +56,8 @@ public BotConnection connectInternal(ProtocolState targetState) { session.setPostDisconnectHook(() -> botConnection.meta().getUnregisterCleanups().forEach(UnregisterCleanup::cleanup)); SessionDataManager sessionDataManager = new SessionDataManager(botConnection); - session.setFlag(SWProtocolConstants.SESSION_DATA_MANAGER, sessionDataManager); + session.getMeta().setSessionDataManager(sessionDataManager); + session.getMeta().setBotControlAPI(new BotControlAPI(sessionDataManager, sessionDataManager.getBotMovementManager())); DevSettings devSettings = settingsHolder.get(DevSettings.class); session.setFlag(BuiltinFlags.PRINT_DEBUG, devSettings.debug()); diff --git a/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnectionMeta.java b/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnectionMeta.java index 2f634d615..560ef036d 100644 --- a/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnectionMeta.java +++ b/src/main/java/net/pistonmaster/serverwrecker/protocol/BotConnectionMeta.java @@ -24,9 +24,12 @@ import com.github.steveice10.mc.auth.exception.request.ServiceUnavailableException; import com.github.steveice10.mc.protocol.data.ProtocolState; import lombok.Getter; +import lombok.Setter; import net.pistonmaster.serverwrecker.api.event.UnregisterCleanup; import net.pistonmaster.serverwrecker.auth.MinecraftAccount; import net.pistonmaster.serverwrecker.auth.service.JavaData; +import net.pistonmaster.serverwrecker.protocol.bot.BotControlAPI; +import net.pistonmaster.serverwrecker.protocol.bot.SessionDataManager; import net.pistonmaster.serverwrecker.protocol.netty.ViaClientSession; import java.util.ArrayList; @@ -38,6 +41,10 @@ public class BotConnectionMeta { private final MinecraftAccount minecraftAccount; private final ProtocolState targetState; private final SWSessionService sessionService; + @Setter + private SessionDataManager sessionDataManager; + @Setter + private BotControlAPI botControlAPI; public BotConnectionMeta(MinecraftAccount minecraftAccount, ProtocolState targetState) { this.minecraftAccount = minecraftAccount; diff --git a/src/main/java/net/pistonmaster/serverwrecker/protocol/SWProtocolConstants.java b/src/main/java/net/pistonmaster/serverwrecker/protocol/SWProtocolConstants.java index 6cce7468a..1e59c81a9 100644 --- a/src/main/java/net/pistonmaster/serverwrecker/protocol/SWProtocolConstants.java +++ b/src/main/java/net/pistonmaster/serverwrecker/protocol/SWProtocolConstants.java @@ -21,7 +21,6 @@ public class SWProtocolConstants { public static final String ENCRYPTION_SECRET_KEY = "encryption-secret-key"; - public static final String SESSION_DATA_MANAGER = "session-data-manager"; public static final String VIA_USER_CONNECTION = "via-user-connection"; public static final String TRAFFIC_HANDLER = "netty-traffic-handler"; } diff --git a/src/main/java/net/pistonmaster/serverwrecker/protocol/bot/BotControlAPI.java b/src/main/java/net/pistonmaster/serverwrecker/protocol/bot/BotControlAPI.java index 9664e0349..d46490e0f 100644 --- a/src/main/java/net/pistonmaster/serverwrecker/protocol/bot/BotControlAPI.java +++ b/src/main/java/net/pistonmaster/serverwrecker/protocol/bot/BotControlAPI.java @@ -20,11 +20,18 @@ package net.pistonmaster.serverwrecker.protocol.bot; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket; +import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket; import lombok.RequiredArgsConstructor; import net.pistonmaster.serverwrecker.protocol.bot.model.AbilitiesData; +import java.security.SecureRandom; +import java.time.Instant; +import java.util.BitSet; +import java.util.Collections; + /** * This class is used to control the bot. * The goal is to reduce friction for doing simple things. @@ -33,6 +40,7 @@ public class BotControlAPI { private final SessionDataManager sessionDataManager; private final BotMovementManager botMovementManager; + private final SecureRandom secureRandom = new SecureRandom(); public boolean toggleFlight() { AbilitiesData abilitiesData = sessionDataManager.getAbilitiesData(); @@ -74,4 +82,31 @@ public boolean toggleSneak() { return newSneak; } + + public void sendMessage(String message) { + Instant now = Instant.now(); + if (message.startsWith("/")) { + String command = message.substring(1); + // We only sign chat at the moment because commands require the entire command tree to be handled + // Command signing is signing every string parameter in the command because of reporting /msg + sessionDataManager.getSession().send(new ServerboundChatCommandPacket( + command, + now.toEpochMilli(), + 0L, + Collections.emptyList(), + 0, + new BitSet() + )); + } else { + long salt = secureRandom.nextLong(); + sessionDataManager.getSession().send(new ServerboundChatPacket( + message, + now.toEpochMilli(), + salt, + null, + 0, + new BitSet() + )); + } + } } diff --git a/src/main/java/net/pistonmaster/serverwrecker/protocol/bot/state/LastSeenMessagesState.java b/src/main/java/net/pistonmaster/serverwrecker/protocol/bot/state/LastSeenMessagesState.java new file mode 100644 index 000000000..450cbe4ab --- /dev/null +++ b/src/main/java/net/pistonmaster/serverwrecker/protocol/bot/state/LastSeenMessagesState.java @@ -0,0 +1,23 @@ +/* + * ServerWrecker + * + * Copyright (C) 2023 ServerWrecker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * . + */ +package net.pistonmaster.serverwrecker.protocol.bot.state; + +public class LastSeenMessagesState { +}