aaaaa
This commit is contained in:
parent
85c6f583e5
commit
86e7fb6a57
57
src/client.zig
Normal file
57
src/client.zig
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const read = @import("./qtshit/read.zig");
|
||||||
|
const write = @import("./qtshit/write.zig");
|
||||||
|
const qvar = @import("./qtshit/qvariant.zig");
|
||||||
|
|
||||||
|
pub const Client = struct {
|
||||||
|
allocator: *std.mem.Allocator,
|
||||||
|
stream: *std.net.Stream,
|
||||||
|
|
||||||
|
pub fn handshake(s: *Client) !void {
|
||||||
|
const magic = 0x42b33f00;
|
||||||
|
|
||||||
|
try write.add_int(s.stream.writer(), magic);
|
||||||
|
try write.add_int(s.stream.writer(), 2);
|
||||||
|
try write.add_int(s.stream.writer(), 1 << 31);
|
||||||
|
var resp = try read.get_int(s.stream.reader());
|
||||||
|
if ((resp & 0xff) != 1) {
|
||||||
|
@panic("No support 4 legacy protocol.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((resp >> 24) & 1) != 0) {
|
||||||
|
@panic("No support 4 ssl protocol.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((resp >> 24) & 2) != 0) {
|
||||||
|
@panic("No support 4 compression.");
|
||||||
|
}
|
||||||
|
std.debug.print("handshake Success!\n", .{});
|
||||||
|
}
|
||||||
|
pub fn quassel_init_packet(s: *Client) !void {
|
||||||
|
var map = std.StringHashMap(qvar.QVariant).init(s.allocator);
|
||||||
|
try map.put("UseSSL", .{ .byte = 0 });
|
||||||
|
try map.put("UseCompression", .{ .byte = 0 });
|
||||||
|
try map.put("ProtocolVersion", .{ .int = 10 });
|
||||||
|
try map.put("MsgType", .{ .string = "ClientInit" });
|
||||||
|
try map.put("ClientVersion", .{ .string = "0.1 (quasselclient)" });
|
||||||
|
try map.put("ClientDate", .{ .string = "0" });
|
||||||
|
|
||||||
|
try write.add_qvariantmap(s.stream.writer(), map);
|
||||||
|
}
|
||||||
|
pub fn quassel_login(s: *Client) !void {
|
||||||
|
var map = std.StringHashMap(qvar.QVariant).init(s.allocator);
|
||||||
|
|
||||||
|
try map.put("MsgType", .{ .string = "ClientLogin" });
|
||||||
|
try map.put("User", .{ .string = "z" });
|
||||||
|
try map.put("Password", .{ .string = "password" });
|
||||||
|
|
||||||
|
try write.add_qvariantmap(s.stream.writer(), map);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn initClient(allocator: *std.mem.Allocator, stream: *std.net.Stream) Client {
|
||||||
|
return Client{
|
||||||
|
.allocator = allocator,
|
||||||
|
.stream = stream,
|
||||||
|
};
|
||||||
|
}
|
12
src/main.zig
12
src/main.zig
|
@ -3,7 +3,15 @@ const std = @import("std");
|
||||||
const read = @import("./qtshit/read.zig");
|
const read = @import("./qtshit/read.zig");
|
||||||
const write = @import("./qtshit/write.zig");
|
const write = @import("./qtshit/write.zig");
|
||||||
|
|
||||||
|
const initClient = @import("./client.zig").initClient;
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const allocator = std.heap.page_allocator;
|
||||||
try stdout.print("Hello, {s}!\n", .{"world"});
|
var sock = try std.net.tcpConnectToHost(allocator, "127.0.0.1", 64242);
|
||||||
|
|
||||||
|
var client = initClient(allocator, &sock);
|
||||||
|
try client.handshake();
|
||||||
|
try client.quassel_init_packet();
|
||||||
|
try client.quassel_login();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub const QVariant = union {
|
pub const QVariant = union(enum) {
|
||||||
int: u32,
|
int: u32,
|
||||||
short: u16,
|
short: u16,
|
||||||
byte: u8,
|
byte: u8,
|
||||||
bytearray: std.ArrayList(u8),
|
bytearray: std.ArrayList(u8),
|
||||||
string: []u8,
|
string: []const u8,
|
||||||
stringlist: std.ArrayList([]const u8),
|
stringlist: std.ArrayList([]const u8),
|
||||||
empty: bool,
|
empty: bool,
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,60 @@ pub const QVariantTypes = enum(u32) {
|
||||||
// IDK why there is 2???
|
// IDK why there is 2???
|
||||||
int_1 = 2,
|
int_1 = 2,
|
||||||
int_2 = 3,
|
int_2 = 3,
|
||||||
|
qmap = 8,
|
||||||
string = 10,
|
string = 10,
|
||||||
stringlist = 11,
|
stringlist = 11,
|
||||||
bytearray = 12,
|
bytearray = 12,
|
||||||
short = 133,
|
short = 133,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn qvariant_type_id(variant: QVariant) !u32 {
|
||||||
|
switch (variant) {
|
||||||
|
.byte => {
|
||||||
|
return @enumToInt(QVariantTypes.byte);
|
||||||
|
},
|
||||||
|
.int_1, .int_2 => {
|
||||||
|
return @enumToInt(QVariantTypes.int_1);
|
||||||
|
},
|
||||||
|
.qmap => {
|
||||||
|
return @enumToInt(QVariantTypes.qmap);
|
||||||
|
},
|
||||||
|
.string => {
|
||||||
|
return @enumToInt(QVariantTypes.string);
|
||||||
|
},
|
||||||
|
.stringlist => {
|
||||||
|
return @enumToInt(QVariantTypes.stringlist);
|
||||||
|
},
|
||||||
|
.bytearray => {
|
||||||
|
return @enumToInt(QVariantTypes.bytearray);
|
||||||
|
},
|
||||||
|
.short => {
|
||||||
|
return @enumToInt(QVariantTypes.short);
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn qvariant_size(variant: QVariant) !u32 {
|
||||||
|
var size: u32 = 0;
|
||||||
|
|
||||||
|
switch (variant) {
|
||||||
|
.int => {
|
||||||
|
size += 4;
|
||||||
|
},
|
||||||
|
.byte => {
|
||||||
|
size += 1;
|
||||||
|
},
|
||||||
|
.string => |*str| {
|
||||||
|
size += @intCast(u32, str.len);
|
||||||
|
// Null Terminator
|
||||||
|
size += 1;
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
size += 0;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ pub fn get_bytearray(reader: anytype, allocator: *std.mem.Allocator) !std.ArrayL
|
||||||
var byteList = std.ArrayList(u8).init(allocator);
|
var byteList = std.ArrayList(u8).init(allocator);
|
||||||
var length = try get_int(reader);
|
var length = try get_int(reader);
|
||||||
|
|
||||||
|
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (index == length) return byteList;
|
if (index == length) return byteList;
|
||||||
|
|
|
@ -108,7 +108,7 @@ test "read/write byte variant" {
|
||||||
var byteList = std.ArrayList(u8).init(global_allocator);
|
var byteList = std.ArrayList(u8).init(global_allocator);
|
||||||
defer byteList.deinit();
|
defer byteList.deinit();
|
||||||
|
|
||||||
try write.add_qvariant(byteList.writer(), @enumToInt(qvar.QVariantTypes.byte));
|
try write.add_qvariant_with_id(byteList.writer(), @enumToInt(qvar.QVariantTypes.byte));
|
||||||
try write.add_byte(byteList.writer(), 'a');
|
try write.add_byte(byteList.writer(), 'a');
|
||||||
|
|
||||||
var fBS = std.io.fixedBufferStream(byteList.items);
|
var fBS = std.io.fixedBufferStream(byteList.items);
|
||||||
|
@ -121,7 +121,7 @@ test "read/write int variant" {
|
||||||
var byteList = std.ArrayList(u8).init(global_allocator);
|
var byteList = std.ArrayList(u8).init(global_allocator);
|
||||||
defer byteList.deinit();
|
defer byteList.deinit();
|
||||||
|
|
||||||
try write.add_qvariant(byteList.writer(), @enumToInt(qvar.QVariantTypes.int_2));
|
try write.add_qvariant_with_id(byteList.writer(), @enumToInt(qvar.QVariantTypes.int_2));
|
||||||
try write.add_int(byteList.writer(), 1312);
|
try write.add_int(byteList.writer(), 1312);
|
||||||
|
|
||||||
var fBS = std.io.fixedBufferStream(byteList.items);
|
var fBS = std.io.fixedBufferStream(byteList.items);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const qvar = @import("./qvariant.zig");
|
||||||
|
|
||||||
pub fn add_int(writer: anytype, number: u32) !void {
|
pub fn add_int(writer: anytype, number: u32) !void {
|
||||||
try writer.writeIntBig(u32, number);
|
try writer.writeIntBig(u32, number);
|
||||||
|
@ -29,9 +30,65 @@ pub fn add_stringlist(writer: anytype, strList: std.ArrayList([]const u8)) !void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Call this and Then write your type
|
// Call this and Then write your type
|
||||||
pub fn add_qvariant(writer: anytype, type_id: u32) !void {
|
pub fn add_qvariant_with_id(writer: anytype, type_id: u32) !void {
|
||||||
try add_int(writer, type_id);
|
try add_int(writer, type_id);
|
||||||
try add_byte(writer, 0);
|
try add_byte(writer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_qvariant(writer: anytype, variant: qvar.QVariant) !void {
|
||||||
|
add_qvariant_with_id(writer, qvar.qvariant_type_id(variant));
|
||||||
|
switch (variant) {
|
||||||
|
.byte => |*out| {
|
||||||
|
return add_byte(writer, out);
|
||||||
|
},
|
||||||
|
.int_1, .int_2 => |*out| {
|
||||||
|
return add_int(writer, out);
|
||||||
|
},
|
||||||
|
.qmap => |*out| {
|
||||||
|
return add_qvariantmap(writer, out);
|
||||||
|
},
|
||||||
|
.string => |*out| {
|
||||||
|
return add_string(writer, out);
|
||||||
|
},
|
||||||
|
.stringlist => |*out| {
|
||||||
|
return add_stringlist(writer, out);
|
||||||
|
},
|
||||||
|
.bytearray => |*out| {
|
||||||
|
return add_bytearray(writer, out);
|
||||||
|
},
|
||||||
|
.short => |*out| {
|
||||||
|
return add_short(writer, out);
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_qvariantmap(writer: anytype, map: std.StringHashMap(qvar.QVariant)) !void {
|
||||||
|
var size: u32 = 0;
|
||||||
|
|
||||||
|
var iterator = map.iterator();
|
||||||
|
|
||||||
|
while (iterator.next()) |entry| {
|
||||||
|
size += try qvar.qvariant_size(.{ .string = entry.key });
|
||||||
|
size += try qvar.qvariant_size(entry.value);
|
||||||
|
size += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
try add_int(writer, size + 4 + 1 + 4);
|
||||||
|
try add_int(writer, 8);
|
||||||
|
try add_byte(writer, 1);
|
||||||
|
try add_int(writer, map.count());
|
||||||
|
|
||||||
|
while (iterator.next()) |entry| {
|
||||||
|
size += try qvar.qvariant_size(.{ .string = entry.key });
|
||||||
|
size += try qvar.qvariant_size(entry.value);
|
||||||
|
size += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.print("Size {d} !\n", .{size});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue