From e850a18d54d62d27d7627bcca1414c2b61dd514f Mon Sep 17 00:00:00 2001 From: rfi Date: Tue, 14 Nov 2023 21:12:15 +0700 Subject: [PATCH] graceful shutdown kill protocol + double session checking --- AscNet.Common/MsgPack/Types.cs | 6 ++--- AscNet.GameServer/Handlers/AccountModule.cs | 26 +++++++++++++++++++-- AscNet.GameServer/Server.cs | 2 +- AscNet/Program.cs | 12 ++++++++++ 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/AscNet.Common/MsgPack/Types.cs b/AscNet.Common/MsgPack/Types.cs index 5e7641f2..3c1e8ea0 100644 --- a/AscNet.Common/MsgPack/Types.cs +++ b/AscNet.Common/MsgPack/Types.cs @@ -214,10 +214,10 @@ namespace AscNet.Common.MsgPack [MessagePackObject(true)] public partial class ItemList { - public long Id { get; set; } + public int Id { get; set; } public long Count { get; set; } - public long BuyTimes { get; set; } - public long TotalBuyTimes { get; set; } + public int BuyTimes { get; set; } + public int TotalBuyTimes { get; set; } public long LastBuyTime { get; set; } public long RefreshTime { get; set; } public long CreateTime { get; set; } diff --git a/AscNet.GameServer/Handlers/AccountModule.cs b/AscNet.GameServer/Handlers/AccountModule.cs index 18f7938a..3c98a80f 100644 --- a/AscNet.GameServer/Handlers/AccountModule.cs +++ b/AscNet.GameServer/Handlers/AccountModule.cs @@ -1,12 +1,25 @@ using AscNet.Common.Database; using AscNet.Common.MsgPack; -using AscNet.Table.share.fuben; using AscNet.Table.share.guide; using MessagePack; -using Newtonsoft.Json; namespace AscNet.GameServer.Handlers { + #region MsgPackScheme +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + [MessagePackObject(true)] + public class ForceLogoutNotify + { + public int Code; + } + + [MessagePackObject(true)] + public class ShutdownNotify + { + } +#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + #endregion + internal class AccountModule { [RequestPacketHandler("HandshakeRequest")] @@ -40,6 +53,14 @@ namespace AscNet.GameServer.Handlers return; } + Session? previousSession = Server.Instance.Sessions.Select(x => x.Value).Where(x => x.GetHashCode() != session.GetHashCode()).FirstOrDefault(x => x.player.PlayerData.Id == player.PlayerData.Id); + if (previousSession is not null) + { + // GateServerForceLogoutByAnotherLogin + previousSession.SendPush(new ForceLogoutNotify() { Code = 1018 }); + previousSession.DisconnectProtocol(); + } + session.player = player; session.character = Character.FromUid(player.PlayerData.Id); session.stage = Stage.FromUid(player.PlayerData.Id); @@ -110,6 +131,7 @@ namespace AscNet.GameServer.Handlers FubenMainLineData = new(), FubenChapterExtraLoginData = new(), FubenUrgentEventData = new(), + // ItemList = ItemTableReader.Instance.All.Select(x => new ItemList() { Id = x.Id, Count = 6969696969 }).ToList(), UseBackgroundId = 14000001 // main ui theme, table still failed to dump }; if (notifyLogin.PlayerData.DisplayCharIdList.Count < 1) diff --git a/AscNet.GameServer/Server.cs b/AscNet.GameServer/Server.cs index 61d9ac59..800863d9 100644 --- a/AscNet.GameServer/Server.cs +++ b/AscNet.GameServer/Server.cs @@ -61,7 +61,7 @@ namespace AscNet.GameServer public Session? SessionFromUID(long uid) { - return Sessions.FirstOrDefault(x => x.Value.player.PlayerData.Id == uid).Value; + return Sessions.Select(x => x.Value).FirstOrDefault(x => x.player.PlayerData.Id == uid); } } } \ No newline at end of file diff --git a/AscNet/Program.cs b/AscNet/Program.cs index be3b7884..bf59147e 100644 --- a/AscNet/Program.cs +++ b/AscNet/Program.cs @@ -1,4 +1,5 @@ using AscNet.GameServer; +using AscNet.GameServer.Handlers; using AscNet.GameServer.Commands; using AscNet.Logging; @@ -22,6 +23,17 @@ namespace AscNet Task.Run(Server.Instance.Start); SDKServer.SDKServer.Main(args); + + AppDomain.CurrentDomain.ProcessExit += new EventHandler(KillProtocol); + } + + static void KillProtocol(object? sender, EventArgs e) + { + foreach (var session in Server.Instance.Sessions) + { + session.Value.SendPush(new ShutdownNotify()); + session.Value.DisconnectProtocol(); + } } } } \ No newline at end of file