using Fantasy.Async; using Fantasy.Entitas; using Fantasy.Entitas.Interface; using Fantasy.Helper; // ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract #pragma warning disable CS8601 // Possible null reference assignment. namespace Fantasy; public sealed class MailUnitManageComponentDestroySystem : DestroySystem { protected override void Destroy(MailUnitManageComponent self) { // 如果不是在.net8的环境下,比如是Unity里。这个的foreach有可能会出现问题 // 问题的原因是有可能你在mailUnit组件的销毁的时候,去UnitByAccountId删除。 // 这样就会出现了一个经典的错误,就是无法再foreach里删除或改变元素。 foreach (var (_, mailUnit) in self.UnitByAccountId) { mailUnit.Dispose(); } self.UnitByAccountId.Clear(); self.UnitByName.Clear(); self.Online.Clear(); } } public static class MailUnitManageComponentSystem { public static async FTask Init(this MailUnitManageComponent self) { var units = await self.Scene.World.DataBase.Query(d => true, true); foreach (var mailUnit in units) { self.UnitByName.Add(mailUnit.Name, mailUnit); self.UnitByAccountId.Add(mailUnit.AccountId,mailUnit); } Log.Debug($"MailUnitManageComponent Init units:{units.Count}"); } /// /// 用户中心登录逻辑,如果有更新的数据,会自动更新。 /// /// /// /// /// /// public static async FTask Online(this MailUnitManageComponent self, long accountId, string unitName, long gateRouteId) { var selfScene = self.Scene; if (self.UnitByAccountId.TryGetValue(accountId, out var mailUnit)) { Log.Debug($"用户已经存在行不需要重新创建 Name:{unitName} mailUnit:{mailUnit.RuntimeId}"); if (mailUnit.Name != unitName) { // 如果不一致的情况,要先删除之前的缓存,然后再添加到缓存。 self.UnitByName.Remove(mailUnit.Name); self.UnitByName.Add(unitName, mailUnit); mailUnit.Name = unitName; } } else { // 创建新的MailUnit实体。 mailUnit = Entity.Create(selfScene,accountId, true, true); mailUnit.Name = unitName; mailUnit.AccountId = accountId; mailUnit.CreateTime = TimeHelper.Now; // 把创建好的实体添加到缓存中,方便后面使用。 self.UnitByAccountId.Add(accountId, mailUnit); self.UnitByName.Add(unitName,mailUnit); Log.Debug($"用户不存在行需要创建 Name:{unitName} mailUnit:{mailUnit.RuntimeId}"); } // 设置GateRouteId mailUnit.GateRouteId = gateRouteId; // 设置MailComponent if (mailUnit.GetComponent() == null) { // 数据库中查询这个组件是否存在。 var mailComponent = await selfScene.World.DataBase.Query(mailUnit.Id, true); if (mailComponent == null) { // MailUnit没有这个MailComponent组件,就给添加一个新的组件。 mailUnit.AddComponent(); } else { mailUnit.AddComponent(mailComponent); } } // 可选,如果你不需要保存到数据库,那么可以忽略下面的代码。 await selfScene.World.DataBase.Save(mailUnit); // 领取下离线的邮件。如果有的情况下。 await selfScene.GetComponent().GetHaveMail(mailUnit, true); // 把用户添加到在线的列表 self.Online.Add(mailUnit.Id, mailUnit); // 返回MailUnit实体。 return mailUnit; } /// /// 退出登录逻辑,会自动保存数据。 /// /// /// public static async FTask Exit(this MailUnitManageComponent self, MailUnit mailUnit) { var mailComponent = mailUnit.GetComponent(); if (mailComponent == null) { return; } // 保存mailComponent到数据库中。 await self.Scene.World.DataBase.Save(mailComponent); // 移除这个组件。 mailUnit.RemoveComponent(); // 在在线列表的容器中,移除这个MailUnit实体。 self.Online.Remove(mailUnit.Id); Log.Debug($"AccountId:{mailUnit.AccountId} Name:{mailUnit.Name} Exit!"); } /// /// 根据UnitName获取MailUnit实体 /// /// /// /// /// public static bool TryGet(this MailUnitManageComponent self, string unitName, out MailUnit mailUnit) { return self.UnitByName.TryGetValue(unitName, out mailUnit); } /// /// 根据AccountId获取MailUnit实体 /// /// /// /// /// public static bool TryGet(this MailUnitManageComponent self, long accountId, out MailUnit mailUnit) { return self.UnitByAccountId.TryGetValue(accountId, out mailUnit); } /// /// 删除MailUnit实体。 /// /// /// /// public static async FTask Remove(this MailUnitManageComponent self, long accountId) { // if (!self.UnitByAccountId.TryGetValue(accountId, out var mailUnit)) // { // // 这个1代表的是没有找到对应的MailUnit // return 1; // } if (!self.UnitByAccountId.Remove(accountId, out var mailUnit)) { // 这个1代表的是没有找到对应的MailUnit return 1; } self.UnitByName.Remove(mailUnit.Name); // 在数据库中删除MailUnit实体 await self.Scene.World.DataBase.Remove(mailUnit.Id); // 销毁这个MailUnit mailUnit.Dispose(); return 0; } }