Files
Fishing2Server/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs

175 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Fantasy;
using Fantasy.Async;
using Fantasy.Entitas;
using Fantasy.Entitas.Interface;
using Fantasy.Helper;
#pragma warning disable CS8603 // 可能返回 null 引用。
namespace NB.Game;
public sealed class PlayerManageComponentAwakeSystem : AwakeSystem<PlayerManageComponent>
{
protected override void Awake(PlayerManageComponent self)
{
self.AutoSaveTimerId =
self.Scene.TimerComponent.Net.RepeatedTimer(1000 * 60, () => { _ = self.CheckAutoSave(); });
}
}
public sealed class PlayerManageComponentDestroySystem : DestroySystem<PlayerManageComponent>
{
protected override void Destroy(PlayerManageComponent self)
{
foreach (var (_, gameAccount) in self.Players)
{
gameAccount.Dispose();
}
self.Players.Clear();
self.Scene.TimerComponent.Net.Remove(self.AutoSaveTimerId);
self.AutoSaveTimerId = 0;
}
}
public static class PlayerManageComponentSystem
{
#region 线线
/// <summary>
/// 玩家上线
/// </summary>
/// <param name="self"></param>
/// <param name="accountId"></param>
/// <param name="gateRouteId"></param>
public static async FTask<Player?> Online(this PlayerManageComponent self, long accountId, long gateRouteId)
{
Log.Debug("检查账号是否在缓存中");
if (!self.TryGet(accountId, out var account))
{
// 首先要先到数据库中查询是否有这个账号
account = await PlayerHelper.LoadDataBase(self.Scene, accountId);
// 如果有的话,就直接加入在缓存中就可以了
if (account == null)
{
Log.Debug("检查到账号没有在数据库中,需要创建一个新的账号并且保存到数据库中");
// 如果没有,就要创建一个新的并且保存到数据库。
// 如果不存在,表示这是一个新的账号,需要创建一下这个账号。
account = PlayerFactory.Create(self.Scene, accountId);
account.Level = 99;
account.NickName = "王麻子";
account.Country = "cn";
account.Exp = 999;
account.Head = "xxx.png";
// for (int i = 0; i < 500; i++)
// {
// var item = Entity.Create<Item>(scene, true, true);
// account.ItemContainer.Add(item.Id, item);
// }
//
// for (int i = 0; i < 500; i++)
// {
// var item = Entity.Create<Fish>(scene, true, true);
// account.Fishes.Add(item.Id, item);
// }
}
else
{
Log.Debug("检查到账号在数据库中");
}
Log.Debug("把当前账号添加到缓存中");
// 把创建完成的Account放入到缓存中
self.Add(account);
}
else
{
Log.Debug("检测到当前账号已经在缓存中了");
// 如果有延迟下线的计划任务,那就先取消一下。
account.CancelTimeout();
// 如果在Gate的缓存中已经存在了该账号那只能以下几种可能:
// 1、同一客户端发送了重复登录的请求数据。
// 2、客户端经历的断线然后又重新连接到这个服务器上了断线重连
// 3、多个客户端同时登录了这个账号顶号
if (gateRouteId == account.SessionRunTimeId)
{
// 如果执行到这里,说明是客户端发送了多次登录的请求,这样的情况下,直接返回就可以了,不需要做任何操作。
return null;
}
}
// account.Statistics.LoginTime = TimeHelper.Now;
await account.Save();
return account;
}
public static async FTask Offline(this PlayerManageComponent self, long accountId, long sessionId)
{
if (self.TryGet(accountId, out var account))
{
if (account.SessionRunTimeId == sessionId)
{
//退出的是当前的
await account.Save();
self.Remove(accountId);
}
}
}
#endregion
#region &
public static void Add(this PlayerManageComponent self, Player account)
{
self.Players.Add(account.Id, account);
}
public static Player Get(this PlayerManageComponent self, long accountId)
{
return self.Players.GetValueOrDefault(accountId);
}
public static bool TryGet(this PlayerManageComponent self, long accountId, out Player account)
{
return self.Players.TryGetValue(accountId, out account);
}
public static void Remove(this PlayerManageComponent self, long accountId, bool isDispose = true)
{
if (!self.Players.Remove(accountId, out var account))
{
return;
}
if (!isDispose)
{
return;
}
account.Dispose();
}
#endregion
#region
public static async FTask CheckAutoSave(this PlayerManageComponent self)
{
foreach (var (_, player) in self.Players)
{
if (player.NeedSave)
{
await player.SaveImmediately();
}
}
}
#endregion
}