Work on add to NetworkManager

This commit is contained in:
Z 2021-06-13 16:03:53 +01:00
parent c5ee112799
commit 7fa61df9fe
6 changed files with 245 additions and 19 deletions

91
src/NetworkManager.zig Normal file
View file

@ -0,0 +1,91 @@
const std = @import("std");
const log = std.log.scoped(.NetworkManager);
const QVariant = @import("./qtshit/types/QVariant.zig").QVariant;
const BufferInfo = @import("./qtshit/types/UserType.zig").BufferInfo;
pub const NetworkInfo = struct {
networkID: i32,
pub fn new(networkID: i32) NetworkInfo {
return .{ .networkID = networkID };
}
};
pub const Network = struct {
allocator: *std.mem.Allocator,
myNick: []const u8,
buffers: std.AutoHashMap(i32, BufferInfo),
networkInfo: NetworkInfo,
pub fn new(allocator: *std.mem.Allocator, networkID: i32) Network {
return .{
.allocator = allocator,
.networkInfo = NetworkInfo.new(networkID),
.myNick = "",
.buffers = std.AutoHashMap(i32, BufferInfo).init(allocator),
};
}
pub fn addBuffer(s: *Network, info: BufferInfo) !void {
try s.buffers.put(info.NetworkID, BufferInfo{
.ID = info.ID,
.NetworkID = info.NetworkID,
.Type = info.Type,
.Name = try s.allocator.dupe(u8, info.Name),
});
}
pub fn handle_init_packet(s: *Network, data: std.StringHashMap(QVariant)) !void {
var itr = data.keyIterator();
while (itr.next()) |key_ptr| {
log.info("nm: data key {s}", .{
key_ptr.*,
});
}
if (data.get("myNick")) |myNick| {
log.info("myNick {s}", .{myNick.String});
s.myNick = try s.allocator.dupe(u8, myNick.String);
}
}
pub fn deinit(s: *Network) void {
var buffersIter = s.buffers.iterator();
while (buffersIter.next()) |bufInfo| {
s.allocator.free(bufInfo.value_ptr.*.Name);
}
s.buffers.deinit();
s.allocator.free(s.myNick);
}
};
pub const NetworkManager = struct {
allocator: *std.mem.Allocator,
networks: std.AutoHashMap(i32, Network),
pub fn deinit(s: *NetworkManager) void {
var iter = s.networks.iterator();
while (iter.next()) |network| {
network.value_ptr.deinit();
}
s.networks.deinit();
}
pub fn get(s: *NetworkManager, networkID: i32) !?Network {
return s.networks.get(networkID);
}
pub fn add(s: *NetworkManager, networkID: i32) !void {
try s.networks.put(
networkID,
Network.new(s.allocator, networkID),
);
}
};
pub fn initNetworkManager(allocator: *std.mem.Allocator) NetworkManager {
return NetworkManager{
.allocator = allocator,
.networks = std.AutoHashMap(i32, Network).init(allocator),
};
}

View file

@ -1,7 +1,7 @@
const std = @import("std");
const BufferManager = @import("./BufferManager.zig");
const SocketManager = @import("./SocketManager.zig");
const NetworkManager = @import("./NetworkManager.zig");
const read = @import("./qtshit/read.zig");
const write = @import("./qtshit/write.zig");
@ -11,6 +11,8 @@ const QDateTime = @import("./qtshit/types/QVariant.zig").QDateTime;
const UserType = @import("./qtshit/types/UserType.zig");
const RequestType = @import("./types/RequestType.zig").RequestType;
const QVariantListToQVariantMap = @import("./qtshit/utils/QVariantListToQVariantMap.zig").QVariantListToQVariantMap;
const prettyPrintQVariant = @import("./qtshit/utils/prettyPrintQVariant.zig").prettyPrintQVariant;
const freeQVariant = @import("./qtshit/utils/free/freeQVariant.zig").freeQVariant;
@ -30,11 +32,11 @@ pub const Client = struct {
allocator: *std.mem.Allocator,
stream: *std.net.Stream,
socketManager: SocketManager.SocketManager,
bufferManager: BufferManager.BufferManager,
networkManager: NetworkManager.NetworkManager,
pub fn deinit(s: *Client) void {
s.bufferManager.deinit();
s.socketManager.deinit();
s.networkManager.deinit();
}
pub fn handshake(s: *Client) !void {
@ -145,16 +147,87 @@ pub const Client = struct {
try s.socketManager.writeFrame(data);
}
fn send_init_request(s: *Client, className: []const u8, objectName: ?[]const u8) !void {
var data = std.ArrayList(u8).init(s.allocator);
defer data.deinit();
var listItems = std.ArrayList(QVariant).init(s.allocator);
defer listItems.deinit();
try listItems.append(.{ .Int = @enumToInt(RequestType.InitRequest) });
try listItems.append(.{ .String = className });
if (objectName) |objName| {
try listItems.append(.{ .String = objName });
} else {
try listItems.append(.{ .String = "" });
}
try write.writeQVariant(data.writer(), s.allocator, .{
.QVariantList = listItems.items,
});
try s.socketManager.writeFrame(data);
}
fn handle_session_init_packet(s: *Client, sessionState: std.StringHashMap(QVariant)) !void {
for (sessionState.get("NetworkIds").?.QVariantList) |qvar| {
var networkID = qvar.UserType.NetworkId;
try s.networkManager.add(networkID);
var networkIDStr = try std.fmt.allocPrint(
s.allocator,
"{d}",
.{networkID},
);
defer s.allocator.free(networkIDStr);
try s.send_init_request("Network", networkIDStr);
}
for (sessionState.get("BufferInfos").?.QVariantList) |qvar| {
try s.bufferManager.addBufferInfo(qvar.UserType.BufferInfo);
var bufInfo = qvar.UserType.BufferInfo;
var network = try s.networkManager.get(bufInfo.NetworkID);
try network.?.addBuffer(bufInfo);
}
}
pub fn handle_struct_init_data(
s: *Client,
className: []const u8,
id: i32,
data: std.StringHashMap(QVariant),
) !void {
if (std.mem.eql(u8, className, "Network")) {
var network = try s.networkManager.get(id);
try network.?.handle_init_packet(data);
}
// Do Things
//prettyPrintQVariant(.{ .QVariantMap = data }, 0);
}
pub fn handle_struct(s: *Client, list: []QVariant) !void {
var reqType = @intToEnum(RequestType, list[0].Int);
switch (reqType) {
.InitData => {
var className = list[1].QByteArray;
var id = list[2].String;
var idInt = try std.fmt.parseInt(i32, id, 10);
var mapData = list[3].QVariantMap;
try s.handle_struct_init_data(className, idInt, mapData);
},
.HeartBeat => {
try s.reply_to_heartbeat(list[1].QDateTime);
return;
},
else => {
prettyPrintQVariant(.{ .QVariantList = list }, 0);
},
}
}
pub fn read_quassel_packet(s: *Client) !void {
var variant = try s.socketManager.readFrame();
defer freeQVariant(variant, s.allocator);
switch (variant) {
.QVariantMap => |map| {
if (map.get("MsgType")) |msgType| {
@ -166,21 +239,22 @@ pub const Client = struct {
}
},
.QVariantList => |list| {
switch (@intToEnum(RequestType, list[0].Int)) {
.HeartBeat => {
try s.reply_to_heartbeat(list[1].QDateTime);
try s.handle_struct(list);
return;
},
else => {},
}
},
else => {},
}
std.debug.print("\n\n Unknown: Quassel Packet: \n", .{});
prettyPrintQVariant(variant, 0);
std.debug.print("\n\n Unknown: Quassel Packet: \n", .{});
}
};
pub fn initClient(allocator: *std.mem.Allocator, stream: *std.net.Stream) Client {
return Client{ .allocator = allocator, .stream = stream, .bufferManager = BufferManager.initBufferManager(allocator), .socketManager = SocketManager.initSocketManager(allocator, stream) };
return Client{
.allocator = allocator,
.stream = stream,
.socketManager = SocketManager.initSocketManager(allocator, stream),
.networkManager = NetworkManager.initNetworkManager(allocator),
};
}

View file

@ -4,7 +4,7 @@ const DebugAllocator = @import("./debug_allocator.zig");
const write = @import("./qtshit/write.zig");
const initClient = @import("./client.zig").initClient;
pub const log_level: std.log.Level = .warn;
pub const log_level: std.log.Level = .info;
pub fn realMain(allocator: *std.mem.Allocator) !void {
var argIter = std.process.args();
@ -32,11 +32,18 @@ pub fn realMain(allocator: *std.mem.Allocator) !void {
try client.quassel_init_packet();
try client.quassel_login(username, password);
_ = try client.read_quassel_packet();
//var network = try client.networkManager.get(2);
//std.debug.print("\n\n {any} \n\n", .{network.?});
//var bufferInfo = try client.bufferManager.getFirstByName("z_is_stimky");
//try client.send_message(bufferInfo.?, "uwu, owo, uwu");
var i: i64 = 0;
while (true) {
std.time.sleep(100 * std.time.ns_per_ms);
while (i < 10) {
i = i + 1;
//std.time.sleep(100 * std.time.ns_per_ms);
client.read_quassel_packet() catch |err| {
if (err == error.DecodeError) {
@ -50,6 +57,9 @@ pub fn realMain(allocator: *std.mem.Allocator) !void {
}
};
}
var network = try client.networkManager.get(1);
std.debug.print("network 1 is using nickname: {s} \n", .{network.?.myNick});
}
pub fn main() !void {
@ -60,5 +70,5 @@ pub fn main() !void {
const alloc = &gpalloc.allocator;
try realMain(alloc);
try realMain(std.heap.page_allocator);
}

View file

@ -52,7 +52,7 @@ pub fn readUserType(reader: anytype, allocator: *std.mem.Allocator) !UserType {
return UserType{
.NetworkInfo = try readQVariantMap(reader, allocator),
};
} else if (std.mem.eql(u8, userTypeName, "NetworkServer")) {
} else if (std.mem.eql(u8, userTypeName, "Network::Server")) {
return UserType{
.NetworkServer = try readQVariantMap(reader, allocator),
};

View file

@ -0,0 +1,50 @@
const std = @import("std");
const QVariant = @import("../types/QVariant.zig").QVariant;
const range = @import("./RangeIter.zig").range;
const freeQVariantMap = @import("./free/freeQVariantMap.zig").freeQVariantMap;
pub fn QVariantListToQVariantMap(varList: []QVariant, allocator: *std.mem.Allocator) !std.StringHashMap(QVariant) {
var varMap = std.StringHashMap(QVariant).init(allocator);
errdefer varMap.deinit();
if (varList.len % 2 != 0) {
return error.NotDivByTwo;
}
var iter = range(u32, 0, @intCast(u32, @divExact(varList.len, 2)));
while (iter.next()) |i| {
if (i % 2 == 1) continue;
try varMap.put(
varList[i].String,
varList[i + 1],
);
}
return varMap;
}
test "QVariantList -> QVariantMap" {
// These will get free'd by freeQVariantMap
var owoString = try std.testing.allocator.dupe(u8, "owo");
var varList = [_]QVariant{
.{.String = owoString},
.{.Int = 1337},
};
var map = try QVariantListToQVariantMap(varList[0..], std.testing.allocator);
defer freeQVariantMap(map, std.testing.allocator);
var owo = map.get("owo");
try std.testing.expect(owo.?.Int == 1337);
}
test "QVariantList not div by 2" {
var varList = [_]QVariant{
.{.String = "uwu"},
};
var res = QVariantListToQVariantMap(varList[0..], std.testing.allocator);
try std.testing.expectError(error.NotDivByTwo, res);
}

View file

@ -1,5 +1,6 @@
const unicode = @import("./unicode.zig");
const QVariantMapToQVariantList = @import("./QVariantMapToQVariantList.zig");
const QVariantListToQVariantMap = @import("./QVariantListToQVariantMap.zig");
comptime {
@import("std").testing.refAllDecls(@This());