diff --git a/src/client.zig b/src/client.zig index 218bce3..4e56e9c 100644 --- a/src/client.zig +++ b/src/client.zig @@ -22,10 +22,12 @@ pub const Client = struct { stream: *std.net.Stream, pub fn handshake(s: *Client) !void { - const magic = 0x42b33f00; + //const magic = 0x42b33f00; + + //try write.writeUInt(s.stream.writer(), magic); + //try write.writeUInt(s.stream.writer(), 0x80000002); + try s.stream.writer().writeAll(&[_]u8{0x42, 0xb3, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00}); - try write.writeUInt(s.stream.writer(), magic); - try write.writeUInt(s.stream.writer(), 0x80000002); var flags = try read.readByte(s.stream.reader()); var extra = try read.readShort(s.stream.reader()); var version = try read.readSignedByte(s.stream.reader()); @@ -38,6 +40,9 @@ pub const Client = struct { var map = std.StringHashMap(QVariantType).init(s.allocator); try map.put("MsgType", .{ .String = "ClientInit" }); + try map.put("UseCompression", .{ .UInt = 0 }); + try map.put("UseSSL", .{ .UInt = 0 }); + 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" }); diff --git a/src/main.zig b/src/main.zig index e26b36f..c702b60 100644 --- a/src/main.zig +++ b/src/main.zig @@ -7,12 +7,23 @@ const initClient = @import("./client.zig").initClient; pub fn main() !void { const allocator = std.heap.page_allocator; - var sock = try std.net.tcpConnectToHost(allocator, "127.0.0.1", 64242); + var argIter = std.process.args(); + _ = try argIter.next(allocator).?; + var host = try argIter.next(allocator).?; + var port = try argIter.next(allocator).?; + var portInt = try std.fmt.parseInt(u16, port, 10); + var username = try argIter.next(allocator).?; + var password = try argIter.next(allocator).?; + + std.debug.print("host={s} port={d}\n", .{host, portInt}); + + + var sock = try std.net.tcpConnectToHost(allocator, host, portInt); var client = initClient(allocator, &sock); try client.handshake(); try client.quassel_init_packet(); - try client.quassel_login("z", "password"); + try client.quassel_login(username, password); while (true) { try client.read_quassel_packet(); } diff --git a/src/qtshit/read.zig b/src/qtshit/read.zig index 9f25412..5ea027c 100644 --- a/src/qtshit/read.zig +++ b/src/qtshit/read.zig @@ -9,4 +9,4 @@ pub const readQVariantList = @import("./read/readQVariantList.zig").readQVariant pub const readQVariantT = @import("./read/readQVariantT.zig").readQVariantT; pub const readQVariant = @import("./read/readQVariant.zig").readQVariant; pub const readQVariantMap = @import("./read/readQVariantMap.zig").readQVariantMap; -pub const readQStringList = @import("./readQStringList.zig").readQStringList; \ No newline at end of file +pub const readQStringList = @import("./read/readQStringList.zig").readQStringList; \ No newline at end of file diff --git a/src/qtshit/read/readLong.zig b/src/qtshit/read/readLong.zig new file mode 100644 index 0000000..5830677 --- /dev/null +++ b/src/qtshit/read/readLong.zig @@ -0,0 +1,3 @@ +pub fn readLong(reader: anytype) !i64 { + return try reader.readIntBig(i64); +} diff --git a/src/qtshit/read/readQVariantT.zig b/src/qtshit/read/readQVariantT.zig index 1093576..83e2c0b 100644 --- a/src/qtshit/read/readQVariantT.zig +++ b/src/qtshit/read/readQVariantT.zig @@ -11,6 +11,7 @@ const readQVariantList = @import("./readQVariantList.zig").readQVariantList; const readQVariant = @import("./readQVariant.zig").readQVariant; const readQVariantMap = @import("./readQVariantMap.zig").readQVariantMap; const readQStringList = @import("./readQStringList.zig").readQStringList; +const readUserType = @import("./usertypes/readUserType.zig").readUserType; const QVariant = @import("../types/QVariant.zig").QVariant; const QVariantTypes = @import("../types/QVariantTypes.zig").QVariantTypes; @@ -54,9 +55,8 @@ pub fn readQVariantT(reader: anytype, type_id: u32, allocator: *std.mem.Allocato return QVariant{ .Short = short }; }, @enumToInt(QVariantTypes.UserType) => { - var userTypeName = readQByteArray(reader, allocator); - std.debug.print("name: {s}\n", .{userTypeName}); - @panic("TODO IMPLEMENT USERTYPES."); + var usertype = try readUserType(reader, allocator); + return QVariant{ .UserType = usertype }; }, else => { std.debug.print("Unknown Type ID: {d}\n", .{type_id}); diff --git a/src/qtshit/read/usertypes/readUserType.zig b/src/qtshit/read/usertypes/readUserType.zig new file mode 100644 index 0000000..b11b219 --- /dev/null +++ b/src/qtshit/read/usertypes/readUserType.zig @@ -0,0 +1,71 @@ +const std = @import("std"); +const UserType = @import("../../types/UserType.zig").UserType; +const UserTypeNames = @import("../../types/UserType.zig").UserTypeNames; +const readInt = @import("../readInt.zig").readInt; +const readShort = @import("../readShort.zig").readShort; +const readLong = @import("../readLong.zig").readLong; +const readQByteArray = @import("../readQByteArray.zig").readQByteArray; +const readQVariantMap = @import("../readQVariantMap.zig").readQVariantMap; + +pub fn readUserType(reader: anytype, allocator: *std.mem.Allocator) !UserType { + var userTypeName = try readQByteArray(reader, allocator); + userTypeName = userTypeName[0 .. userTypeName.len - 1]; + + if (std.mem.eql(u8, userTypeName, "BufferId")) { + return UserType{ + .BufferId = try readInt(reader), + }; + } else if (std.mem.eql(u8, userTypeName, "IdentityId")) { + return UserType{ + .IdentityId = try readInt(reader), + }; + } else if (std.mem.eql(u8, userTypeName, "NetworkId")) { + return UserType{ + .NetworkId = try readInt(reader), + }; + } else if (std.mem.eql(u8, userTypeName, "MsgId")) { + return UserType{ + .MsgId = try readInt(reader), + }; + } else if (std.mem.eql(u8, userTypeName, "PeerPtr")) { + return UserType{ + .PeerPtr = try readLong(reader), + }; + } else if (std.mem.eql(u8, userTypeName, "IrcUser")) { + return UserType{ + .IrcUser = try readQVariantMap(reader, allocator), + }; + } else if (std.mem.eql(u8, userTypeName, "IrcChannel")) { + return UserType{ + .IrcChannel = try readQVariantMap(reader, allocator), + }; + } else if (std.mem.eql(u8, userTypeName, "Identity")) { + return UserType{ + .Identity = try readQVariantMap(reader, allocator), + }; + } else if (std.mem.eql(u8, userTypeName, "NetworkInfo")) { + return UserType{ + .NetworkInfo = try readQVariantMap(reader, allocator), + }; + } else if (std.mem.eql(u8, userTypeName, "NetworkServer")) { + return UserType{ + .NetworkServer = try readQVariantMap(reader, allocator), + }; + } else if (std.mem.eql(u8, userTypeName, "BufferInfo")) { + return UserType{ + .BufferInfo = .{ + .ID = try readInt(reader), + .NetworkID = try readInt(reader), + .Type = try readShort(reader), + .Name = try readQByteArray(reader, allocator), + }, + }; + } else { + std.debug.print("Unknown UserType With Name: {s}\n", .{userTypeName}); + @panic("Unknown Usertype."); + } + + return UserType{ + .NetworkId = 1, + }; +} diff --git a/src/qtshit/test.zig b/src/qtshit/test.zig index ed346a2..32ec287 100644 --- a/src/qtshit/test.zig +++ b/src/qtshit/test.zig @@ -4,7 +4,8 @@ const global_allocator = std.testing.allocator; const read = @import("./read.zig"); const write = @import("./write.zig"); -const qvar = @import("./qvariant.zig"); +const QVariant = @import("./types/QVariant.zig").QVariant; +const freeQVariant = @import("./utils/freeQVariant.zig").freeQVariant; test "UInt serialization/deserialization" { var byteList = std.ArrayList(u8).init(global_allocator); @@ -122,7 +123,7 @@ test "QVariant QVariantMap serialization/deserialization" { var byteList = std.ArrayList(u8).init(global_allocator); defer byteList.deinit(); - var map = std.StringHashMap(qvar.QVariant).init(global_allocator); + var map = std.StringHashMap(QVariant).init(global_allocator); defer map.deinit(); try map.put("testkey", .{ .UInt = 1337 }); @@ -133,7 +134,7 @@ test "QVariant QVariantMap serialization/deserialization" { var fBS = std.io.fixedBufferStream(byteList.items); var varient = try read.readQVariant(fBS.reader(), global_allocator); - defer qvar.freeQVariant(varient, global_allocator); + defer freeQVariant(varient, global_allocator); var qVariantMap = varient.QVariantMap; diff --git a/src/qtshit/types/QVariant.zig b/src/qtshit/types/QVariant.zig index 655ec8c..be43e3b 100644 --- a/src/qtshit/types/QVariant.zig +++ b/src/qtshit/types/QVariant.zig @@ -1,6 +1,5 @@ const std = @import("std"); -const range = @import("./rangeiter.zig").range; -const UserTypes = @import("./UserTypes.zig").UserTypes; +const UserType = @import("./UserType.zig").UserType; pub const QVariant = union(enum) { Int: i32, @@ -12,5 +11,5 @@ pub const QVariant = union(enum) { QStringList: [][]const u8, QVariantList: []QVariant, QVariantMap: std.StringHashMap(QVariant), - UserType: UserTypes, + UserType: UserType, }; \ No newline at end of file diff --git a/src/qtshit/types/UserType.zig b/src/qtshit/types/UserType.zig new file mode 100644 index 0000000..b7e2b09 --- /dev/null +++ b/src/qtshit/types/UserType.zig @@ -0,0 +1,23 @@ +const std = @import("std"); +const QVariant = @import("./QVariant.zig").QVariant; + +pub const UserType = union(enum) { + BufferId: i32, + IdentityId: i32, + NetworkId: i32, + MsgId: i32, + PeerPtr: i64, + IrcUser: std.StringHashMap(QVariant), + IrcChannel: std.StringHashMap(QVariant), + Identity: std.StringHashMap(QVariant), + NetworkInfo: std.StringHashMap(QVariant), + NetworkServer: std.StringHashMap(QVariant), + BufferInfo: BufferInfo, +}; + +pub const BufferInfo = struct { + ID: i32, + NetworkID: i32, + Type: u16, + Name: []u8, +}; \ No newline at end of file diff --git a/src/qtshit/types/UserTypes.zig b/src/qtshit/types/UserTypes.zig deleted file mode 100644 index 77b72f9..0000000 --- a/src/qtshit/types/UserTypes.zig +++ /dev/null @@ -1,3 +0,0 @@ -pub const UserTypes = union(enum) { - NetworkId: i32, -}; diff --git a/src/qtshit/write.zig b/src/qtshit/write.zig index 4375a35..837c1de 100644 --- a/src/qtshit/write.zig +++ b/src/qtshit/write.zig @@ -3,6 +3,7 @@ pub const writeUInt = @import("./write/writeUInt.zig").writeUInt; pub const writeShort = @import("./write/writeShort.zig").writeShort; pub const writeByte = @import("./write/writeByte.zig").writeByte; pub const writeSignedByte = @import("./write/writeSignedByte.zig").writeSignedByte; +pub const writeQStringList = @import("./write/writeQStringList.zig").writeQStringList; pub const writeQByteArray = @import("./write/writeQByteArray.zig").writeQByteArray; pub const writeString = @import("./write/writeString.zig").writeString; pub const writeQVariantList = @import("./write/writeQVariantList.zig").writeQVariantList;