From 2a961704a800a76c60962cc85b1eb8000327de6b Mon Sep 17 00:00:00 2001 From: Kei-Luna Date: Wed, 22 Apr 2026 05:31:08 +0900 Subject: [PATCH] CallGS --- .../Server/CallGS/CallGSApiAttribute.cs | 7 +++ GameServer/Server/CallGS/CallGSRouter.cs | 46 +++++++++++++++++++ .../Achievement/Achievement_GetReward.cs | 13 ++++++ GameServer/Server/CallGS/ICallGSHandler.cs | 6 +++ .../Packet/Recv/Player/HandlerReqCallGS.cs | 14 ++++++ MikuSB/Program/LoaderManager.cs | 4 +- 6 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 GameServer/Server/CallGS/CallGSApiAttribute.cs create mode 100644 GameServer/Server/CallGS/CallGSRouter.cs create mode 100644 GameServer/Server/CallGS/Handlers/Achievement/Achievement_GetReward.cs create mode 100644 GameServer/Server/CallGS/ICallGSHandler.cs create mode 100644 GameServer/Server/Packet/Recv/Player/HandlerReqCallGS.cs diff --git a/GameServer/Server/CallGS/CallGSApiAttribute.cs b/GameServer/Server/CallGS/CallGSApiAttribute.cs new file mode 100644 index 0000000..45a9038 --- /dev/null +++ b/GameServer/Server/CallGS/CallGSApiAttribute.cs @@ -0,0 +1,7 @@ +namespace MikuSB.GameServer.Server.CallGS; + +[AttributeUsage(AttributeTargets.Class)] +public class CallGSApiAttribute(string api) : Attribute +{ + public string Api { get; } = api; +} diff --git a/GameServer/Server/CallGS/CallGSRouter.cs b/GameServer/Server/CallGS/CallGSRouter.cs new file mode 100644 index 0000000..6873fdc --- /dev/null +++ b/GameServer/Server/CallGS/CallGSRouter.cs @@ -0,0 +1,46 @@ +using MikuSB.Proto; +using MikuSB.Util; +using System.Reflection; + +namespace MikuSB.GameServer.Server.CallGS; + +public static class CallGSRouter +{ + private static readonly Logger Logger = new("CallGS"); + private static readonly Dictionary Handlers = []; + + public static void Init() + { + foreach (var type in Assembly.GetExecutingAssembly().GetTypes()) + { + var attr = type.GetCustomAttribute(); + if (attr == null) continue; + Handlers[attr.Api] = (ICallGSHandler)Activator.CreateInstance(type)!; + } + Logger.Info($"Registered {Handlers.Count} CallGS handlers."); + } + + public static async Task Route(Connection connection, ReqCallGS req, ushort seqNo) + { + if (Handlers.TryGetValue(req.Api, out var handler)) + { + try + { + await handler.Handle(connection, req.Param, seqNo); + } + catch (Exception e) + { + Logger.Error($"[{req.Api}] {e.Message}", e); + } + return; + } + + Logger.Error($"No handler for CallGS API: {req.Api}"); + } + + public static async Task SendScript(Connection connection, string api, string arg, ushort seqNo = 0) + { + var rsp = new NtfCallScript { Api = api, Arg = arg }; + await connection.SendPacket(CmdIds.RspCallGS, rsp, seqNo); + } +} diff --git a/GameServer/Server/CallGS/Handlers/Achievement/Achievement_GetReward.cs b/GameServer/Server/CallGS/Handlers/Achievement/Achievement_GetReward.cs new file mode 100644 index 0000000..eabd406 --- /dev/null +++ b/GameServer/Server/CallGS/Handlers/Achievement/Achievement_GetReward.cs @@ -0,0 +1,13 @@ +namespace MikuSB.GameServer.Server.CallGS.Handlers.Achievement; + +[CallGSApi("Achievement_GetReward")] +public class Achievement_GetReward : ICallGSHandler +{ + public async Task Handle(Connection connection, string param, ushort seqNo) + { + // param: json.encode({nId = nId}) + // TODO: implement reward logic + + await CallGSRouter.SendScript(connection, "Achievement_GetReward", "{}", seqNo); + } +} diff --git a/GameServer/Server/CallGS/ICallGSHandler.cs b/GameServer/Server/CallGS/ICallGSHandler.cs new file mode 100644 index 0000000..5f3a5e9 --- /dev/null +++ b/GameServer/Server/CallGS/ICallGSHandler.cs @@ -0,0 +1,6 @@ +namespace MikuSB.GameServer.Server.CallGS; + +public interface ICallGSHandler +{ + Task Handle(Connection connection, string param, ushort seqNo); +} diff --git a/GameServer/Server/Packet/Recv/Player/HandlerReqCallGS.cs b/GameServer/Server/Packet/Recv/Player/HandlerReqCallGS.cs new file mode 100644 index 0000000..b8be93d --- /dev/null +++ b/GameServer/Server/Packet/Recv/Player/HandlerReqCallGS.cs @@ -0,0 +1,14 @@ +using MikuSB.GameServer.Server.CallGS; +using MikuSB.Proto; + +namespace MikuSB.GameServer.Server.Packet.Recv.Player; + +[Opcode(CmdIds.ReqCallGS)] +public class HandlerReqCallGS : Handler +{ + public override async Task OnHandle(Connection connection, byte[] data, ushort seqNo) + { + var req = ReqCallGS.Parser.ParseFrom(data); + await CallGSRouter.Route(connection, req, seqNo); + } +} diff --git a/MikuSB/Program/LoaderManager.cs b/MikuSB/Program/LoaderManager.cs index f0ac644..d940ea5 100644 --- a/MikuSB/Program/LoaderManager.cs +++ b/MikuSB/Program/LoaderManager.cs @@ -3,6 +3,7 @@ using MikuSB.Data; using MikuSB.Database; using MikuSB.GameServer.Command; using MikuSB.GameServer.Server; +using MikuSB.GameServer.Server.CallGS; using MikuSB.GameServer.Server.Packet; using MikuSB.Internationalization; using MikuSB.MikuSB.Tool; @@ -121,7 +122,8 @@ public class LoaderManager : MikuSB SocketConnection.LogMap.TryAdd(value, name); } - HandlerManager.Init(); + HandlerManager.Init(); + CallGSRouter.Init(); } public static async Task InitResource()