feat: make the chomens mod integration feel more like chomens proxy and also fix AuthPlugin
most stuff are still pretty broken, there's no chunking things yet, so long datas will simply just break, but it works!
This commit is contained in:
parent
265a35080b
commit
a2b564abf5
11 changed files with 228 additions and 228 deletions
build-number.txt
src/main/java/me/chayapak1/chomens_bot
|
@ -1 +1 @@
|
|||
2160
|
||||
2195
|
|
@ -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);
|
||||
|
|
|
@ -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<Component> 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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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<Class<? extends Packet>> 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<Listener> listeners = new ArrayList<>();
|
||||
|
||||
public final List<PlayerEntry> 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<PlayerEntry, Packet> 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<Component> 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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue