using Fantasy; using Fantasy.Async; using Fantasy.Entitas.Interface; using Fantasy.Helper; using Fantasy.Network; using Hotfix.Helper; namespace Hotfix; public static class GameAccountManageComponentSystem { public static void Add(this GameAccountManageComponent self,long accountId, GameAccount gameAccount) { if (!self.Accounts.ContainsKey(accountId)) { self.Accounts.Add(accountId, gameAccount); } else { self.Accounts[accountId] = gameAccount; } } public static GameAccount? Get(this GameAccountManageComponent self,long accountId) { return self.Accounts.GetValueOrDefault(accountId); } public static bool TryGet(this GameAccountManageComponent self,long accountId,out GameAccount account) { return self.Accounts.TryGetValue(accountId,out account); } public static async FTask Remove(this GameAccountManageComponent self, long accountId, bool isDispose = true) { if (!self.TryGet(accountId, out var account)) { return false; } var errorCode = await GateLoginHelper.Offline(account); if (errorCode!= GameErrorCode.Success) { return false; } if (!self.Accounts.Remove(accountId,out var gameAccount)) { return false; } if (isDispose) { gameAccount.Dispose(); } return true; } public static async FTask<(uint error,GameAccount gameAccount)> LoginAccountGame(this GameAccountManageComponent self,Session session,long accountId) { var scene = self.Scene; //GameAccount gameAccount = null; using (await scene.CoroutineLockComponent.Wait((int)ELockType.GateGetGameAccount,accountId)) { // gameAccount = self.Get(accountId); if (!self.TryGet(accountId,out var gameAccount)) { gameAccount = await GameAccountHelper.LoadGameAccountFromDatabase(scene,accountId); if (gameAccount == null) { Log.Debug("Gate创建新的账号(account)并保存到数据库"); gameAccount = await GameAccountFactory.Create(scene, accountId); } self.Add(accountId, gameAccount); } else { Log.Debug("Gate account already exists(账号已存在缓存中)"); if ( gameAccount.SessionRuntimeId == session.RuntimeId) { return (GameErrorCode.GateRepeatedLogin,gameAccount); } Log.Debug($"Gate 检测当前帐号和当前Session 不是同一个,{gameAccount.SessionRuntimeId},${session.RuntimeId}"); if (scene.TryGetEntity( gameAccount.SessionRuntimeId,out var oldSession)) { Log.Debug($"Gate 如果当前Session 存在 需要 发送 给 oldSession 一个 重复登录的消息 ,并且要断开这个Session"); oldSession.GetComponent().AccountId = 0; oldSession.Send(new G2C_LoginRepeatedMessage()); oldSession.SetTimeout(3000); } } var flagCom = session.AddComponent(); flagCom.AccountId = accountId; flagCom.Account = gameAccount; gameAccount.LoginTime = TimeHelper.Now; Log.Debug($"Gate 当前缓存中的 SessionID {session.RuntimeId}"); gameAccount.SessionRuntimeId = session.RuntimeId; return (GameErrorCode.GateLoginSuccess,gameAccount); } } public static async FTask DisConnect(this GameAccountManageComponent self, long accountId,long timeout = 1000 * 60 * 5 ) { var scene = self?.Scene; if (scene == null) { Log.Debug("scene is null"); } if (!self.TryGet(accountId,out var gameAccount)) { Log.Warning("Gate:下线操作时失败,账号缓存库里面并不存在这个账号,逻辑出现错误了"); return; } if (!scene.TryGetEntity(gameAccount.SessionRuntimeId,out var session)) { Log.Warning("Gate:下线操作时失败,Session 未找到 已经实现了断开了逻辑,逻辑出现错误了"); return; } if (gameAccount.IsHasTimeout()) { Log.Debug("Gate 已经存在了销毁组件"); return; } if (timeout < 0 ) { await gameAccount.DisConnect(); return; } gameAccount.SetTimeout(timeout,gameAccount.DisConnect); } public static async FTask UpdateAccountGameName(this GameAccountManageComponent self,Session session,long accountId,string gameName) { if (!self.TryGet(accountId,out var gameAccount)) { gameAccount = (await self.LoginAccountGame(session,accountId)).gameAccount; if (gameAccount == null) { Log.Debug("Gate 修改用户名称 失败 用户不存在"); return GameErrorCode.GateUpdateGameNameFailed; } } Log.Debug($"Gate 修改用户名成功 用户名{gameName}"); gameAccount.GameName = gameName; return GameErrorCode.GateUpdateGameNameSuccess; } public static async FTask GetGameAccount(this GameAccountManageComponent self,Session session,long accountId) { if (!self.TryGet(accountId,out var gameAccount)) { gameAccount = (await self.LoginAccountGame(session,accountId)).gameAccount; if (gameAccount == null) { Log.Debug("Gate 修改用户名称 失败 用户不存在"); return null; } } return gameAccount; } } public class GameAccountManageComponentDestroySystem : DestroySystem { protected override void Destroy(GameAccountManageComponent self) { foreach (var (_,account) in self.Accounts.ToArray()) { account.Dispose(); } self.Accounts.Clear(); } }