diff --git a/lib/consts.dart b/lib/consts.dart index 381bd70..38461ee 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -1,3 +1,3 @@ class Constants { - static const VERSION = "1.3.010625+0228"; + static const VERSION = "1.3.010625+1127"; } diff --git a/lib/packets/packets.dart b/lib/packets/packets.dart index 7ff3df0..7e028e6 100644 --- a/lib/packets/packets.dart +++ b/lib/packets/packets.dart @@ -38,6 +38,11 @@ enum EncryptionType { } } +class PacketsConsts { + /// Version of the packets system. Bumped when there is a major change to protocol + static const VERSION = 2; +} + class PacketServer { static ServerSocket? socket; static bool shouldRestart = true; @@ -46,9 +51,6 @@ class PacketServer { static String PSK = ""; static String TEA_SALT = "Harbinger 01/05/2025 @ 03:59:17 AM"; - /// Version of the packets system. Bumped when there is a major change to protocol - static const VERSION = 2; - /// Packet Data Format: /// /// 4 bytes (int) - Version @@ -163,7 +165,7 @@ class PacketServer { // NOTE: Added a length indicator because SocketServer is apparently... really really dumb in its impl, and has no way to know when all data has been received, so no special event. We just have to check for it based on this initial value. layer.clear(); - layer.writeInt(VERSION); + layer.writeInt(PacketsConsts.VERSION); layer.writeLong(nbtData.lengthInBytes + layer.currentPosition + 8); layer.writeBytes(nbtData); @@ -199,6 +201,11 @@ class PacketClient { String lastIP = ""; int port = 25306; int packetSequence = 0; + EncryptionType encryptionType = EncryptionType.NONE; + Uint8List aesKey = Uint8List(0); + + /// Used for xtea encryption + String PSK = ""; PacketClient(); @@ -251,7 +258,22 @@ class PacketClient { while (!success) { layer.clear(); + layer.writeInt(PacketsConsts.VERSION); layer.writeLong(packetSequence); + layer.writeByte(encryptionType.value); + + if (encryptionType == EncryptionType.AES) { + AESCipher aes = AESCipher.useKey(aesKey); + AESData encData = await aes.encrypt(nbtData); + layer.writeInt(encData.iv.length); + layer.writeBytes(encData.iv); + + nbtData = Uint8List.fromList(encData.data); + } else if (encryptionType == EncryptionType.XTEA) { + XTEA xtea = XTEA(PSK); + nbtData = Uint8List.fromList(await xtea.encipher(nbtData.toList())); + } + layer.writeLong(nbtData.lengthInBytes); layer.writeBytes(nbtData); var tmpBytes = layer.bytes; @@ -281,6 +303,14 @@ class PacketClient { reply.readLong(); // This is unused outside of the sanity check above. int sequence = reply.readLong(); int successReceipt = reply.readByte(); + EncryptionType encType = EncryptionType.valueOf(layer.readByte()); + List encIV = []; + + if (encType == EncryptionType.AES) { + int ivLen = layer.readInt(); + encIV = layer.readBytes(ivLen); + } + int numBytes = reply.readLong(); List pktBytes = reply.readBytes(numBytes); @@ -288,6 +318,15 @@ class PacketClient { success = true; if (success) { + if (encType == EncryptionType.AES) { + AESCipher aes = AESCipher.useKey(aesKey); + AESData encData = AESData(iv: encIV, data: pktBytes); + pktBytes = (await aes.decrypt(encData)).toList(); + } else if (encType == EncryptionType.XTEA) { + XTEA xtea = XTEA(PSK); + pktBytes = await xtea.decipher(pktBytes); + } + NBTTag = await NbtIo.readFromStream(Uint8List.fromList(pktBytes)); } diff --git a/pubspec.yaml b/pubspec.yaml index 739dc5d..183561b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: libac_dart description: "Aria's Creations code library" -version: 1.3.010625+0228 +version: 1.3.010625+1127 homepage: "https://zontreck.com" environment: