Remove hash check, and document packet format inbound and out
This commit is contained in:
parent
d1ff953717
commit
a126358c5f
4 changed files with 67 additions and 52 deletions
|
@ -1,3 +1,3 @@
|
||||||
class Constants {
|
class Constants {
|
||||||
static const VERSION = "1.2.082924+1625";
|
static const VERSION = "1.2.082924+1846";
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,21 @@ import '../nbt/impl/StringTag.dart';
|
||||||
class PacketServer {
|
class PacketServer {
|
||||||
static ServerSocket? socket;
|
static ServerSocket? socket;
|
||||||
static bool shouldRestart = true;
|
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
|
||||||
|
/// <arbitrary> - 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
|
||||||
|
/// <arbitrary> - NBT Data
|
||||||
|
///
|
||||||
static Future<void> start(int port) async {
|
static Future<void> start(int port) async {
|
||||||
socket = await ServerSocket.bind(InternetAddress.anyIPv4, port);
|
socket = await ServerSocket.bind(InternetAddress.anyIPv4, port);
|
||||||
print("Server now listening on port ${port}");
|
print("Server now listening on port ${port}");
|
||||||
|
@ -41,7 +56,6 @@ class PacketServer {
|
||||||
layer.resetPosition();
|
layer.resetPosition();
|
||||||
layer.readLong(); // This is unused outside of the above sanity check.
|
layer.readLong(); // This is unused outside of the above sanity check.
|
||||||
try {
|
try {
|
||||||
List<int> dataHash = layer.readBytes(32); // Sha256
|
|
||||||
int sequenceID = layer.readLong();
|
int sequenceID = layer.readLong();
|
||||||
print("Sequence ID in request: $sequenceID");
|
print("Sequence ID in request: $sequenceID");
|
||||||
|
|
||||||
|
@ -49,53 +63,38 @@ class PacketServer {
|
||||||
|
|
||||||
List<int> remainingBytes = layer.readBytes(numBytes);
|
List<int> remainingBytes = layer.readBytes(numBytes);
|
||||||
|
|
||||||
String sha256OriginalHash = Hashing.bytes2Hash(dataHash);
|
CompoundTag tag =
|
||||||
String sha256Hash =
|
await NbtIo.readFromStream(Uint8List.fromList(remainingBytes));
|
||||||
Hashing.bytes2Hash(Hashing.sha1Sum(remainingBytes));
|
StringBuilder builder = StringBuilder();
|
||||||
if (sha256OriginalHash == sha256Hash) {
|
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();
|
C2SRequestPacket request = C2SRequestPacket();
|
||||||
request.decodeTag(tag);
|
request.decodeTag(tag);
|
||||||
|
|
||||||
PacketResponse reply = await request.handleServerPacket();
|
PacketResponse reply = await request.handleServerPacket();
|
||||||
|
|
||||||
// Server uses NBT to communicate
|
// Server uses NBT to communicate
|
||||||
builder = StringBuilder();
|
builder = StringBuilder();
|
||||||
Tag.writeStringifiedNamedTag(reply.replyDataTag, builder, 0);
|
Tag.writeStringifiedNamedTag(reply.replyDataTag, builder, 0);
|
||||||
|
|
||||||
print("Response to client: \n${builder}");
|
print("Response to client: \n${builder}");
|
||||||
Uint8List nbtData = await NbtIo.writeToStream(reply.replyDataTag);
|
Uint8List nbtData = await NbtIo.writeToStream(reply.replyDataTag);
|
||||||
|
|
||||||
layer.clear();
|
layer.clear();
|
||||||
layer.writeLong(sequenceID);
|
layer.writeLong(sequenceID);
|
||||||
layer.writeByte(0xFF); // Successful receipt
|
layer.writeByte(0xFF); // Successful receipt
|
||||||
layer.writeBytes(Hashing.sha256Sum(nbtData));
|
layer.writeLong(nbtData.lengthInBytes);
|
||||||
layer.writeLong(nbtData.lengthInBytes);
|
layer.writeBytes(nbtData);
|
||||||
layer.writeBytes(nbtData);
|
nbtData = layer.bytes;
|
||||||
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.
|
// 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.clear();
|
||||||
layer.writeLong(nbtData.lengthInBytes);
|
layer.writeLong(nbtData.lengthInBytes);
|
||||||
layer.writeBytes(nbtData);
|
layer.writeBytes(nbtData);
|
||||||
|
|
||||||
sock.add(layer.bytes);
|
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");
|
|
||||||
}
|
|
||||||
} catch (E, stack) {
|
} catch (E, stack) {
|
||||||
response.contents
|
response.contents
|
||||||
.put("error", StringTag.valueOf("Malformed request packet"));
|
.put("error", StringTag.valueOf("Malformed request packet"));
|
||||||
|
@ -145,6 +144,21 @@ class PacketClient {
|
||||||
/// Tries to send a packet to the connected server
|
/// 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]
|
/// 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
|
||||||
|
/// <arbitrary> - 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
|
||||||
|
/// <arbitrary> - NBT Data
|
||||||
|
///
|
||||||
Future<S2CResponse> send(IPacket packet, bool shouldReconnect) async {
|
Future<S2CResponse> send(IPacket packet, bool shouldReconnect) async {
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
return S2CResponse();
|
return S2CResponse();
|
||||||
|
@ -158,14 +172,12 @@ class PacketClient {
|
||||||
|
|
||||||
Uint8List nbtData =
|
Uint8List nbtData =
|
||||||
await NbtIo.writeToStream(request.encodeTag().asCompoundTag());
|
await NbtIo.writeToStream(request.encodeTag().asCompoundTag());
|
||||||
List<int> nbtDataHash = Hashing.sha256Sum(nbtData);
|
|
||||||
|
|
||||||
ByteLayer reply = ByteLayer();
|
ByteLayer reply = ByteLayer();
|
||||||
CompoundTag NBTTag = CompoundTag();
|
CompoundTag NBTTag = CompoundTag();
|
||||||
|
|
||||||
while (!success) {
|
while (!success) {
|
||||||
layer.clear();
|
layer.clear();
|
||||||
layer.writeBytes(nbtDataHash);
|
|
||||||
layer.writeLong(packetSequence);
|
layer.writeLong(packetSequence);
|
||||||
layer.writeLong(nbtData.lengthInBytes);
|
layer.writeLong(nbtData.lengthInBytes);
|
||||||
layer.writeBytes(nbtData);
|
layer.writeBytes(nbtData);
|
||||||
|
@ -196,15 +208,11 @@ class PacketClient {
|
||||||
reply.readLong(); // This is unused outside of the sanity check above.
|
reply.readLong(); // This is unused outside of the sanity check above.
|
||||||
int sequence = reply.readLong();
|
int sequence = reply.readLong();
|
||||||
int successReceipt = reply.readByte();
|
int successReceipt = reply.readByte();
|
||||||
List<int> serverHash = reply.readBytes(32);
|
|
||||||
String srvHashStr = Hashing.bytes2Hash(serverHash);
|
|
||||||
int numBytes = reply.readLong();
|
int numBytes = reply.readLong();
|
||||||
List<int> pktBytes = reply.readBytes(numBytes);
|
List<int> pktBytes = reply.readBytes(numBytes);
|
||||||
String pktHash = Hashing.bytes2Hash(Hashing.sha256Sum(pktBytes));
|
|
||||||
|
|
||||||
if (successReceipt == 0xFF &&
|
if (successReceipt == 0xFF && packetSequence == sequence)
|
||||||
packetSequence == sequence &&
|
success = true;
|
||||||
srvHashStr == pktHash) success = true;
|
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
NBTTag = await NbtIo.readFromStream(Uint8List.fromList(pktBytes));
|
NBTTag = await NbtIo.readFromStream(Uint8List.fromList(pktBytes));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: libac_dart
|
name: libac_dart
|
||||||
description: "Aria's Creations code library"
|
description: "Aria's Creations code library"
|
||||||
version: 1.2.082924+1625
|
version: 1.2.082924+1846
|
||||||
homepage: "https://zontreck.com"
|
homepage: "https://zontreck.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:libac_dart/nbt/Stream.dart';
|
||||||
import 'package:libac_dart/utils/Hashing.dart';
|
import 'package:libac_dart/utils/Hashing.dart';
|
||||||
import 'package:test/expect.dart';
|
import 'package:test/expect.dart';
|
||||||
import 'package:test/scaffolding.dart';
|
import 'package:test/scaffolding.dart';
|
||||||
|
@ -8,8 +11,12 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Test sha256", () {
|
test("Test sha256", () {
|
||||||
List<int> hsh = Hashing.sha256Sum([0x0A, 0x0B]);
|
Uint8List hsh = Uint8List.fromList(Hashing.sha256Sum([0x0A, 0x0B]));
|
||||||
print("Sha256 Length: ${hsh.length}");
|
print("Sha256 Length: ${hsh.lengthInBytes}");
|
||||||
|
|
||||||
|
ByteLayer layer = ByteLayer();
|
||||||
|
layer.writeBytes(hsh);
|
||||||
|
print("Layer length: ${layer.bytes.lengthInBytes}");
|
||||||
|
|
||||||
print("Sha256 Hash: ${Hashing.bytes2Hash(hsh)}");
|
print("Sha256 Hash: ${Hashing.bytes2Hash(hsh)}");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue