新增私聊相关

This commit is contained in:
2025-08-18 23:24:33 +08:00
parent 34b25273a7
commit 8122c577f6
68 changed files with 1442 additions and 467 deletions

View File

@@ -1,16 +0,0 @@
using Fantasy;
namespace NB.Game;
public static class CacheHandler
{
public static List<RoleSimpleInfo> GetPlayerBasicCacheInfos(List<long> id)
{
}
public static RoleSimpleInfo GetPlayerBasicCacheInfos(long id)
{
}
}

View File

@@ -0,0 +1,24 @@
using Fantasy;
using Fantasy.Async;
using Fantasy.Network.Interface;
namespace NB.Game;
public class
S2G_GetPlayerBasicInfoRequestHandler : RouteRPC<Scene, S2G_GetPlayerBasicInfoRequest,
G2S_GetPlayerBasicInfoResponse>
{
protected override async FTask Run(Scene scene, S2G_GetPlayerBasicInfoRequest request,
G2S_GetPlayerBasicInfoResponse response, Action reply)
{
var playerBasicCacheManageComponent = scene.GetComponent<PlayerBasicCacheManageComponent>();
if (playerBasicCacheManageComponent != null)
{
var list = await playerBasicCacheManageComponent.GetPlayerBasicCacheInfos(request.IdList);
if (list != null && list.Count > 0)
{
response.RoleList.AddRange(list);
}
}
}
}

View File

@@ -0,0 +1,49 @@
using Fantasy;
using Fantasy.Async;
namespace NB.Game;
public static class CacheHandler
{
/// <summary>
/// 查询玩家基础信息
/// </summary>
/// <param name="scene"></param>
/// <param name="id"></param>
/// <returns></returns>
public static async FTask<List<RoleSimpleInfo>> GetPlayerBasicCacheInfos(Scene scene, List<long> id)
{
var gameSceneConfig = GameSceneHelper.GetSceneConfig();
var gameRouteId = gameSceneConfig.RouteId;
//连接到游戏中心服
var gameResponse = (G2S_GetPlayerBasicInfoResponse)await scene.NetworkMessagingComponent.CallInnerRoute(
gameRouteId, new S2G_GetPlayerBasicInfoRequest()
{
IdList = id
});
if (gameResponse.ErrorCode != 0)
{
return new List<RoleSimpleInfo>();
}
return gameResponse.RoleList;
}
/// <summary>
/// 获取玩家基础信息
/// </summary>
/// <param name="scene"></param>
/// <param name="id"></param>
/// <returns></returns>
public static async FTask<RoleSimpleInfo?> GetPlayerBasicCacheInfo(Scene scene, long id)
{
var list = await GetPlayerBasicCacheInfos(scene, [id]);
if (list.Count > 0)
{
return list[0];
}
return null;
}
}

View File

@@ -0,0 +1,13 @@
using Fantasy;
using Fantasy.Entitas;
namespace NB.Game;
public class PlayerBasicCacheFactory
{
public static PlayerBasicCache Create(Scene scene, long id)
{
var player = Entity.Create<PlayerBasicCache>(scene, id, true, true);
return player;
}
}

View File

@@ -0,0 +1,130 @@
using System.Diagnostics;
using Fantasy;
using Fantasy.Async;
using Fantasy.Entitas.Interface;
using Fantasy.Helper;
namespace NB.Game;
public class PlayerBasicCacheManageComponentAwakeSystem : AwakeSystem<PlayerBasicCacheManageComponent>
{
protected override void Awake(PlayerBasicCacheManageComponent self)
{
// var timerId = self.Scene.TimerComponent.Net.RepeatedTimer(1000 * 60, new TestEvent());
}
}
public class PlayerBasicCacheManageComponentDestroySystem : DestroySystem<PlayerBasicCacheManageComponent>
{
protected override void Destroy(PlayerBasicCacheManageComponent self)
{
foreach (var (_, player) in self.Players)
{
player.Dispose();
}
self.Players.Clear();
}
}
public static class PlayerBasicCacheManageComponentSystem
{
/// <summary>
/// 获取一组玩家基本信息
/// </summary>
/// <param name="manage"></param>
/// <param name="list"></param>
/// <returns></returns>
public static async FTask<List<RoleSimpleInfo>> GetPlayerBasicCacheInfos(
this PlayerBasicCacheManageComponent manage,
List<long> list)
{
var ret = new List<RoleSimpleInfo>();
var notCacheIdList = new List<long>();
foreach (var id in list)
{
var info = GetPlayerBasicCacheInfos(manage, id);
if (info != null)
{
ret.Add(info);
}
else
{
notCacheIdList.Add(id);
}
}
if (notCacheIdList.Count > 0)
{
//查数据库
var dbDataList = await LoadPlayerBasicCacheByDB(manage, notCacheIdList);
foreach (var playerBasicCache in dbDataList)
{
ret.Add(playerBasicCache.ToInfo());
}
}
return ret;
}
/// <summary>
/// 获取缓存的单个玩家基本信息
/// </summary>
/// <param name="manage"></param>
/// <param name="id"></param>
/// <returns></returns>
public static RoleSimpleInfo? GetPlayerBasicCacheInfos(this PlayerBasicCacheManageComponent manage,
long id)
{
if (manage.Players.TryGetValue(id, out var cache))
{
return cache.ToInfo();
}
return null;
}
/// <summary>
/// 从数据库中加载玩家基本信息
/// </summary>
/// <param name="manage"></param>
/// <param name="ids"></param>
/// <returns></returns>
public static async FTask<List<PlayerBasicCache>> LoadPlayerBasicCacheByDB(
this PlayerBasicCacheManageComponent manage,
List<long> ids)
{
// Stopwatch stopwatch = new Stopwatch();
// stopwatch.Start();
var ret = new List<PlayerBasicCache>();
//TODO:需要考虑如果数量过大是否需要分页
List<Player> players =
await manage.Scene.World.DataBase.QueryByPage<Player>(d => ids.Contains(d.Id), 1, ids.Count);
foreach (var player in players)
{
var cache = manage.UpdateCache(player);
ret.Add(cache);
}
return ret;
}
public static PlayerBasicCache UpdateCache(this PlayerBasicCacheManageComponent manage, Player player)
{
if (!manage.Players.TryGetValue(player.Id, out var cache))
{
cache = PlayerBasicCacheFactory.Create(manage.Scene, player.Id);
manage.Players.Add(player.Id, cache);
}
cache.NickName = player.NickName;
cache.Country = player.Country;
cache.Head = player.Head;
cache.Level = player.Level;
cache.IsVip = player.IsVip;
cache.ExpirationTime = TimeHelper.Now + TimeHelper.OneDay; //更新则过期时间增加一天
return cache;
}
}

View File

@@ -0,0 +1,33 @@
using Fantasy;
using Fantasy.Entitas.Interface;
namespace NB.Game;
public class PlayerBasicCacheDestroySystem : DestroySystem<PlayerBasicCache>
{
protected override void Destroy(PlayerBasicCache self)
{
self.Country = string.Empty;
self.NickName = string.Empty;
self.Head = string.Empty;
self.Level = 0;
self.IsVip = false;
self.ExpirationTime = 0;
}
}
public static class PlayerBasicCacheSystem
{
public static RoleSimpleInfo ToInfo(this PlayerBasicCache player)
{
var ret = new RoleSimpleInfo();
ret.NickName = player.NickName;
ret.Country = player.Country;
ret.Head = player.Head;
ret.Level = player.Level;
ret.Vip = player.IsVip;
ret.RoleId = player.Id;
return ret;
}
}

View File

@@ -8,13 +8,16 @@ namespace NB.Game;
public static class GameSceneHelper
{
private static SceneConfig GetSceneConfig()
#region 线 线
public static SceneConfig GetSceneConfig()
{
var gameSceneConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Game);
return gameSceneConfigs.First();
}
public static async FTask<(long, RoleSimpleInfo?)> Online(Scene scene, long accountID, long gateRuntimeId)
{
var gameSceneConfig = GetSceneConfig();
@@ -34,8 +37,12 @@ public static class GameSceneHelper
return (gameResponse.RoleRouteId, gameResponse.RoleInfo);
}
public static async FTask Offline(Scene scene, long accountId, long gateRuntimeId)
{
}
#endregion
}

View File

@@ -1,79 +0,0 @@
using Fantasy;
using Fantasy.Async;
using Fantasy.Entitas.Interface;
using Fantasy.Helper;
namespace NB.Game;
public class MailComponentDestroySystem : DestroySystem<MailComponent>
{
protected override void Destroy(MailComponent self)
{
foreach (var (_, mail) in self.Mails)
{
mail.Dispose();
}
self.Mails.Clear();
self.Timer.Clear();
}
}
public static class MailComponentSystem
{
public static async FTask Add(this MailComponent self, Mail mail, bool sync)
{
mail.CreateTime = TimeHelper.Now;
mail.ExpireTime = TimeHelper.Now + MailComponent.MaxExpireTime;
if (self.Mails.Count >= MailComponent.MaxMailCount)
{
//删除最老的邮件
var (_, value) = self.Timer.First();
foreach (var removeId in value)
{
await self.Remove(removeId, sync);
}
}
self.Mails.Add(mail.Id, mail);
self.Timer.Add(mail.ExpireTime, mail.Id);
if (sync)
{
//同步客户端
self.Scene.NetworkMessagingComponent.SendInnerRoute(0,new Game2C_HaveMail()
{
Mail = mail.ToMailInfo(),
});
}
await self.Scene.World.DataBase.Save(self);
Log.Info($"MailComponent Add id:{self.Id} mailId:{mail.Id} count:{self.Mails.Count}");
}
public static async FTask<uint> Remove(this MailComponent self, long mailId, bool sync)
{
if (!self.Mails.Remove(mailId, out var mail))
{
return 1;
}
self.Timer.RemoveValue(mail.ExpireTime, mail.Id);
mail.Dispose();
if (sync)
{
//同步客户端
self.Scene.NetworkMessagingComponent.SendInnerRoute(0,new Game2C_MailState()
{
MailState = (int)MailState.Deleted,
MailId = mailId,
});
}
await self.Scene.World.DataBase.Save(self);
Log.Info($"MailComponent Remove id:{self.Id} mailId:{mail.Id} count:{self.Mails.Count}");
return 0;
}
}

View File

@@ -1,22 +0,0 @@
using Fantasy.Entitas.Interface;
namespace NB.Game;
public class MailBoxDestroySystem : DestroySystem<MailBox>
{
protected override void Destroy(MailBox self)
{
if (self.Mail != null)
{
self.Mail.Dispose();
self.Mail = null;
}
self.BoxType = MailBoxType.None;
self.CreateTime = 0;
self.ExpireTime = 0;
self.SendAccountId = 0;
self.AccountId.Clear();
self.Received.Clear();
}
}

View File

@@ -1,53 +0,0 @@
using Fantasy;
using Fantasy.Entitas.Interface;
namespace NB.Game;
public class MailDestroySystem : DestroySystem<Mail>
{
protected override void Destroy(Mail self)
{
self.OwnerId = 0;
self.Title = string.Empty;
self.Content = string.Empty;
self.ExpireTime = 0;
self.CreateTime = 0;
self.State = MailState.None;
self.MailType = MailType.None;
foreach (var item in self.Items)
{
item.Dispose();
}
self.Items.Clear();
}
}
public static class MailSystem
{
public static MailInfo ToMailInfo(this Mail mail)
{
return new MailInfo()
{
Id = mail.Id,
Title = mail.Title,
Content = mail.Content,
ExpireTime = mail.ExpireTime,
CreateTime = mail.CreateTime,
MailState = (int)mail.State,
MailType = (int)mail.MailType,
Items = mail.Items.ToAwardInfo()
};
}
public static List<MailInfo> ToMailInfo(this List<Mail> mails)
{
var list = new List<MailInfo>();
foreach (var mail in mails)
{
list.Add(mail.ToMailInfo());
}
return list;
}
}

View File

@@ -1,55 +0,0 @@
using Fantasy;
using Fantasy.Entitas;
using Fantasy.Helper;
namespace NB.Game;
public static class MailBoxFactory
{
/// <summary>
/// 创建一个邮件箱
/// </summary>
/// <param name="scene"></param>
/// <param name="sendAccountId"></param>
/// <param name="mail"></param>
/// <param name="expireTime"></param>
/// <param name="accountIds"></param>
/// <returns></returns>
public static MailBox Create(Scene scene, long sendAccountId, Mail mail, int expireTime, List<long> accountIds)
{
var mailBox = Entity.Create<MailBox>(scene, true, true);
mailBox.SendAccountId = sendAccountId;
mailBox.Mail = mail;
mailBox.ExpireTime = TimeHelper.Now + expireTime;
mailBox.CreateTime = TimeHelper.Now;
if (accountIds == null || accountIds.Count <= 0)
{
return mailBox;
}
foreach (var accountId in accountIds)
{
mailBox.AccountId.Add(accountId);
}
return mailBox;
}
/// <summary>
/// 创建一个邮件箱
/// </summary>
/// <param name="scene"></param>
/// <param name="sendAccountId"></param>
/// <param name="expireTime"></param>
/// <param name="accountIds"></param>
/// <param name="title"></param>
/// <param name="content"></param>
/// <param name="items"></param>
/// <returns></returns>
public static MailBox Create(Scene scene, long sendAccountId, int expireTime, List<long> accountIds, string title,
string content, List<AwardItem> items = null)
{
var mail = MailFactory.Create(scene, title, content, items);
return Create(scene, sendAccountId, mail, expireTime, accountIds);
}
}

View File

@@ -1,30 +0,0 @@
using Fantasy;
using Fantasy.Entitas;
using Fantasy.Helper;
using Fantasy.Serialize;
namespace NB.Game;
public static class MailFactory
{
private static readonly ISerialize _serializer = SerializerManager.GetSerializer(FantasySerializerType.Bson);
public static Mail Create(Scene scene, string title, string content, List<AwardItem> items = null)
{
var mail = Entity.Create<Mail>(scene, true, true);
mail.Title = title;
mail.Content = content;
mail.State = MailState.Unread;
mail.CreateTime = TimeHelper.Now;
if (items != null && items.Count > 0)
{
foreach (var item in items)
{
mail.Items.Add(_serializer.Clone(item));
}
}
return mail;
}
}

View File

@@ -1,31 +0,0 @@
using Fantasy;
using Fantasy.Async;
namespace NB.Game;
/// <summary>
/// 发送邮件接口
/// </summary>
public static class MailHelper
{
public static async FTask Send(Scene scene, MailBox mailBox)
{
if (mailBox.BoxType == MailBoxType.None)
{
Log.Error("不支持的邮件类型");
return;
}
switch (mailBox.BoxType)
{
case MailBoxType.All:
{
break;
}
case MailBoxType.Specify:
{
break;
}
}
}
}

View File

@@ -103,7 +103,7 @@ public static class PlayerManageComponentSystem
}
}
account.Statistics.LoginTime = TimeHelper.Now;
// account.Statistics.LoginTime = TimeHelper.Now;
await account.Save();

View File

@@ -19,16 +19,16 @@ public sealed class PlayerDestroySystem : DestroySystem<Player>
self.IsVip = false;
self.Head = string.Empty;
self.ItemContainer.Dispose();
self.ItemContainer = null;
self.FishContainer.Dispose();
self.FishContainer = null;
self.Wallet.Dispose();
self.Wallet = null;
self.Vip.Dispose();
self.Vip = null;
self.Statistics.Dispose();
self.Statistics = null;
// self.ItemContainer.Dispose();
// self.ItemContainer = null;
// self.FishContainer.Dispose();
// self.FishContainer = null;
// self.Wallet.Dispose();
// self.Wallet = null;
// self.Vip.Dispose();
// self.Vip = null;
// self.Statistics.Dispose();
// self.Statistics = null;
self.SessionRunTimeId = 0;
}

View File

@@ -12,31 +12,31 @@ public static class PlayerHelper
public static void InitializeChildEntity(this Player self)
{
if (self.ItemContainer == null)
{
self.ItemContainer = Entity.Create<ItemContainer>(self.Scene, true, true);
}
if (self.FishContainer == null)
{
self.FishContainer = Entity.Create<FishContainer>(self.Scene, true, true);
}
if (self.Wallet == null)
{
self.Wallet = Entity.Create<PlayerWallet>(self.Scene, true, true);
}
if (self.Vip == null)
{
self.Vip = Entity.Create<PlayerVip>(self.Scene, true, true);
}
if (self.Statistics == null)
{
self.Statistics = Entity.Create<PlayerStatistics>(self.Scene, true, true);
self.Statistics.LoginTime = self.Statistics.CreateTime = TimeHelper.Now;
}
// if (self.ItemContainer == null)
// {
// self.ItemContainer = Entity.Create<ItemContainer>(self.Scene, true, true);
// }
//
// if (self.FishContainer == null)
// {
// self.FishContainer = Entity.Create<FishContainer>(self.Scene, true, true);
// }
//
// if (self.Wallet == null)
// {
// self.Wallet = Entity.Create<PlayerWallet>(self.Scene, true, true);
// }
//
// if (self.Vip == null)
// {
// self.Vip = Entity.Create<PlayerVip>(self.Scene, true, true);
// }
//
// if (self.Statistics == null)
// {
// self.Statistics = Entity.Create<PlayerStatistics>(self.Scene, true, true);
// self.Statistics.LoginTime = self.Statistics.CreateTime = TimeHelper.Now;
// }
}
public static async FTask SaveImmediately(this Player self)
@@ -156,8 +156,8 @@ public static class PlayerHelper
return new GameAccountInfo()
{
CreateTime = self.Statistics.CreateTime,
LoginTime = self.Statistics.LoginTime
// CreateTime = self.Statistics.CreateTime,
// LoginTime = self.Statistics.LoginTime
};
}
@@ -194,8 +194,8 @@ public static class PlayerHelper
if (self.IsVip)
{
ret.VipInfo = new VipInfo();
ret.VipInfo.OpenTime = self.Vip.GetTime;
ret.VipInfo.ExpirationTime = self.Vip.ExpirationTime;
// ret.VipInfo.OpenTime = self.Vip.GetTime;
// ret.VipInfo.ExpirationTime = self.Vip.ExpirationTime;
}
return ret;