diff --git a/src/client.zig b/src/client.zig index fc55720..7b054ec 100644 --- a/src/client.zig +++ b/src/client.zig @@ -46,14 +46,14 @@ pub const Client = struct { try map.put("ProtocolVersion", .{ .UInt = 10 }); try map.put("ClientVersion", .{ .String = "0.1 (quasselclient)" }); try map.put("ClientDate", .{ .String = "Wed, 02 Jun 2021 17:30:30 +0100" }); - try map.put("Features", .{ .Int = 0 }); + try map.put("Features", .{ .Int = 0x00008000 }); var featureList = std.ArrayList([]const u8).init(s.allocator); defer featureList.deinit(); - try featureList.put("LongTime"); - try featureList.put("SenderPrefixes"); - try featureList.put("RichMessages"); + try featureList.append("LongTime"); + try featureList.append("SenderPrefixes"); + try featureList.append("RichMessages"); - try map.put("FeatureList", .{ .QStringList = empty.items }); + try map.put("FeatureList", .{ .QStringList = featureList.items }); try write.writeFrame(list.writer(), s.allocator, map); try dumpDebug("ClientInit.bin", list); diff --git a/src/qtshit/read/readQByteArray.zig b/src/qtshit/read/readQByteArray.zig index 1968162..1ff40cd 100644 --- a/src/qtshit/read/readQByteArray.zig +++ b/src/qtshit/read/readQByteArray.zig @@ -3,17 +3,22 @@ const readUInt = @import("./readUInt.zig").readUInt; pub fn readQByteArray(reader: anytype, allocator: *std.mem.Allocator) ![]u8 { var length = try readUInt(reader); - //std.debug.print("read: readQByteArray length={d} \n", .{length}); + if (length == 4294967295) { + return ""; + } + //std.debug.print("read: readQByteArray length={d}\n", .{length}); var byteList = try allocator.alloc(u8, @intCast(usize, length)); var index: usize = 0; while (true) { //std.debug.print("read: readQByteArray length={d} index={d} \n", .{length, index}); + //std.debug.print("read: readQByteArray \"{s}\" \n", .{byteList}); if (index == length) return byteList; const byte = try reader.readByte(); byteList[index] = byte; index += 1; } + } diff --git a/src/qtshit/read/usertypes/readBufferInfo.zig b/src/qtshit/read/usertypes/readBufferInfo.zig new file mode 100644 index 0000000..1f5ac09 --- /dev/null +++ b/src/qtshit/read/usertypes/readBufferInfo.zig @@ -0,0 +1,25 @@ +const std = @import("std"); +const BufferInfo = @import("../../types/UserType.zig").BufferInfo; +const readInt = @import("../readInt.zig").readInt; +const readShort = @import("../readShort.zig").readShort; +const readByte = @import("../readByte.zig").readByte; +const readQByteArray = @import("../readQByteArray.zig").readQByteArray; + +pub fn readBufferInfo(reader: anytype, allocator: *std.mem.Allocator) !BufferInfo { + var id = try readInt(reader); + var networkid = try readInt(reader); + var btype = try readShort(reader); + // 4 undocumented bytes. + _ = try readByte(reader); + _ = try readByte(reader); + _ = try readByte(reader); + _ = try readByte(reader); + var name = try readQByteArray(reader, allocator); + + return BufferInfo{ + .ID = id, + .NetworkID = networkid, + .Type = btype, + .Name = name, + }; +} diff --git a/src/qtshit/read/usertypes/readMessage.zig b/src/qtshit/read/usertypes/readMessage.zig new file mode 100644 index 0000000..5083a6d --- /dev/null +++ b/src/qtshit/read/usertypes/readMessage.zig @@ -0,0 +1,22 @@ +const std = @import("std"); +const Message = @import("../../types/UserType.zig").Message; +const readInt = @import("../readInt.zig").readInt; +const readLong = @import("../readLong.zig").readLong; +const readByte = @import("../readByte.zig").readByte; +const readBufferInfo = @import("./readBufferInfo.zig").readBufferInfo; +const readQByteArray = @import("../readQByteArray.zig").readQByteArray; + +pub fn readMessage(reader: anytype, allocator: *std.mem.Allocator) !Message { + return Message{ + .MessageID = try readInt(reader), + .Timestamp = try readLong(reader), + .Type = try readInt(reader), + .Flags = try readByte(reader), + .Buffer = try readBufferInfo(reader, allocator), + .Sender = try readQByteArray(reader, allocator), + .SenderPrefixes = try readQByteArray(reader, allocator), + .RealName = try readQByteArray(reader, allocator), + .AvatarUrl = try readQByteArray(reader, allocator), + .Content = try readQByteArray(reader, allocator), + }; +} diff --git a/src/qtshit/read/usertypes/readUserType.zig b/src/qtshit/read/usertypes/readUserType.zig index 36e0dcc..413e353 100644 --- a/src/qtshit/read/usertypes/readUserType.zig +++ b/src/qtshit/read/usertypes/readUserType.zig @@ -7,6 +7,9 @@ const readByte = @import("../readByte.zig").readByte; const readLong = @import("../readLong.zig").readLong; const readQByteArray = @import("../readQByteArray.zig").readQByteArray; const readQVariantMap = @import("../readQVariantMap.zig").readQVariantMap; +const readBufferInfo = @import("./readBufferInfo.zig").readBufferInfo; +const readMessage = @import("./readMessage.zig").readMessage; + pub fn readUserType(reader: anytype, allocator: *std.mem.Allocator) !UserType { var userTypeName = try readQByteArray(reader, allocator); @@ -54,26 +57,14 @@ pub fn readUserType(reader: anytype, allocator: *std.mem.Allocator) !UserType { .NetworkServer = try readQVariantMap(reader, allocator), }; } else if (std.mem.eql(u8, userTypeName, "BufferInfo")) { - - var id = try readInt(reader); - var networkid = try readInt(reader); - var btype = try readShort(reader); - // 4 undocumented bytes. - _ = try readByte(reader); - _ = try readByte(reader); - _ = try readByte(reader); - _ = try readByte(reader); - var name = try readQByteArray(reader, allocator); - return UserType{ - .BufferInfo = .{ - .ID = id, - .NetworkID = networkid, - .Type = btype, - .Name = name, - }, + .BufferInfo = try readBufferInfo(reader, allocator), }; - } else { + } else if (std.mem.eql(u8, userTypeName, "Message")) { + return UserType{ + .Message = try readMessage(reader, allocator), + }; + }else { std.debug.print("Unknown UserType With Name: {s}\n", .{userTypeName}); @panic("Unknown Usertype."); } diff --git a/src/qtshit/types/UserType.zig b/src/qtshit/types/UserType.zig index b7e2b09..e9b54d2 100644 --- a/src/qtshit/types/UserType.zig +++ b/src/qtshit/types/UserType.zig @@ -13,6 +13,7 @@ pub const UserType = union(enum) { NetworkInfo: std.StringHashMap(QVariant), NetworkServer: std.StringHashMap(QVariant), BufferInfo: BufferInfo, + Message: Message, }; pub const BufferInfo = struct { @@ -20,4 +21,17 @@ pub const BufferInfo = struct { NetworkID: i32, Type: u16, Name: []u8, +}; + +pub const Message = struct { + MessageID: i32, + Timestamp: i64, + Type: i32, + Flags: u8, + Buffer: BufferInfo, + Sender: []u8, + SenderPrefixes: []u8, + RealName: []u8, + AvatarUrl: []u8, + Content: []u8, }; \ No newline at end of file diff --git a/src/qtshit/utils/freeQVariant.zig b/src/qtshit/utils/freeQVariant.zig index 1d27b4b..5be73b2 100644 --- a/src/qtshit/utils/freeQVariant.zig +++ b/src/qtshit/utils/freeQVariant.zig @@ -51,6 +51,13 @@ pub fn freeQVariant(variant: QVariant, allocator: *std.mem.Allocator) void { .BufferInfo => |value| { allocator.free(value.Name); }, + .Message => |value| { + allocator.free(value.Buffer.Name); + allocator.free(value.SenderPrefixes); + allocator.free(value.RealName); + allocator.free(value.AvatarUrl); + allocator.free(value.Content); + } } }, } diff --git a/src/qtshit/utils/prettyPrintQVariant.zig b/src/qtshit/utils/prettyPrintQVariant.zig index 86542fe..f9b0f0d 100644 --- a/src/qtshit/utils/prettyPrintQVariant.zig +++ b/src/qtshit/utils/prettyPrintQVariant.zig @@ -1,6 +1,7 @@ const std = @import("std"); const QVariant = @import("../types/QVariant.zig").QVariant; const UserType = @import("../types/UserType.zig").UserType; +const BufferInfo = @import("../types/UserType.zig").BufferInfo; const range = @import("../utils/RangeIter.zig").range; @@ -11,6 +12,18 @@ pub fn print_indent_level(indentLevel: u64) void { } } +pub fn prettyPrintBufferInfo(value: BufferInfo, indentLevel: u64) void { + std.debug.print("BufferInfo:\n", .{}); + print_indent_level(indentLevel + 1); + std.debug.print("ID: {d}\n", .{value.ID}); + print_indent_level(indentLevel + 1); + std.debug.print("NetworkID: {d}\n", .{value.NetworkID}); + print_indent_level(indentLevel + 1); + std.debug.print("Type: {d}\n", .{value.Type}); + print_indent_level(indentLevel + 1); + std.debug.print("Name: {s}\n", .{value.Name}); +} + pub fn prettyPrintUserType(usertype: UserType, indentLevel: u64) void { switch (usertype) { .BufferId => |value| { @@ -49,15 +62,42 @@ pub fn prettyPrintUserType(usertype: UserType, indentLevel: u64) void { prettyPrintQVariantMap(value, indentLevel + 1); }, .BufferInfo => |value| { - std.debug.print("BufferInfo:\n", .{}); + prettyPrintBufferInfo(value, indentLevel); + }, + .Message => |value| { + std.debug.print("Message:\n", .{}); + print_indent_level(indentLevel + 1); - std.debug.print("ID: {d}\n", .{value.ID}); + std.debug.print("MessageID: {d}\n", .{value.MessageID}); + print_indent_level(indentLevel + 1); - std.debug.print("NetworkID: {d}\n", .{value.NetworkID}); + std.debug.print("Timestamp: {d}\n", .{value.Timestamp}); + print_indent_level(indentLevel + 1); std.debug.print("Type: {d}\n", .{value.Type}); + print_indent_level(indentLevel + 1); - std.debug.print("Name: {s}\n", .{value.Name}); + std.debug.print("Flags: {d}\n", .{value.Flags}); + + print_indent_level(indentLevel + 1); + std.debug.print("Buffer:\n", .{}); + print_indent_level(indentLevel + 1); + prettyPrintBufferInfo(value.Buffer, indentLevel + 2); + + print_indent_level(indentLevel + 1); + std.debug.print("Sender: {s}\n", .{value.Sender}); + + print_indent_level(indentLevel + 1); + std.debug.print("SenderPrefixes: {s}\n", .{value.SenderPrefixes}); + + print_indent_level(indentLevel + 1); + std.debug.print("RealName: {s}\n", .{value.RealName}); + + print_indent_level(indentLevel + 1); + std.debug.print("AvatarUrl: {s}\n", .{value.AvatarUrl}); + + print_indent_level(indentLevel + 1); + std.debug.print("Content: {s}\n", .{value.Content}); }, //else => { // std.debug.print("Unknown.\n", .{});