Compare commits

..

5 commits

Author SHA1 Message Date
63fc7a5888 GetMultiPathAvatarInfo handler 2024-06-27 14:12:33 +03:00
195d76a92c Fix typo 2024-06-26 19:38:46 +03:00
e8b50bf352 Better logging
Define default log level (debug for debug builds, info for everything else)
Use log scopes
2024-06-26 19:37:19 +03:00
c66d8726ed Use allocator per session thread 2024-06-26 18:26:24 +03:00
e7e140f341 Fix PlayerHeartBeatScRsp timestamp 2024-06-26 14:30:01 +03:00
9 changed files with 62 additions and 28 deletions

View file

@ -1,10 +1,18 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin");
const httpz = @import("httpz"); const httpz = @import("httpz");
const protocol = @import("protocol"); const protocol = @import("protocol");
const authentication = @import("authentication.zig"); const authentication = @import("authentication.zig");
const dispatch = @import("dispatch.zig"); const dispatch = @import("dispatch.zig");
pub const std_options = .{
.log_level = switch (builtin.mode) {
.Debug => .debug,
else => .info,
},
};
pub fn main() !void { pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){}; var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator(); const allocator = gpa.allocator();

View file

@ -9,6 +9,7 @@ const Stream = std.net.Stream;
const Address = std.net.Address; const Address = std.net.Address;
const Self = @This(); const Self = @This();
const log = std.log.scoped(.session);
address: Address, address: Address,
stream: Stream, stream: Stream,
@ -42,7 +43,6 @@ pub fn send(self: *Self, cmd_id: protocol.CmdID, proto: anytype) !void {
defer self.allocator.free(packet); defer self.allocator.free(packet);
_ = try self.stream.write(packet); _ = try self.stream.write(packet);
std.log.debug("sent packet with id {}", .{cmd_id});
} }
pub fn send_empty(self: *Self, cmd_id: protocol.CmdID) !void { pub fn send_empty(self: *Self, cmd_id: protocol.CmdID) !void {
@ -50,5 +50,5 @@ pub fn send_empty(self: *Self, cmd_id: protocol.CmdID) !void {
defer self.allocator.free(packet); defer self.allocator.free(packet);
_ = try self.stream.write(packet); _ = try self.stream.write(packet);
std.log.debug("sent EMPTY packet with id {}", .{cmd_id}); log.debug("sent EMPTY packet with id {}", .{cmd_id});
} }

View file

@ -14,12 +14,15 @@ const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator; const ArenaAllocator = std.heap.ArenaAllocator;
const CmdID = protocol.CmdID; const CmdID = protocol.CmdID;
const log = std.log.scoped(.handlers);
const Action = *const fn (*Session, *const Packet, Allocator) anyerror!void; const Action = *const fn (*Session, *const Packet, Allocator) anyerror!void;
const HandlerList = [_]struct { CmdID, Action }{ const HandlerList = [_]struct { CmdID, Action }{
.{ CmdID.CmdPlayerGetTokenCsReq, login.onPlayerGetToken }, .{ CmdID.CmdPlayerGetTokenCsReq, login.onPlayerGetToken },
.{ CmdID.CmdPlayerLoginCsReq, login.onPlayerLogin }, .{ CmdID.CmdPlayerLoginCsReq, login.onPlayerLogin },
.{ CmdID.CmdPlayerHeartBeatCsReq, misc.onPlayerHeartBeat }, .{ CmdID.CmdPlayerHeartBeatCsReq, misc.onPlayerHeartBeat },
.{ CmdID.CmdGetAvatarDataCsReq, avatar.onGetAvatarData }, .{ CmdID.CmdGetAvatarDataCsReq, avatar.onGetAvatarData },
.{ CmdID.CmdGetMultiPathAvatarInfoCsReq, avatar.onGetMultiPathAvatarInfo },
.{ CmdID.CmdGetMissionStatusCsReq, mission.onGetMissionStatus }, .{ CmdID.CmdGetMissionStatusCsReq, mission.onGetMissionStatus },
.{ CmdID.CmdGetCurLineupDataCsReq, lineup.onGetCurLineupData }, .{ CmdID.CmdGetCurLineupDataCsReq, lineup.onGetCurLineupData },
.{ CmdID.CmdGetCurSceneInfoCsReq, scene.onGetCurSceneInfo }, .{ CmdID.CmdGetCurSceneInfoCsReq, scene.onGetCurSceneInfo },
@ -68,6 +71,8 @@ const DummyCmdList = [_]struct { CmdID, CmdID }{
.{ CmdID.CmdGetMainMissionCustomValueCsReq, CmdID.CmdGetMainMissionCustomValueScRsp }, .{ CmdID.CmdGetMainMissionCustomValueCsReq, CmdID.CmdGetMainMissionCustomValueScRsp },
}; };
const SuppressLogList = [_]CmdID{CmdID.CmdSceneEntityMoveCsReq};
pub fn handle(session: *Session, packet: *const Packet) !void { pub fn handle(session: *Session, packet: *const Packet) !void {
var arena = ArenaAllocator.init(session.allocator); var arena = ArenaAllocator.init(session.allocator);
defer arena.deinit(); defer arena.deinit();
@ -77,7 +82,9 @@ pub fn handle(session: *Session, packet: *const Packet) !void {
inline for (HandlerList) |handler| { inline for (HandlerList) |handler| {
if (handler[0] == cmd_id) { if (handler[0] == cmd_id) {
try handler[1](session, packet, arena.allocator()); try handler[1](session, packet, arena.allocator());
std.log.debug("packet {} was handled", .{cmd_id}); if (!std.mem.containsAtLeast(CmdID, &SuppressLogList, 1, &[_]CmdID{cmd_id})) {
log.debug("packet {} was handled", .{cmd_id});
}
return; return;
} }
} }
@ -89,5 +96,5 @@ pub fn handle(session: *Session, packet: *const Packet) !void {
} }
} }
std.log.warn("packet {} was ignored", .{cmd_id}); log.warn("packet {} was ignored", .{cmd_id});
} }

View file

@ -1,10 +1,15 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin");
const network = @import("network.zig"); const network = @import("network.zig");
const handlers = @import("handlers.zig"); const handlers = @import("handlers.zig");
pub fn main() !void { pub const std_options = .{
var gpa = std.heap.GeneralPurposeAllocator(.{}){}; .log_level = switch (builtin.mode) {
const allocator = gpa.allocator(); .Debug => .debug,
else => .info,
},
};
try network.listen(allocator); pub fn main() !void {
try network.listen();
} }

View file

@ -2,7 +2,7 @@ const std = @import("std");
const Session = @import("Session.zig"); const Session = @import("Session.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
pub fn listen(allocator: Allocator) !void { pub fn listen() !void {
const addr = std.net.Address.parseIp4("0.0.0.0", 23301) catch unreachable; const addr = std.net.Address.parseIp4("0.0.0.0", 23301) catch unreachable;
var listener = try addr.listen(.{ var listener = try addr.listen(.{
.kernel_backlog = 100, .kernel_backlog = 100,
@ -15,22 +15,27 @@ pub fn listen(allocator: Allocator) !void {
const conn = listener.accept() catch continue; const conn = listener.accept() catch continue;
errdefer conn.stream.close(); errdefer conn.stream.close();
const session = try allocator.create(Session); const thread = try std.Thread.spawn(.{}, runSession, .{ conn.address, conn.stream });
session.* = Session.init(conn.address, conn.stream, allocator);
const thread = try std.Thread.spawn(.{}, runSession, .{session});
thread.detach(); thread.detach();
} }
} }
fn runSession(s: *Session) void { fn runSession(address: std.net.Address, stream: std.net.Stream) !void {
std.log.info("new connection from {}", .{s.address}); std.log.info("new connection from {}", .{address});
if (s.run()) |_| { var gpa = std.heap.GeneralPurposeAllocator(.{}){};
std.log.info("client from {} disconnected", .{s.address}); defer if (gpa.deinit() == .leak) std.log.err("memory leaks were detected for session at {}", .{address});
const allocator = gpa.allocator();
const session = try allocator.create(Session);
session.* = Session.init(address, stream, allocator);
if (session.*.run()) |_| {
std.log.info("client from {} disconnected", .{address});
} else |err| { } else |err| {
std.log.err("session disconnected with an error: {}", .{err}); std.log.err("session disconnected with an error: {}", .{err});
} }
s.allocator.destroy(s); allocator.destroy(session);
} }

View file

@ -29,3 +29,10 @@ pub fn onGetAvatarData(session: *Session, packet: *const Packet, allocator: Allo
try session.send(CmdID.CmdGetAvatarDataScRsp, rsp); try session.send(CmdID.CmdGetAvatarDataScRsp, rsp);
} }
pub fn onGetMultiPathAvatarInfo(session: *Session, _: *const Packet, allocator: Allocator) !void {
var rsp = protocol.GetMultiPathAvatarInfoScRsp.init(allocator);
try rsp.cur_multi_path_avatar_type_map.append(.{ .key = 1001, .value = .Mar_7thRogueType });
try session.send(CmdID.CmdGetMultiPathAvatarInfoScRsp, rsp);
}

View file

@ -18,7 +18,7 @@ pub fn onPlayerHeartBeat(session: *Session, packet: *const Packet, allocator: Al
const rsp = protocol.PlayerHeartBeatScRsp{ const rsp = protocol.PlayerHeartBeatScRsp{
.retcode = 0, .retcode = 0,
.client_time_ms = req.client_time_ms, .client_time_ms = req.client_time_ms,
.server_time_ms = @intCast(std.time.timestamp()), .server_time_ms = @intCast(std.time.milliTimestamp()),
.download_data = data, .download_data = data,
}; };

View file

@ -5,6 +5,8 @@ const Session = @import("../Session.zig");
const Packet = @import("../Packet.zig"); const Packet = @import("../Packet.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const log = std.log.scoped(.scene_service);
pub fn onGetCurSceneInfo(session: *Session, _: *const Packet, allocator: Allocator) !void { pub fn onGetCurSceneInfo(session: *Session, _: *const Packet, allocator: Allocator) !void {
var scene_info = protocol.SceneInfo.init(allocator); var scene_info = protocol.SceneInfo.init(allocator);
scene_info.game_mode_type = 1; scene_info.game_mode_type = 1;
@ -64,7 +66,7 @@ pub fn onSceneEntityMove(session: *Session, packet: *const Packet, allocator: Al
for (req.entity_motion_list.items) |entity_motion| { for (req.entity_motion_list.items) |entity_motion| {
if (entity_motion.motion) |motion| { if (entity_motion.motion) |motion| {
std.log.debug("[POSITION] entity_id: {}, motion: {}", .{ entity_motion.entity_id, motion }); log.debug("[POSITION] entity_id: {}, motion: {}", .{ entity_motion.entity_id, motion });
} }
} }

View file

@ -22767,7 +22767,7 @@ pub const JDKHDANPJEA = struct {
pub usingnamespace protobuf.MessageMixins(@This()); pub usingnamespace protobuf.MessageMixins(@This());
}; };
pub const PDLCDMEPDDJ = struct { pub const MultiPathAvatarInfo = struct {
KBEJIBADOKJ: u32 = 0, KBEJIBADOKJ: u32 = 0,
avatar_id: MultiPathAvatarType = @enumFromInt(0), avatar_id: MultiPathAvatarType = @enumFromInt(0),
FKDENBOKHPO: ArrayList(AvatarSkillTree), FKDENBOKHPO: ArrayList(AvatarSkillTree),
@ -22819,18 +22819,18 @@ pub const GetMultiPathAvatarInfoCsReq = struct {
pub const GetMultiPathAvatarInfoScRsp = struct { pub const GetMultiPathAvatarInfoScRsp = struct {
retcode: u32 = 0, retcode: u32 = 0,
HKNADMABCGG: ArrayList(PDLCDMEPDDJ), multi_path_avatar_info_list: ArrayList(MultiPathAvatarInfo),
FIFIBNJEIGL: ArrayList(FIFIBNJEIGLEntry), cur_multi_path_avatar_type_map: ArrayList(CurMultiPathAvatarTypeMapEntry),
GMHDHIMDKFI: ArrayList(u32), GMHDHIMDKFI: ArrayList(u32),
pub const _desc_table = .{ pub const _desc_table = .{
.retcode = fd(7, .{ .Varint = .Simple }), .retcode = fd(7, .{ .Varint = .Simple }),
.HKNADMABCGG = fd(13, .{ .List = .{ .SubMessage = {} } }), .multi_path_avatar_info_list = fd(13, .{ .List = .{ .SubMessage = {} } }),
.FIFIBNJEIGL = fd(4, .{ .List = .{ .SubMessage = {} } }), .cur_multi_path_avatar_type_map = fd(4, .{ .List = .{ .SubMessage = {} } }),
.GMHDHIMDKFI = fd(15, .{ .PackedList = .{ .Varint = .Simple } }), .GMHDHIMDKFI = fd(15, .{ .PackedList = .{ .Varint = .Simple } }),
}; };
pub const FIFIBNJEIGLEntry = struct { pub const CurMultiPathAvatarTypeMapEntry = struct {
key: u32 = 0, key: u32 = 0,
value: MultiPathAvatarType = @enumFromInt(0), value: MultiPathAvatarType = @enumFromInt(0),
@ -34265,7 +34265,7 @@ pub const GGCKPLMOOPE = struct {
NOGKOKELAKC: ArrayList(CJHMEKCHFDH), NOGKOKELAKC: ArrayList(CJHMEKCHFDH),
AFAPMKPDNAK: ArrayList(GKKAKMDBGAD), AFAPMKPDNAK: ArrayList(GKKAKMDBGAD),
DLCOBFIGMMD: ArrayList(CJHMEKCHFDH), DLCOBFIGMMD: ArrayList(CJHMEKCHFDH),
HKNADMABCGG: ArrayList(PDLCDMEPDDJ), multi_path_avatar_info_list: ArrayList(MultiPathAvatarInfo),
KPMNKMGMEGA: ArrayList(ILDONLKCIDA), KPMNKMGMEGA: ArrayList(ILDONLKCIDA),
GLEAJHKCMEA: ?FJFLOACEAOL = null, GLEAJHKCMEA: ?FJFLOACEAOL = null,
LLDHJNLGOPL: u32 = 0, LLDHJNLGOPL: u32 = 0,
@ -34288,7 +34288,7 @@ pub const GGCKPLMOOPE = struct {
.NOGKOKELAKC = fd(935, .{ .List = .{ .SubMessage = {} } }), .NOGKOKELAKC = fd(935, .{ .List = .{ .SubMessage = {} } }),
.AFAPMKPDNAK = fd(10, .{ .List = .{ .SubMessage = {} } }), .AFAPMKPDNAK = fd(10, .{ .List = .{ .SubMessage = {} } }),
.DLCOBFIGMMD = fd(3, .{ .List = .{ .SubMessage = {} } }), .DLCOBFIGMMD = fd(3, .{ .List = .{ .SubMessage = {} } }),
.HKNADMABCGG = fd(1767, .{ .List = .{ .SubMessage = {} } }), .multi_path_avatar_info_list = fd(1767, .{ .List = .{ .SubMessage = {} } }),
.KPMNKMGMEGA = fd(176, .{ .List = .{ .SubMessage = {} } }), .KPMNKMGMEGA = fd(176, .{ .List = .{ .SubMessage = {} } }),
.GLEAJHKCMEA = fd(12, .{ .SubMessage = {} }), .GLEAJHKCMEA = fd(12, .{ .SubMessage = {} }),
.LLDHJNLGOPL = fd(552, .{ .Varint = .Simple }), .LLDHJNLGOPL = fd(552, .{ .Varint = .Simple }),