XtGameKit/Packages/cn.xt.db/Scripts/Hotfix/Server/DBSaveComponentSystem.cs

93 lines
2.5 KiB
C#

using System.Collections.Generic;
namespace ET.Server
{
[EntitySystemOf(typeof(DBSaveComponent))]
[FriendOf(typeof(DBSaveComponent))]
public static partial class DBSaveComponentSystem
{
[EntitySystem]
private static void Awake(this DBSaveComponent self)
{
self.RunFlushLoop().NoContext();
}
[EntitySystem]
private static void Destroy(this DBSaveComponent self)
{
self.DirtyAccounts.Clear();
}
public static void MarkDirty(this DBSaveComponent self, string account)
{
if (string.IsNullOrEmpty(account))
{
return;
}
self.DirtyAccounts.Add(account);
}
public static async ETTask FlushNow(this DBSaveComponent self, string account)
{
if (string.IsNullOrEmpty(account))
{
return;
}
Scene root = self.Root();
DBComponent dbComponent = root.GetComponent<DBComponent>();
PlayerComponent playerComponent = root.GetComponent<PlayerComponent>();
if (dbComponent == null || playerComponent == null)
{
return;
}
Player player = playerComponent.GetByAccount(account);
if (player == null)
{
self.DirtyAccounts.Remove(account);
return;
}
await dbComponent.Save(player.Id, player);
self.DirtyAccounts.Remove(account);
}
private static async ETTask RunFlushLoop(this DBSaveComponent self)
{
Scene root = self.Root();
TimerComponent timerComponent = root.GetComponent<TimerComponent>();
if (timerComponent == null)
{
return;
}
while (!self.IsDisposed)
{
await timerComponent.WaitAsync(self.FlushIntervalMs);
if (self.IsDisposed)
{
break;
}
await self.FlushDirtyPlayers();
}
}
private static async ETTask FlushDirtyPlayers(this DBSaveComponent self)
{
if (self.DirtyAccounts.Count == 0)
{
return;
}
List<string> accounts = new(self.DirtyAccounts);
foreach (string account in accounts)
{
await self.FlushNow(account);
}
}
}
}