First push
This commit is contained in:
parent
f0211138f5
commit
43fd9302d6
26 changed files with 38824 additions and 0 deletions
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
# This file is for zig-specific build artifacts.
|
||||
# If you have OS-specific or editor-specific files to ignore,
|
||||
# such as *.swp or .DS_Store, put those in your global
|
||||
# ~/.gitignore and put this in your ~/.gitconfig:
|
||||
#
|
||||
# [core]
|
||||
# excludesfile = ~/.gitignore
|
||||
|
||||
.zig-cache/
|
||||
zig-out/
|
||||
/release/
|
||||
/debug/
|
||||
/build/
|
||||
/build-*/
|
||||
/docgen_tmp/
|
||||
|
||||
# Although this was renamed to .zig-cache, let's leave it here for a few
|
||||
# releases to make it less annoying to work with multiple branches.
|
||||
zig-cache/
|
||||
|
||||
protocol/StarRail.proto
|
||||
protocol/nameTranslation.txt
|
51
build.zig
Normal file
51
build.zig
Normal file
|
@ -0,0 +1,51 @@
|
|||
const std = @import("std");
|
||||
const protobuf = @import("protobuf");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const dep_opts = .{ .target = target, .optimize = optimize };
|
||||
|
||||
const protobuf_dep = b.dependency("protobuf", dep_opts);
|
||||
|
||||
if (std.fs.cwd().access("protocol/StarRail.proto", .{})) {
|
||||
const protoc_step = protobuf.RunProtocStep.create(b, protobuf_dep.builder, target, .{
|
||||
.destination_directory = b.path("protocol/src"),
|
||||
.source_files = &.{
|
||||
"protocol/StarRail.proto",
|
||||
},
|
||||
.include_directories = &.{},
|
||||
});
|
||||
|
||||
b.getInstallStep().dependOn(&protoc_step.step);
|
||||
} else |_| {} // don't invoke protoc if proto definition doesn't exist
|
||||
|
||||
const dispatch = b.dependency("dispatch", dep_opts);
|
||||
b.installArtifact(dispatch.artifact("dispatch"));
|
||||
|
||||
const gameserver = b.dependency("gameserver", dep_opts);
|
||||
b.installArtifact(gameserver.artifact("gameserver"));
|
||||
|
||||
// "run-dispatch" command
|
||||
const dispatch_cmd = b.addRunArtifact(dispatch.artifact("dispatch"));
|
||||
dispatch_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
if (b.args) |args| {
|
||||
dispatch_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
const dispatch_step = b.step("run-dispatch", "Run the dispatch server");
|
||||
dispatch_step.dependOn(&dispatch_cmd.step);
|
||||
|
||||
// "run-gameserver" command
|
||||
const gameserver_cmd = b.addRunArtifact(gameserver.artifact("gameserver"));
|
||||
gameserver_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
if (b.args) |args| {
|
||||
gameserver_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
const gameserver_step = b.step("run-gameserver", "Run the game server");
|
||||
gameserver_step.dependOn(&gameserver_cmd.step);
|
||||
}
|
15
build.zig.zon
Normal file
15
build.zig.zon
Normal file
|
@ -0,0 +1,15 @@
|
|||
.{
|
||||
.name = "YunliSR",
|
||||
.version = "0.0.1",
|
||||
.minimum_zig_version = "0.13.0",
|
||||
.dependencies = .{
|
||||
.dispatch = .{ .path = "dispatch" },
|
||||
.gameserver = .{ .path = "gameserver" },
|
||||
.protocol = .{ .path = "protocol" },
|
||||
.protobuf = .{
|
||||
.url = "https://github.com/Arwalk/zig-protobuf/archive/7c49ed66e029c9c7e6253b3d6d256118745550a4.tar.gz",
|
||||
.hash = "122063ee7ff32a3c1aefd91a46a9fc23df0571949c3a02e2f44d39afbad0b53018a3",
|
||||
},
|
||||
},
|
||||
.paths = .{""},
|
||||
}
|
35
dispatch/build.zig
Normal file
35
dispatch/build.zig
Normal file
|
@ -0,0 +1,35 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const httpz = b.dependency("httpz", .{
|
||||
.optimize = optimize,
|
||||
.target = target,
|
||||
});
|
||||
|
||||
const protocol = b.dependency("protocol", .{});
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "dispatch",
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
exe.root_module.addImport("httpz", httpz.module("httpz"));
|
||||
exe.root_module.addImport("protocol", protocol.module("protocol"));
|
||||
|
||||
b.installArtifact(exe);
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
28
dispatch/build.zig.zon
Normal file
28
dispatch/build.zig.zon
Normal file
|
@ -0,0 +1,28 @@
|
|||
.{
|
||||
.name = "dispatch",
|
||||
.version = "0.0.1",
|
||||
.minimum_zig_version = "0.13.0",
|
||||
|
||||
// This field is optional.
|
||||
// Each dependency must either provide a `url` and `hash`, or a `path`.
|
||||
// `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
|
||||
// Once all dependencies are fetched, `zig build` no longer requires
|
||||
// internet connectivity.
|
||||
.dependencies = .{
|
||||
.httpz = .{
|
||||
.url = "https://github.com/karlseguin/http.zig/archive/406fb00f8c43fe9b2da0f32f428675755c67d054.tar.gz",
|
||||
.hash = "12209e87663712928c6ae1c690e65df15a796e970e5d18f5e4e05f0eb10404883d23",
|
||||
},
|
||||
.protocol = .{
|
||||
.path = "../protocol",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
// For example...
|
||||
//"LICENSE",
|
||||
//"README.md",
|
||||
},
|
||||
}
|
48
dispatch/src/authentication.zig
Normal file
48
dispatch/src/authentication.zig
Normal file
|
@ -0,0 +1,48 @@
|
|||
const std = @import("std");
|
||||
const httpz = @import("httpz");
|
||||
|
||||
pub fn onShieldLogin(_: *httpz.Request, res: *httpz.Response) !void {
|
||||
std.log.debug("onShieldLogin", .{});
|
||||
|
||||
try res.json(.{
|
||||
.retcode = 0,
|
||||
.message = "OK",
|
||||
.data = .{
|
||||
.account = .{
|
||||
.area_code = "**",
|
||||
.email = "reversedrooms@xeondev.com",
|
||||
.country = "RU",
|
||||
.is_email_verify = "1",
|
||||
.token = "mostsecuretokenever",
|
||||
.uid = "1337",
|
||||
},
|
||||
},
|
||||
}, .{});
|
||||
}
|
||||
|
||||
pub fn onComboTokenReq(_: *httpz.Request, res: *httpz.Response) !void {
|
||||
std.log.debug("onComboTokenReq", .{});
|
||||
|
||||
try res.json(.{
|
||||
.retcode = 0,
|
||||
.message = "OK",
|
||||
.data = .{
|
||||
.account_type = 1,
|
||||
.open_id = "1337",
|
||||
.combo_id = "1337",
|
||||
.combo_token = "mostsecuretokenever",
|
||||
.heartbeat = false,
|
||||
.data = "{\"guest\": false}",
|
||||
},
|
||||
}, .{});
|
||||
}
|
||||
|
||||
pub fn onRiskyApiCheck(_: *httpz.Request, res: *httpz.Response) !void {
|
||||
std.log.debug("onRiskyApiCheck", .{});
|
||||
|
||||
try res.json(.{
|
||||
.retcode = 0,
|
||||
.message = "OK",
|
||||
.data = .{ .id = "" },
|
||||
}, .{});
|
||||
}
|
56
dispatch/src/dispatch.zig
Normal file
56
dispatch/src/dispatch.zig
Normal file
|
@ -0,0 +1,56 @@
|
|||
const std = @import("std");
|
||||
const httpz = @import("httpz");
|
||||
const protocol = @import("protocol");
|
||||
const Base64Encoder = @import("std").base64.standard.Encoder;
|
||||
|
||||
pub fn onQueryDispatch(_: *httpz.Request, res: *httpz.Response) !void {
|
||||
std.log.debug("onQueryDispatch", .{});
|
||||
|
||||
var proto = protocol.GlobalDispatchData.init(res.arena);
|
||||
|
||||
proto.retcode = 0;
|
||||
try proto.server_list.append(.{
|
||||
.name = .{ .Const = "YunliSR" },
|
||||
.display_name = .{ .Const = "YunliSR" },
|
||||
.env_type = .{ .Const = "2" },
|
||||
.title = .{ .Const = "YunliSR" },
|
||||
.dispatch_url = .{ .Const = "http://127.0.0.1:21000/query_gateway" },
|
||||
});
|
||||
|
||||
const data = try proto.encode(res.arena);
|
||||
const size = Base64Encoder.calcSize(data.len);
|
||||
const output = try res.arena.alloc(u8, size);
|
||||
_ = Base64Encoder.encode(output, data);
|
||||
|
||||
res.body = output;
|
||||
}
|
||||
|
||||
pub fn onQueryGateway(_: *httpz.Request, res: *httpz.Response) !void {
|
||||
std.log.debug("onQueryGateway", .{});
|
||||
|
||||
var proto = protocol.Gateserver.init(res.arena);
|
||||
|
||||
proto.retcode = 0;
|
||||
proto.use_tcp = true;
|
||||
proto.port = 23301;
|
||||
proto.ip = .{ .Const = "127.0.0.1" };
|
||||
proto.lua_version = .{ .Const = "7327274" };
|
||||
proto.ifix_version = .{ .Const = "0" };
|
||||
proto.lua_url = .{ .Const = "https://autopatchos.starrails.com/lua/BetaLive/output_7327274_d12d75929650" };
|
||||
proto.asset_bundle_url = .{ .Const = "https://autopatchos.starrails.com/asb/BetaLive/output_7327119_c52eec0f6a92" };
|
||||
proto.ex_resource_url = .{ .Const = "https://autopatchos.starrails.com/design_data/BetaLive/output_7349339_419592cb2562" };
|
||||
proto.MCANJEHAEKO = true;
|
||||
proto.PGMFEHFKLBG = true;
|
||||
proto.NNPPEAAIHAK = true;
|
||||
proto.LGPAAPCPBMD = true;
|
||||
proto.GNFPFKJHIDJ = true;
|
||||
proto.FKFKCDJNHFL = true;
|
||||
proto.AOEKIKFKMGA = true;
|
||||
|
||||
const data = try proto.encode(res.arena);
|
||||
const size = Base64Encoder.calcSize(data.len);
|
||||
const output = try res.arena.alloc(u8, size);
|
||||
_ = Base64Encoder.encode(output, data);
|
||||
|
||||
res.body = output;
|
||||
}
|
22
dispatch/src/main.zig
Normal file
22
dispatch/src/main.zig
Normal file
|
@ -0,0 +1,22 @@
|
|||
const std = @import("std");
|
||||
const httpz = @import("httpz");
|
||||
const protocol = @import("protocol");
|
||||
|
||||
const authentication = @import("authentication.zig");
|
||||
const dispatch = @import("dispatch.zig");
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var server = try httpz.Server().init(allocator, .{ .port = 21000 });
|
||||
var router = server.router();
|
||||
|
||||
router.get("/query_dispatch", dispatch.onQueryDispatch);
|
||||
router.get("/query_gateway", dispatch.onQueryGateway);
|
||||
router.post("/account/risky/api/check", authentication.onRiskyApiCheck);
|
||||
router.post("/:product_name/mdk/shield/api/login", authentication.onShieldLogin);
|
||||
router.post("/:product_name/combo/granter/login/v2/login", authentication.onComboTokenReq);
|
||||
|
||||
try server.listen();
|
||||
}
|
28
gameserver/build.zig
Normal file
28
gameserver/build.zig
Normal file
|
@ -0,0 +1,28 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const protocol = b.dependency("protocol", .{});
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "gameserver",
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
exe.root_module.addImport("protocol", protocol.module("protocol"));
|
||||
b.installArtifact(exe);
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
18
gameserver/build.zig.zon
Normal file
18
gameserver/build.zig.zon
Normal file
|
@ -0,0 +1,18 @@
|
|||
.{
|
||||
.name = "gameserver",
|
||||
.version = "0.0.0",
|
||||
.minimum_zig_version = "0.13.0",
|
||||
.dependencies = .{
|
||||
.protocol = .{
|
||||
.path = "../protocol",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
// For example...
|
||||
//"LICENSE",
|
||||
//"README.md",
|
||||
},
|
||||
}
|
75
gameserver/src/Packet.zig
Normal file
75
gameserver/src/Packet.zig
Normal file
|
@ -0,0 +1,75 @@
|
|||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Reader = std.net.Stream.Reader;
|
||||
const Self = @This();
|
||||
|
||||
cmd_id: u16,
|
||||
head: []u8,
|
||||
body: []u8,
|
||||
allocator: Allocator,
|
||||
|
||||
const head_magic: u32 = 0x9D74C714;
|
||||
const tail_magic: u32 = 0xD7A152C8;
|
||||
|
||||
pub const DecodeError = error{
|
||||
HeadMagicMismatch,
|
||||
TailMagicMismatch,
|
||||
PayloadTooBig,
|
||||
};
|
||||
|
||||
pub fn read(reader: *Reader, allocator: Allocator) !Self {
|
||||
if (try reader.readInt(u32, .big) != Self.head_magic) {
|
||||
return Self.DecodeError.HeadMagicMismatch;
|
||||
}
|
||||
|
||||
const cmd_id = try reader.readInt(u16, .big);
|
||||
const head_len = try reader.readInt(u16, .big);
|
||||
const body_len = try reader.readInt(u32, .big);
|
||||
|
||||
if (body_len > 0xFFFFFF) {
|
||||
return Self.DecodeError.PayloadTooBig;
|
||||
}
|
||||
|
||||
const head = try allocator.alloc(u8, head_len);
|
||||
errdefer allocator.free(head);
|
||||
|
||||
const body = try allocator.alloc(u8, body_len);
|
||||
errdefer allocator.free(body);
|
||||
|
||||
_ = try reader.readAll(head);
|
||||
_ = try reader.readAll(body);
|
||||
|
||||
if (try reader.readInt(u32, .big) != Self.tail_magic) {
|
||||
return Self.DecodeError.TailMagicMismatch;
|
||||
}
|
||||
|
||||
return .{
|
||||
.cmd_id = cmd_id,
|
||||
.head = head,
|
||||
.body = body,
|
||||
.allocator = allocator,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getProto(self: *const Self, comptime T: type, allocator: Allocator) !T {
|
||||
return try T.decode(self.body, allocator);
|
||||
}
|
||||
|
||||
pub fn encode(cmd_id: u16, head: []u8, body: []u8, allocator: Allocator) ![]u8 {
|
||||
var buf = try allocator.alloc(u8, 16 + head.len + body.len);
|
||||
|
||||
std.mem.writeInt(u32, buf[0..4], Self.head_magic, .big);
|
||||
std.mem.writeInt(u16, buf[4..6], cmd_id, .big);
|
||||
std.mem.writeInt(u16, buf[6..8], @intCast(head.len), .big);
|
||||
std.mem.writeInt(u32, buf[8..12], @intCast(body.len), .big);
|
||||
@memcpy(buf[12..(12 + head.len)], head);
|
||||
@memcpy(buf[(12 + head.len)..(12 + head.len + body.len)], body);
|
||||
std.mem.writeInt(u32, buf[(12 + head.len + body.len)..][0..4], Self.tail_magic, .big);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.allocator.free(self.head);
|
||||
self.allocator.free(self.body);
|
||||
}
|
54
gameserver/src/Session.zig
Normal file
54
gameserver/src/Session.zig
Normal file
|
@ -0,0 +1,54 @@
|
|||
const std = @import("std");
|
||||
const protocol = @import("protocol");
|
||||
const handlers = @import("handlers.zig");
|
||||
const Packet = @import("Packet.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
|
||||
const Stream = std.net.Stream;
|
||||
const Address = std.net.Address;
|
||||
|
||||
const Self = @This();
|
||||
|
||||
address: Address,
|
||||
stream: Stream,
|
||||
allocator: Allocator,
|
||||
|
||||
pub fn init(address: Address, stream: Stream, allocator: Allocator) Self {
|
||||
return .{
|
||||
.address = address,
|
||||
.stream = stream,
|
||||
.allocator = allocator,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn run(self: *Self) !void {
|
||||
defer self.stream.close();
|
||||
|
||||
var reader = self.stream.reader();
|
||||
while (true) {
|
||||
var packet = Packet.read(&reader, self.allocator) catch break;
|
||||
defer packet.deinit();
|
||||
|
||||
try handlers.handle(self, &packet);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send(self: *Self, cmd_id: protocol.CmdID, proto: anytype) !void {
|
||||
const data = try proto.encode(self.allocator);
|
||||
defer self.allocator.free(data);
|
||||
|
||||
const packet = try Packet.encode(@intFromEnum(cmd_id), &.{}, data, self.allocator);
|
||||
defer self.allocator.free(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 {
|
||||
const packet = try Packet.encode(@intFromEnum(cmd_id), &.{}, &.{}, self.allocator);
|
||||
defer self.allocator.free(packet);
|
||||
|
||||
_ = try self.stream.write(packet);
|
||||
std.log.debug("sent EMPTY packet with id {}", .{cmd_id});
|
||||
}
|
93
gameserver/src/handlers.zig
Normal file
93
gameserver/src/handlers.zig
Normal file
|
@ -0,0 +1,93 @@
|
|||
const std = @import("std");
|
||||
const protocol = @import("protocol");
|
||||
const Session = @import("Session.zig");
|
||||
const Packet = @import("Packet.zig");
|
||||
const avatar = @import("services/avatar.zig");
|
||||
const battle = @import("services/battle.zig");
|
||||
const login = @import("services/login.zig");
|
||||
const lineup = @import("services/lineup.zig");
|
||||
const mission = @import("services/mission.zig");
|
||||
const scene = @import("services/scene.zig");
|
||||
const misc = @import("services/misc.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const CmdID = protocol.CmdID;
|
||||
|
||||
const Action = *const fn (*Session, *const Packet, Allocator) anyerror!void;
|
||||
const HandlerList = [_]struct { CmdID, Action }{
|
||||
.{ CmdID.CmdPlayerGetTokenCsReq, login.onPlayerGetToken },
|
||||
.{ CmdID.CmdPlayerLoginCsReq, login.onPlayerLogin },
|
||||
.{ CmdID.CmdPlayerHeartBeatCsReq, misc.onPlayerHeartBeat },
|
||||
.{ CmdID.CmdGetAvatarDataCsReq, avatar.onGetAvatarData },
|
||||
.{ CmdID.CmdGetMissionStatusCsReq, mission.onGetMissionStatus },
|
||||
.{ CmdID.CmdGetCurLineupDataCsReq, lineup.onGetCurLineupData },
|
||||
.{ CmdID.CmdGetCurSceneInfoCsReq, scene.onGetCurSceneInfo },
|
||||
.{ CmdID.CmdSceneEntityMoveCsReq, scene.onSceneEntityMove },
|
||||
.{ CmdID.CmdStartCocoonStageCsReq, battle.onStartCocoonStage },
|
||||
.{ CmdID.CmdPVEBattleResultCsReq, battle.onPVEBattleResult },
|
||||
};
|
||||
|
||||
const DummyCmdList = [_]struct { CmdID, CmdID }{
|
||||
.{ CmdID.CmdGetBasicInfoCsReq, CmdID.CmdGetBasicInfoScRsp },
|
||||
.{ CmdID.CmdGetMultiPathAvatarInfoCsReq, CmdID.CmdGetMultiPathAvatarInfoScRsp },
|
||||
.{ CmdID.CmdGetBagCsReq, CmdID.CmdGetBagScRsp },
|
||||
.{ CmdID.CmdGetMarkItemListCsReq, CmdID.CmdGetMarkItemListScRsp },
|
||||
.{ CmdID.CmdGetPlayerBoardDataCsReq, CmdID.CmdGetPlayerBoardDataScRsp },
|
||||
.{ CmdID.CmdGetCurAssistCsReq, CmdID.CmdGetCurAssistScRsp },
|
||||
.{ CmdID.CmdGetAllLineupDataCsReq, CmdID.CmdGetAllLineupDataScRsp },
|
||||
.{ CmdID.CmdGetAllServerPrefsDataCsReq, CmdID.CmdGetAllServerPrefsDataScRsp },
|
||||
.{ CmdID.CmdGetActivityScheduleConfigCsReq, CmdID.CmdGetActivityScheduleConfigScRsp },
|
||||
.{ CmdID.CmdGetMissionDataCsReq, CmdID.CmdGetMissionDataScRsp },
|
||||
.{ CmdID.CmdGetMissionEventDataCsReq, CmdID.CmdGetMissionEventDataScRsp },
|
||||
.{ CmdID.CmdGetQuestDataCsReq, CmdID.CmdGetQuestDataScRsp },
|
||||
.{ CmdID.CmdGetCurChallengeCsReq, CmdID.CmdGetCurChallengeScRsp },
|
||||
.{ CmdID.CmdGetRogueCommonDialogueDataCsReq, CmdID.CmdGetRogueCommonDialogueDataScRsp },
|
||||
.{ CmdID.CmdGetRogueInfoCsReq, CmdID.CmdGetRogueInfoScRsp },
|
||||
.{ CmdID.CmdGetRogueHandbookDataCsReq, CmdID.CmdGetRogueHandbookDataScRsp },
|
||||
.{ CmdID.CmdGetRogueEndlessActivityDataCsReq, CmdID.CmdGetRogueEndlessActivityDataScRsp },
|
||||
.{ CmdID.CmdChessRogueQueryCsReq, CmdID.CmdChessRogueQueryScRsp },
|
||||
.{ CmdID.CmdRogueTournQueryCsReq, CmdID.CmdRogueTournQueryScRsp },
|
||||
.{ CmdID.CmdSyncClientResVersionCsReq, CmdID.CmdSyncClientResVersionScRsp },
|
||||
.{ CmdID.CmdDailyFirstMeetPamCsReq, CmdID.CmdDailyFirstMeetPamScRsp },
|
||||
.{ CmdID.CmdGetBattleCollegeDataCsReq, CmdID.CmdGetBattleCollegeDataScRsp },
|
||||
.{ CmdID.CmdGetNpcStatusCsReq, CmdID.CmdGetNpcStatusScRsp },
|
||||
.{ CmdID.CmdGetSecretKeyInfoCsReq, CmdID.CmdGetSecretKeyInfoScRsp },
|
||||
.{ CmdID.CmdGetHeartDialInfoCsReq, CmdID.CmdGetHeartDialInfoScRsp },
|
||||
.{ CmdID.CmdGetVideoVersionKeyCsReq, CmdID.CmdGetVideoVersionKeyScRsp },
|
||||
.{ CmdID.CmdGetCurBattleInfoCsReq, CmdID.CmdGetCurBattleInfoScRsp },
|
||||
.{ CmdID.CmdHeliobusActivityDataCsReq, CmdID.CmdHeliobusActivityDataScRsp },
|
||||
.{ CmdID.CmdGetEnteredSceneCsReq, CmdID.CmdGetEnteredSceneScRsp },
|
||||
.{ CmdID.CmdGetAetherDivideInfoCsReq, CmdID.CmdGetAetherDivideInfoScRsp },
|
||||
.{ CmdID.CmdGetMapRotationDataCsReq, CmdID.CmdGetMapRotationDataScRsp },
|
||||
.{ CmdID.CmdGetRogueCollectionCsReq, CmdID.CmdGetRogueCollectionScRsp },
|
||||
.{ CmdID.CmdGetRogueExhibitionCsReq, CmdID.CmdGetRogueExhibitionScRsp },
|
||||
.{ CmdID.CmdPlayerReturnInfoQueryCsReq, CmdID.CmdPlayerReturnInfoQueryScRsp },
|
||||
.{ CmdID.CmdPlayerLoginFinishCsReq, CmdID.CmdPlayerLoginFinishScRsp },
|
||||
.{ CmdID.CmdGetLevelRewardTakenListCsReq, CmdID.CmdGetLevelRewardTakenListScRsp },
|
||||
.{ CmdID.CmdGetMainMissionCustomValueCsReq, CmdID.CmdGetMainMissionCustomValueScRsp },
|
||||
};
|
||||
|
||||
pub fn handle(session: *Session, packet: *const Packet) !void {
|
||||
var arena = ArenaAllocator.init(session.allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const cmd_id: CmdID = @enumFromInt(packet.cmd_id);
|
||||
|
||||
inline for (HandlerList) |handler| {
|
||||
if (handler[0] == cmd_id) {
|
||||
try handler[1](session, packet, arena.allocator());
|
||||
std.log.debug("packet {} was handled", .{cmd_id});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline for (DummyCmdList) |pair| {
|
||||
if (pair[0] == cmd_id) {
|
||||
try session.send_empty(pair[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std.log.warn("packet {} was ignored", .{cmd_id});
|
||||
}
|
10
gameserver/src/main.zig
Normal file
10
gameserver/src/main.zig
Normal file
|
@ -0,0 +1,10 @@
|
|||
const std = @import("std");
|
||||
const network = @import("network.zig");
|
||||
const handlers = @import("handlers.zig");
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
try network.listen(allocator);
|
||||
}
|
36
gameserver/src/network.zig
Normal file
36
gameserver/src/network.zig
Normal file
|
@ -0,0 +1,36 @@
|
|||
const std = @import("std");
|
||||
const Session = @import("Session.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub fn listen(allocator: Allocator) !void {
|
||||
const addr = std.net.Address.parseIp4("0.0.0.0", 23301) catch unreachable;
|
||||
var listener = try addr.listen(.{
|
||||
.kernel_backlog = 100,
|
||||
.reuse_address = true,
|
||||
});
|
||||
|
||||
std.log.info("server is listening at {}", .{listener.listen_address});
|
||||
|
||||
while (true) {
|
||||
const conn = listener.accept() catch continue;
|
||||
errdefer conn.stream.close();
|
||||
|
||||
const session = try allocator.create(Session);
|
||||
session.* = Session.init(conn.address, conn.stream, allocator);
|
||||
|
||||
const thread = try std.Thread.spawn(.{}, runSession, .{session});
|
||||
thread.detach();
|
||||
}
|
||||
}
|
||||
|
||||
fn runSession(s: *Session) void {
|
||||
std.log.info("new connection from {}", .{s.address});
|
||||
|
||||
if (s.run()) |_| {
|
||||
std.log.info("client from {} disconnected", .{s.address});
|
||||
} else |err| {
|
||||
std.log.err("session disconnected with an error: {}", .{err});
|
||||
}
|
||||
|
||||
s.allocator.destroy(s);
|
||||
}
|
31
gameserver/src/services/avatar.zig
Normal file
31
gameserver/src/services/avatar.zig
Normal file
|
@ -0,0 +1,31 @@
|
|||
const std = @import("std");
|
||||
const protocol = @import("protocol");
|
||||
const CmdID = protocol.CmdID;
|
||||
const Session = @import("../Session.zig");
|
||||
const Packet = @import("../Packet.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const AllAvatars = [_]u32{
|
||||
1001, 1002, 1003, 1004, 1005, 1006, 1008, 1009, 1013, 1101, 1102, 1103, 1104, 1105, 1106, 1107,
|
||||
1108, 1109, 1110, 1111, 1112, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211,
|
||||
1212, 1213, 1214, 1215, 1217, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1312,
|
||||
1314, 1315, 1221, 1218,
|
||||
};
|
||||
|
||||
pub fn onGetAvatarData(session: *Session, packet: *const Packet, allocator: Allocator) !void {
|
||||
const req = try packet.getProto(protocol.GetAvatarDataCsReq, allocator);
|
||||
var rsp = protocol.GetAvatarDataScRsp.init(allocator);
|
||||
|
||||
rsp.is_all = req.is_get_all;
|
||||
|
||||
for (AllAvatars) |id| {
|
||||
var avatar = protocol.Avatar.init(allocator);
|
||||
avatar.base_avatar_id = id;
|
||||
avatar.level = 80;
|
||||
avatar.promotion = 6;
|
||||
avatar.rank = 6;
|
||||
try rsp.avatar_list.append(avatar);
|
||||
}
|
||||
|
||||
try session.send(CmdID.CmdGetAvatarDataScRsp, rsp);
|
||||
}
|
50
gameserver/src/services/battle.zig
Normal file
50
gameserver/src/services/battle.zig
Normal file
|
@ -0,0 +1,50 @@
|
|||
const std = @import("std");
|
||||
const protocol = @import("protocol");
|
||||
const CmdID = protocol.CmdID;
|
||||
const Session = @import("../Session.zig");
|
||||
const Packet = @import("../Packet.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub fn onStartCocoonStage(session: *Session, packet: *const Packet, allocator: Allocator) !void {
|
||||
const req = try packet.getProto(protocol.StartCocoonStageCsReq, allocator);
|
||||
|
||||
var avatar = protocol.BattleAvatar.init(allocator);
|
||||
avatar.id = 1221;
|
||||
avatar.hp = 10000;
|
||||
avatar.sp = .{ .sp_cur = 10000, .sp_need = 10000 };
|
||||
avatar.level = 80;
|
||||
avatar.rank = 6;
|
||||
avatar.promotion = 6;
|
||||
avatar.avatar_type = .AVATAR_FORMAL_TYPE;
|
||||
|
||||
var battle = protocol.SceneBattleInfo.init(allocator);
|
||||
for (0..req.wave) |_| {
|
||||
const monster = protocol.SceneMonsterInfo{ .monster_id = 3024020 };
|
||||
var monster_wave = protocol.SceneMonsterWave.init(allocator);
|
||||
try monster_wave.monster_list.append(monster);
|
||||
try battle.monster_wave_list.append(monster_wave);
|
||||
}
|
||||
|
||||
try battle.battle_avatar_list.append(avatar);
|
||||
battle.battle_id = 1;
|
||||
battle.stage_id = 201012311;
|
||||
battle.logic_random_seed = @intCast(@mod(std.time.timestamp(), 0xFFFFFFFF));
|
||||
|
||||
try session.send(CmdID.CmdStartCocoonStageScRsp, protocol.StartCocoonStageScRsp{
|
||||
.retcode = 0,
|
||||
.cocoon_id = req.cocoon_id,
|
||||
.prop_entity_id = req.prop_entity_id,
|
||||
.wave = req.wave,
|
||||
.battle_info = battle,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn onPVEBattleResult(session: *Session, packet: *const Packet, allocator: Allocator) !void {
|
||||
const req = try packet.getProto(protocol.PVEBattleResultCsReq, allocator);
|
||||
|
||||
var rsp = protocol.PVEBattleResultScRsp.init(allocator);
|
||||
rsp.battle_id = req.battle_id;
|
||||
rsp.end_status = req.end_status;
|
||||
|
||||
try session.send(CmdID.CmdPVEBattleResultScRsp, rsp);
|
||||
}
|
26
gameserver/src/services/lineup.zig
Normal file
26
gameserver/src/services/lineup.zig
Normal file
|
@ -0,0 +1,26 @@
|
|||
const std = @import("std");
|
||||
const protocol = @import("protocol");
|
||||
const CmdID = protocol.CmdID;
|
||||
const Session = @import("../Session.zig");
|
||||
const Packet = @import("../Packet.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub fn onGetCurLineupData(session: *Session, _: *const Packet, allocator: Allocator) !void {
|
||||
const avatar = protocol.LineupAvatar{
|
||||
.id = 1221,
|
||||
.slot = 0,
|
||||
.satiety = 0,
|
||||
.hp = 10000,
|
||||
.avatar_type = protocol.AvatarType.AVATAR_FORMAL_TYPE,
|
||||
.sp = .{ .sp_cur = 10000, .sp_need = 10000 },
|
||||
};
|
||||
|
||||
var lineup = protocol.LineupInfo.init(allocator);
|
||||
lineup.name = .{ .Const = "Squad 1" };
|
||||
try lineup.avatar_list.append(avatar);
|
||||
|
||||
try session.send(CmdID.CmdGetCurLineupDataScRsp, protocol.GetCurLineupDataScRsp{
|
||||
.retcode = 0,
|
||||
.lineup = lineup,
|
||||
});
|
||||
}
|
32
gameserver/src/services/login.zig
Normal file
32
gameserver/src/services/login.zig
Normal file
|
@ -0,0 +1,32 @@
|
|||
const std = @import("std");
|
||||
const protocol = @import("protocol");
|
||||
const CmdID = protocol.CmdID;
|
||||
const Session = @import("../Session.zig");
|
||||
const Packet = @import("../Packet.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub fn onPlayerGetToken(session: *Session, _: *const Packet, allocator: Allocator) !void {
|
||||
var rsp = protocol.PlayerGetTokenScRsp.init(allocator);
|
||||
|
||||
rsp.retcode = 0;
|
||||
rsp.uid = 1337;
|
||||
|
||||
try session.send(CmdID.CmdPlayerGetTokenScRsp, rsp);
|
||||
}
|
||||
|
||||
pub fn onPlayerLogin(session: *Session, packet: *const Packet, allocator: Allocator) !void {
|
||||
const req = try packet.getProto(protocol.PlayerLoginCsReq, allocator);
|
||||
|
||||
var basic_info = protocol.PlayerBasicInfo.init(allocator);
|
||||
basic_info.stamina = 240;
|
||||
basic_info.level = 5;
|
||||
basic_info.nickname = .{ .Const = "xeondev" };
|
||||
|
||||
var rsp = protocol.PlayerLoginScRsp.init(allocator);
|
||||
rsp.retcode = 0;
|
||||
rsp.login_random = req.login_random;
|
||||
rsp.stamina = 240;
|
||||
rsp.basic_info = basic_info;
|
||||
|
||||
try session.send(CmdID.CmdPlayerLoginScRsp, rsp);
|
||||
}
|
26
gameserver/src/services/misc.zig
Normal file
26
gameserver/src/services/misc.zig
Normal file
|
@ -0,0 +1,26 @@
|
|||
const std = @import("std");
|
||||
const protocol = @import("protocol");
|
||||
const CmdID = protocol.CmdID;
|
||||
const Session = @import("../Session.zig");
|
||||
const Packet = @import("../Packet.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const B64Decoder = std.base64.standard.Decoder;
|
||||
|
||||
pub fn onPlayerHeartBeat(session: *Session, packet: *const Packet, allocator: Allocator) !void {
|
||||
const req = try packet.getProto(protocol.PlayerHeartBeatCsReq, allocator);
|
||||
|
||||
const downloadDataBin = "CDMQuQoa1AFDUy5Vbml0eUVuZ2luZS5HYW1lT2JqZWN0LkZpbmQoIlVJUm9vdC9BYm92ZURpYWxvZy9CZXRhSGludERpYWxvZyhDbG9uZSkiKTpHZXRDb21wb25lbnRJbkNoaWxkcmVuKHR5cGVvZihDUy5SUEcuQ2xpZW50LkxvY2FsaXplZFRleHQpKS50ZXh0ID0gIll1bmxpU1IgaXMgYSBmcmVlIGFuZCBvcGVuIHNvdXJjZSBzb2Z0d2FyZS4gZGlzY29yZC5nZy9yZXZlcnNlZHJvb21zIg==";
|
||||
const size = try B64Decoder.calcSizeForSlice(downloadDataBin);
|
||||
const buf = try allocator.alloc(u8, size);
|
||||
_ = try B64Decoder.decode(buf, downloadDataBin);
|
||||
const data = try protocol.ClientDownloadData.decode(buf, allocator);
|
||||
|
||||
const rsp = protocol.PlayerHeartBeatScRsp{
|
||||
.retcode = 0,
|
||||
.client_time_ms = req.client_time_ms,
|
||||
.server_time_ms = @intCast(std.time.timestamp()),
|
||||
.download_data = data,
|
||||
};
|
||||
|
||||
try session.send(CmdID.CmdPlayerHeartBeatScRsp, rsp);
|
||||
}
|
96
gameserver/src/services/mission.zig
Normal file
96
gameserver/src/services/mission.zig
Normal file
|
@ -0,0 +1,96 @@
|
|||
const std = @import("std");
|
||||
const protocol = @import("protocol");
|
||||
const CmdID = protocol.CmdID;
|
||||
const Session = @import("../Session.zig");
|
||||
const Packet = @import("../Packet.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const FinishedMainMissionIdList = [_]u32{
|
||||
1000101, 1000111, 1000112, 1000113, 1000114, 1000201, 1000202, 1000203, 1000204, 1000300,
|
||||
1000301, 1000302, 1000303, 1000304, 1000400, 1000401, 1000402, 1000410, 1000500, 1000501,
|
||||
1000502, 1000503, 1000504, 1000505, 1000510, 1000511, 1010001, 1010002, 1010101, 1010201,
|
||||
1010202, 1010203, 1010204, 1010205, 1010206, 1010301, 1010302, 1010303, 1010401, 1010405,
|
||||
1010402, 1010403, 1010500, 1010501, 1010502, 1010503, 1010601, 1010602, 1010700, 1010701,
|
||||
1010801, 1010802, 1010901, 1010902, 1011001, 1011002, 1011003, 1011100, 1011101, 1011102,
|
||||
1011103, 1011201, 1011202, 1011301, 1011400, 1011401, 1011402, 1011403, 1011501, 1011502,
|
||||
1011503, 1020101, 1020201, 1020302, 1020301, 1020400, 1020401, 1020402, 1020403, 1020501,
|
||||
1020601, 1020701, 1020702, 1020801, 1020901, 1021001, 1021101, 1021201, 1021301, 1021401,
|
||||
1021501, 1021601, 2000001, 2000002, 2000003, 2000004, 2000100, 2000101, 2000131, 2000132,
|
||||
2000133, 2000110, 2000111, 2000301, 2000103, 2000112, 2000108, 2000104, 2000102, 2000105,
|
||||
2000106, 2000107, 2000313, 2000314, 2000109, 2000113, 2000116, 2000118, 2000119, 2000120,
|
||||
2000122, 2000302, 2000303, 2000304, 2000305, 2000310, 2000311, 2000312, 2000320, 2000701,
|
||||
2000702, 2000703, 2000704, 2000705, 2000706, 2000707, 2010005, 2010301, 2010302, 2011103,
|
||||
2011104, 2011409, 2010401, 2010402, 2010405, 2010502, 2010503, 2010701, 2010708, 2010709,
|
||||
2010720, 2010730, 2010731, 2010732, 2010733, 2010734, 2010735, 2010904, 2011101, 2011102,
|
||||
2011105, 2011301, 2011302, 2011303, 2011501, 2011502, 2010909, 2010910, 2011901, 2011902,
|
||||
2011903, 2011904, 2011905, 2011906, 2020301, 2020302, 2020304, 2020316, 2020317, 2020318,
|
||||
2020319, 2020401, 2020402, 2020403, 2020404, 2020405, 2020406, 2020407, 2020303, 2020103,
|
||||
2020104, 2020105, 2020106, 2020107, 2020108, 2020109, 2020110, 2020201, 2020202, 2020203,
|
||||
2020204, 2000201, 2000202, 2000203, 2000204, 2000205, 2000206, 2000207, 2000208, 2000209,
|
||||
2000211, 2000212, 2010500, 2010501, 2010705, 2010706, 2010901, 2010902, 2010903, 2010702,
|
||||
2010703, 2011400, 2011401, 2011406, 2011402, 2011403, 2011404, 2011405, 2011407, 2011408,
|
||||
2011410, 2010905, 2010906, 2010907, 2010908, 2010911, 2010912, 2020305, 2020306, 2020309,
|
||||
2020307, 2020308, 2020701, 2020702, 2020313, 2020314, 2020315, 6020101, 6020201, 6020202,
|
||||
2020801, 2020802, 2020901, 2021601, 2021602, 3000201, 3000202, 3000203, 3000211, 3000212,
|
||||
3000213, 3000301, 3000302, 3000303, 3000522, 3000523, 3000524, 3000525, 3000526, 3000527,
|
||||
3000601, 3000602, 3000603, 3000604, 3000701, 3000702, 3000703, 3000704, 3000705, 3000800,
|
||||
3000801, 3000802, 3000803, 3010102, 3010103, 3010104, 3010105, 3010201, 3010202, 3010203,
|
||||
3010204, 3010205, 3011011, 3011012, 3011013, 3011014, 3011111, 3011112, 3011113, 3011114,
|
||||
3011201, 3011202, 3011203, 3011204, 3011205, 3011206, 3011207, 3011208, 3011401, 3011402,
|
||||
3011403, 3011404, 3011405, 3011406, 3011407, 3011408, 3011501, 3011502, 3011503, 3011504,
|
||||
3011505, 3011601, 3011602, 3011603, 3011604, 3011605, 3011606, 3011607, 3011608, 3011609,
|
||||
3011610, 3012001, 4020101, 4020102, 4020103, 4020104, 4020105, 4020106, 4020107, 4020108,
|
||||
4020109, 4020110, 4020111, 4020112, 4020113, 4020114, 4010105, 4010106, 4010107, 4010112,
|
||||
4010113, 4010131, 4010115, 4010116, 4010121, 4010122, 4010123, 4010124, 4010125, 4010126,
|
||||
4010127, 4010128, 4010133, 4010134, 4010135, 4010130, 4010136, 4010137, 4015101, 4015103,
|
||||
4015102, 4015202, 4015203, 4015204, 4015301, 4015302, 4015303, 4030001, 4030002, 4030003,
|
||||
4030004, 4030006, 4030007, 4030009, 4030010, 4040001, 4040002, 4040003, 4040004, 4040005,
|
||||
4040006, 4040052, 4040007, 4040008, 4040051, 4040009, 4040010, 4040011, 4040012, 4040053,
|
||||
4040014, 4040015, 4040017, 4040018, 4040019, 4040020, 4040021, 4040022, 4040023, 4040024,
|
||||
4040100, 4040189, 4040190, 4040101, 4040151, 4040154, 4040102, 4040103, 4040153, 4040104,
|
||||
4040152, 4040105, 4040106, 4040155, 4040107, 4040108, 4040109, 4040156, 4040157, 4040110,
|
||||
4040114, 4040115, 4040158, 4040159, 4040160, 4040161, 4040162, 4040116, 4040169, 4040163,
|
||||
4040164, 4040165, 4040166, 4040167, 4040168, 4040170, 4040171, 4040172, 4040173, 4040174,
|
||||
4040175, 4040176, 4040177, 4040178, 4040179, 4040180, 4040181, 4040182, 4040183, 4040184,
|
||||
4040185, 4040186, 4040117, 4040118, 4040119, 4040187, 4040120, 4040188, 4040121, 4040122,
|
||||
4040123, 4040124, 4040125, 4040126, 4040127, 4040128, 4040129, 4040130, 4040201, 4040202,
|
||||
4040203, 4040204, 4040205, 4040206, 4040207, 4040208, 4040290, 4040209, 4040210, 4040211,
|
||||
4040212, 4040213, 4040214, 4040215, 4040216, 4040217, 4040218, 4040219, 4040220, 4040221,
|
||||
4040222, 4040223, 4040224, 4040225, 4040226, 4040227, 4040228, 4040229, 4040230, 4040231,
|
||||
4040240, 4040241, 4040242, 4040244, 4040245, 4040246, 4040247, 4050005, 4050007, 4050008,
|
||||
4050009, 4050010, 4050011, 4050012, 4050013, 4050014, 4050015, 4050016, 4050017, 4050018,
|
||||
4050019, 4050020, 4050021, 4050022, 4050023, 4050024, 4050025, 4050026, 4050027, 4050028,
|
||||
4050029, 4050030, 4050031, 4050032, 4050033, 4050034, 4050035, 4050036, 4050037, 4072121,
|
||||
4072122, 4072123, 4071311, 4071312, 4071313, 4071320, 4071321, 4071322, 4122100, 4122101,
|
||||
4122102, 4122103, 4081311, 4081312, 4081313, 4081314, 4081315, 4081316, 4081317, 4081318,
|
||||
8000001, 8000002, 8000101, 8000102, 8000104, 8000105, 8000131, 8000132, 8000133, 8000134,
|
||||
8000135, 8000136, 8000137, 8000138, 8000139, 8000151, 8000152, 8000153, 8000154, 8000155,
|
||||
8000156, 8000157, 8000158, 8000159, 8000161, 8000162, 8000170, 8000171, 8000172, 8000173,
|
||||
8000174, 8000175, 8000177, 8000178, 8000180, 8000181, 8000183, 8000182, 8000185, 8000184,
|
||||
8000186, 8000187, 8000188, 8000189, 8000201, 8000202, 8000203, 8000204, 8001201, 8001202,
|
||||
8001203, 8001205, 8001206, 8001207, 8001208, 8001209, 8001211, 8001212, 8001213, 8001215,
|
||||
8001216, 8001219, 8001220, 8001223, 8001224, 8001225, 8001226, 8001227, 8001204, 8001210,
|
||||
8001214, 8001217, 8001218, 8001221, 8001222, 8001241, 8001242, 8001243, 8001244, 8001251,
|
||||
8001252, 8001253, 8001254, 8001255, 8001261, 8001262, 8001263, 8001264, 8001265, 8001266,
|
||||
8001267, 8001268, 8011401, 8002201, 8002202, 8002211, 8002212, 8002213, 8002214, 8002221,
|
||||
8002222, 8002231, 8002232, 8002233, 8002234, 8012101, 8012102, 8012103, 8012104, 8012105,
|
||||
8012106, 8012107, 8012401, 9999920,
|
||||
};
|
||||
|
||||
pub fn onGetMissionStatus(session: *Session, packet: *const Packet, allocator: Allocator) !void {
|
||||
const req = try packet.getProto(protocol.GetMissionStatusCsReq, allocator);
|
||||
var rsp = protocol.GetMissionStatusScRsp.init(allocator);
|
||||
|
||||
rsp.retcode = 0;
|
||||
for (req.sub_mission_id_list.items) |id| {
|
||||
try rsp.sub_mission_status_list.append(protocol.Mission{ .id = id, .status = protocol.MissionStatus.MISSION_FINISH, .progress = 1 });
|
||||
}
|
||||
|
||||
for (req.mission_event_id_list.items) |id| {
|
||||
try rsp.mission_event_status_list.append(protocol.Mission{ .id = id, .status = protocol.MissionStatus.MISSION_FINISH, .progress = 1 });
|
||||
}
|
||||
|
||||
try rsp.finished_main_mission_id_list.appendSlice(&FinishedMainMissionIdList);
|
||||
|
||||
try session.send(CmdID.CmdGetMissionStatusScRsp, rsp);
|
||||
}
|
76
gameserver/src/services/scene.zig
Normal file
76
gameserver/src/services/scene.zig
Normal file
|
@ -0,0 +1,76 @@
|
|||
const std = @import("std");
|
||||
const protocol = @import("protocol");
|
||||
const CmdID = protocol.CmdID;
|
||||
const Session = @import("../Session.zig");
|
||||
const Packet = @import("../Packet.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub fn onGetCurSceneInfo(session: *Session, _: *const Packet, allocator: Allocator) !void {
|
||||
var scene_info = protocol.SceneInfo.init(allocator);
|
||||
scene_info.game_mode_type = 1;
|
||||
scene_info.plane_id = 20101;
|
||||
scene_info.floor_id = 20101001;
|
||||
scene_info.entry_id = 2010101;
|
||||
|
||||
{ // Character
|
||||
var scene_group = protocol.SceneGroupInfo.init(allocator);
|
||||
scene_group.state = 1;
|
||||
|
||||
try scene_group.entity_list.append(.{
|
||||
.entity = .{
|
||||
.actor = .{
|
||||
.base_avatar_id = 1221,
|
||||
.avatar_type = .AVATAR_FORMAL_TYPE,
|
||||
.uid = 1337,
|
||||
.map_layer = 2,
|
||||
},
|
||||
},
|
||||
.motion = .{ .pos = .{ .x = -2300, .y = 19365, .z = 3150 }, .rot = .{} },
|
||||
});
|
||||
|
||||
try scene_info.scene_group_list.append(scene_group);
|
||||
}
|
||||
|
||||
{ // Calyx prop
|
||||
var scene_group = protocol.SceneGroupInfo.init(allocator);
|
||||
scene_group.state = 1;
|
||||
scene_group.group_id = 19;
|
||||
|
||||
var prop = protocol.ScenePropInfo.init(allocator);
|
||||
prop.prop_id = 808;
|
||||
prop.prop_state = 1;
|
||||
|
||||
try scene_group.entity_list.append(.{
|
||||
.group_id = 19,
|
||||
.inst_id = 300001,
|
||||
.entity_id = 1337,
|
||||
.entity = .{
|
||||
.prop = prop,
|
||||
},
|
||||
.motion = .{ .pos = .{ .x = -570, .y = 19364, .z = 4480 }, .rot = .{} },
|
||||
});
|
||||
|
||||
try scene_info.scene_group_list.append(scene_group);
|
||||
}
|
||||
|
||||
try session.send(CmdID.CmdGetCurSceneInfoScRsp, protocol.GetCurSceneInfoScRsp{
|
||||
.scene = scene_info,
|
||||
.retcode = 0,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn onSceneEntityMove(session: *Session, packet: *const Packet, allocator: Allocator) !void {
|
||||
const req = try packet.getProto(protocol.SceneEntityMoveCsReq, allocator);
|
||||
|
||||
for (req.entity_motion_list.items) |entity_motion| {
|
||||
if (entity_motion.motion) |motion| {
|
||||
std.log.debug("[POSITION] entity_id: {}, motion: {}", .{ entity_motion.entity_id, motion });
|
||||
}
|
||||
}
|
||||
|
||||
try session.send(CmdID.CmdSceneEntityMoveScRsp, protocol.SceneEntityMoveScRsp{
|
||||
.retcode = 0,
|
||||
.entity_motion_list = req.entity_motion_list,
|
||||
.download_data = null,
|
||||
});
|
||||
}
|
18
protocol/build.zig
Normal file
18
protocol/build.zig
Normal file
|
@ -0,0 +1,18 @@
|
|||
const std = @import("std");
|
||||
const protobuf = @import("protobuf");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const protobuf_dep = b.dependency("protobuf", .{
|
||||
.optimize = optimize,
|
||||
.target = target,
|
||||
});
|
||||
|
||||
const protocol = b.addModule("protocol", .{
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
});
|
||||
//
|
||||
protocol.addImport("protobuf", protobuf_dep.module("protobuf"));
|
||||
}
|
15
protocol/build.zig.zon
Normal file
15
protocol/build.zig.zon
Normal file
|
@ -0,0 +1,15 @@
|
|||
.{
|
||||
.name = "protocol",
|
||||
.version = "0.0.0",
|
||||
.dependencies = .{
|
||||
.protobuf = .{
|
||||
.url = "https://github.com/Arwalk/zig-protobuf/archive/7c49ed66e029c9c7e6253b3d6d256118745550a4.tar.gz",
|
||||
.hash = "122063ee7ff32a3c1aefd91a46a9fc23df0571949c3a02e2f44d39afbad0b53018a3",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
},
|
||||
}
|
36306
protocol/src/protocol.pb.zig
Normal file
36306
protocol/src/protocol.pb.zig
Normal file
File diff suppressed because it is too large
Load diff
1557
protocol/src/root.zig
Normal file
1557
protocol/src/root.zig
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue