Add message parsing.

This commit is contained in:
Kitteh 2021-06-03 15:19:59 +01:00
parent 4afff73397
commit 4d36de6c5d
8 changed files with 132 additions and 28 deletions

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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,
};
}

View file

@ -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),
};
}

View file

@ -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.");
}

View file

@ -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,
};

View file

@ -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);
}
}
},
}

View file

@ -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", .{});