176 lines
6.6 KiB
C#
176 lines
6.6 KiB
C#
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<MailUnitManageComponent>
|
||
{
|
||
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<MailUnit>(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}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 用户中心登录逻辑,如果有更新的数据,会自动更新。
|
||
/// </summary>
|
||
/// <param name="self"></param>
|
||
/// <param name="accountId"></param>
|
||
/// <param name="unitName"></param>
|
||
/// <param name="gateRouteId"></param>
|
||
/// <returns></returns>
|
||
public static async FTask<MailUnit> 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<MailUnit>(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<MailComponent>() == null)
|
||
{
|
||
// 数据库中查询这个组件是否存在。
|
||
var mailComponent = await selfScene.World.DataBase.Query<MailComponent>(mailUnit.Id, true);
|
||
if (mailComponent == null)
|
||
{
|
||
// MailUnit没有这个MailComponent组件,就给添加一个新的组件。
|
||
mailUnit.AddComponent<MailComponent>();
|
||
}
|
||
else
|
||
{
|
||
mailUnit.AddComponent(mailComponent);
|
||
}
|
||
}
|
||
// 可选,如果你不需要保存到数据库,那么可以忽略下面的代码。
|
||
await selfScene.World.DataBase.Save(mailUnit);
|
||
// 领取下离线的邮件。如果有的情况下。
|
||
await selfScene.GetComponent<MailBoxManageComponent>().GetHaveMail(mailUnit, true);
|
||
// 把用户添加到在线的列表
|
||
self.Online.Add(mailUnit.Id, mailUnit);
|
||
// 返回MailUnit实体。
|
||
return mailUnit;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 退出登录逻辑,会自动保存数据。
|
||
/// </summary>
|
||
/// <param name="self"></param>
|
||
/// <param name="mailUnit"></param>
|
||
public static async FTask Exit(this MailUnitManageComponent self, MailUnit mailUnit)
|
||
{
|
||
var mailComponent = mailUnit.GetComponent<MailComponent>();
|
||
if (mailComponent == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 保存mailComponent到数据库中。
|
||
await self.Scene.World.DataBase.Save(mailComponent);
|
||
// 移除这个组件。
|
||
mailUnit.RemoveComponent<MailComponent>();
|
||
// 在在线列表的容器中,移除这个MailUnit实体。
|
||
self.Online.Remove(mailUnit.Id);
|
||
Log.Debug($"AccountId:{mailUnit.AccountId} Name:{mailUnit.Name} Exit!");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据UnitName获取MailUnit实体
|
||
/// </summary>
|
||
/// <param name="self"></param>
|
||
/// <param name="unitName"></param>
|
||
/// <param name="mailUnit"></param>
|
||
/// <returns></returns>
|
||
public static bool TryGet(this MailUnitManageComponent self, string unitName, out MailUnit mailUnit)
|
||
{
|
||
return self.UnitByName.TryGetValue(unitName, out mailUnit);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据AccountId获取MailUnit实体
|
||
/// </summary>
|
||
/// <param name="self"></param>
|
||
/// <param name="accountId"></param>
|
||
/// <param name="mailUnit"></param>
|
||
/// <returns></returns>
|
||
public static bool TryGet(this MailUnitManageComponent self, long accountId, out MailUnit mailUnit)
|
||
{
|
||
return self.UnitByAccountId.TryGetValue(accountId, out mailUnit);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除MailUnit实体。
|
||
/// </summary>
|
||
/// <param name="self"></param>
|
||
/// <param name="accountId"></param>
|
||
/// <returns></returns>
|
||
public static async FTask<uint> 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>(mailUnit.Id);
|
||
// 销毁这个MailUnit
|
||
mailUnit.Dispose();
|
||
return 0;
|
||
}
|
||
} |