diff --git a/lib/consts.dart b/lib/consts.dart index ebe62f4..0c2066c 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -1,3 +1,3 @@ class Constants { - static const VERSION = "1.2.082924+1625"; + static const VERSION = "1.2.082924+1846"; } diff --git a/lib/packets/packets.dart b/lib/packets/packets.dart index 4b6a878..bb11756 100644 --- a/lib/packets/packets.dart +++ b/lib/packets/packets.dart @@ -14,6 +14,21 @@ import '../nbt/impl/StringTag.dart'; class PacketServer { static ServerSocket? socket; static bool shouldRestart = true; + + /// Packet Data Format: + /// + /// 8 Bytes (Long) - Total expected bytes of packet minus the 8 bytes here. + /// 8 bytes (Long) - Sequence ID + /// 8 bytes (Long) - Number of bytes to read + /// - NBT Data + /// + /// Response Format: + /// + /// 8 bytes (Long) - Total expected bytes in packet minus the 8 bytes here. + /// 1 byte - Success flag, Zero or 255 currently. + /// 8 byes (Long) - Packet Length + /// - NBT Data + /// static Future start(int port) async { socket = await ServerSocket.bind(InternetAddress.anyIPv4, port); print("Server now listening on port ${port}"); @@ -41,7 +56,6 @@ class PacketServer { layer.resetPosition(); layer.readLong(); // This is unused outside of the above sanity check. try { - List dataHash = layer.readBytes(32); // Sha256 int sequenceID = layer.readLong(); print("Sequence ID in request: $sequenceID"); @@ -49,53 +63,38 @@ class PacketServer { List remainingBytes = layer.readBytes(numBytes); - String sha256OriginalHash = Hashing.bytes2Hash(dataHash); - String sha256Hash = - Hashing.bytes2Hash(Hashing.sha1Sum(remainingBytes)); - if (sha256OriginalHash == sha256Hash) { - CompoundTag tag = await NbtIo.readFromStream( - Uint8List.fromList(remainingBytes)); - StringBuilder builder = StringBuilder(); - Tag.writeStringifiedNamedTag(tag, builder, 0); + CompoundTag tag = + await NbtIo.readFromStream(Uint8List.fromList(remainingBytes)); + StringBuilder builder = StringBuilder(); + Tag.writeStringifiedNamedTag(tag, builder, 0); - print("Request from client: \n${builder}"); + print("Request from client: \n${builder}"); - C2SRequestPacket request = C2SRequestPacket(); - request.decodeTag(tag); + C2SRequestPacket request = C2SRequestPacket(); + request.decodeTag(tag); - PacketResponse reply = await request.handleServerPacket(); + PacketResponse reply = await request.handleServerPacket(); - // Server uses NBT to communicate - builder = StringBuilder(); - Tag.writeStringifiedNamedTag(reply.replyDataTag, builder, 0); + // Server uses NBT to communicate + builder = StringBuilder(); + Tag.writeStringifiedNamedTag(reply.replyDataTag, builder, 0); - print("Response to client: \n${builder}"); - Uint8List nbtData = await NbtIo.writeToStream(reply.replyDataTag); + print("Response to client: \n${builder}"); + Uint8List nbtData = await NbtIo.writeToStream(reply.replyDataTag); - layer.clear(); - layer.writeLong(sequenceID); - layer.writeByte(0xFF); // Successful receipt - layer.writeBytes(Hashing.sha256Sum(nbtData)); - layer.writeLong(nbtData.lengthInBytes); - layer.writeBytes(nbtData); - nbtData = layer.bytes; + layer.clear(); + layer.writeLong(sequenceID); + layer.writeByte(0xFF); // Successful receipt + layer.writeLong(nbtData.lengthInBytes); + layer.writeBytes(nbtData); + nbtData = layer.bytes; - // 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.writeLong(nbtData.lengthInBytes); - layer.writeBytes(nbtData); + // 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.writeLong(nbtData.lengthInBytes); + layer.writeBytes(nbtData); - sock.add(layer.bytes); - } else { - // Return a failure packet - layer.clear(); - layer.writeLong(sequenceID); - layer.writeByte(0x00); - - sock.add(layer.bytes); // Failure code. - print( - "ERROR: The inbound hash did not match real hash: $sha256OriginalHash != $sha256Hash\n> REFUSING TO PROCESS PACKET. SENDING ERROR CODE TO CLIENT"); - } + sock.add(layer.bytes); } catch (E, stack) { response.contents .put("error", StringTag.valueOf("Malformed request packet")); @@ -145,6 +144,21 @@ class PacketClient { /// Tries to send a packet to the connected server /// /// On success, returns either, the decoded [S2CResponse], or on error a S2CResponse containing an error and a stacktrace as [StringTag] + /// + /// Packet Data Format: + /// + /// 8 Bytes (Long) - Total expected bytes of packet minus the 8 bytes here. + /// 8 bytes (Long) - Sequence ID + /// 8 bytes (Long) - Number of bytes to read + /// - NBT Data + /// + /// Response Format: + /// + /// 8 bytes (Long) - Total expected bytes in packet minus the 8 bytes here. + /// 1 byte - Success flag, Zero or 255 currently. + /// 8 byes (Long) - Packet Length + /// - NBT Data + /// Future send(IPacket packet, bool shouldReconnect) async { if (!connected) { return S2CResponse(); @@ -158,14 +172,12 @@ class PacketClient { Uint8List nbtData = await NbtIo.writeToStream(request.encodeTag().asCompoundTag()); - List nbtDataHash = Hashing.sha256Sum(nbtData); ByteLayer reply = ByteLayer(); CompoundTag NBTTag = CompoundTag(); while (!success) { layer.clear(); - layer.writeBytes(nbtDataHash); layer.writeLong(packetSequence); layer.writeLong(nbtData.lengthInBytes); layer.writeBytes(nbtData); @@ -196,15 +208,11 @@ class PacketClient { reply.readLong(); // This is unused outside of the sanity check above. int sequence = reply.readLong(); int successReceipt = reply.readByte(); - List serverHash = reply.readBytes(32); - String srvHashStr = Hashing.bytes2Hash(serverHash); int numBytes = reply.readLong(); List pktBytes = reply.readBytes(numBytes); - String pktHash = Hashing.bytes2Hash(Hashing.sha256Sum(pktBytes)); - if (successReceipt == 0xFF && - packetSequence == sequence && - srvHashStr == pktHash) success = true; + if (successReceipt == 0xFF && packetSequence == sequence) + success = true; if (success) { NBTTag = await NbtIo.readFromStream(Uint8List.fromList(pktBytes)); diff --git a/pubspec.yaml b/pubspec.yaml index 52cea17..755ffaf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: libac_dart description: "Aria's Creations code library" -version: 1.2.082924+1625 +version: 1.2.082924+1846 homepage: "https://zontreck.com" diff --git a/test/hash_test.dart b/test/hash_test.dart index 1ec7fdf..597cad9 100644 --- a/test/hash_test.dart +++ b/test/hash_test.dart @@ -1,3 +1,6 @@ +import 'dart:typed_data'; + +import 'package:libac_dart/nbt/Stream.dart'; import 'package:libac_dart/utils/Hashing.dart'; import 'package:test/expect.dart'; import 'package:test/scaffolding.dart'; @@ -8,8 +11,12 @@ void main() { }); test("Test sha256", () { - List hsh = Hashing.sha256Sum([0x0A, 0x0B]); - print("Sha256 Length: ${hsh.length}"); + Uint8List hsh = Uint8List.fromList(Hashing.sha256Sum([0x0A, 0x0B])); + print("Sha256 Length: ${hsh.lengthInBytes}"); + + ByteLayer layer = ByteLayer(); + layer.writeBytes(hsh); + print("Layer length: ${layer.bytes.lengthInBytes}"); print("Sha256 Hash: ${Hashing.bytes2Hash(hsh)}");