缓存模块

This commit is contained in:
bob
2025-08-15 18:12:04 +08:00
parent d5689258fc
commit 34b25273a7
19 changed files with 275 additions and 79 deletions

View File

@@ -23,6 +23,17 @@ message Game2G_ExitResponse // IRouteResponse
} }
///获取玩家基础信息
message S2G_GetPlayerBasicInfoRequest // IRouteRequest,G2S_GetPlayerBasicInfoResponse
{
repeated int64 IdList = 1; // 查询列表
}
///获取玩家基础信息响应
message G2S_GetPlayerBasicInfoResponse // IRouteResponse
{
repeated RoleSimpleInfo RoleList = 1;
}
///通知游戏服角色进入该聊天服 ///通知游戏服角色进入该聊天服

View File

@@ -115,7 +115,7 @@ message S2C_GetChatRecordResponse // ICustomRouteResponse
} }
////////////// ******** 工会 *******/////////////
message ClubInfo message ClubInfo
{ {

View File

@@ -9,6 +9,8 @@ message RoleBaseInfo
string Country = 3; //国家 string Country = 3; //国家
int32 Level = 4; //等级 int32 Level = 4; //等级
int32 Exp = 5; //当前等级 int32 Exp = 5; //当前等级
bool Vip = 6; //是否vip
VipInfo VipInfo = 7; //vip信息
} }
message KeyValueStringInt64 message KeyValueStringInt64
@@ -51,6 +53,7 @@ message RoleSimpleInfo
string Head = 3; //头像 string Head = 3; //头像
string Country = 4; //国家 string Country = 4; //国家
int32 Level = 5; //等级 int32 Level = 5; //等级
bool Vip = 6; //是否vip
} }
/// VIP信息 /// VIP信息

14
Entity/Def/AppConfig.cs Normal file
View File

@@ -0,0 +1,14 @@
namespace NB;
public class AppConfig
{
/// <summary>
/// 缓存过期检测时间间隔,1小时
/// </summary>
public static long CacheCheckIntervalTime = 360000;
/// <summary>
/// 玩家数据定时落地间隔
/// </summary>
public const long PlayerDataAutoSaveTime = 60000; // 600000;
}

View File

@@ -0,0 +1,42 @@
using Fantasy.Entitas;
using MongoDB.Bson.Serialization.Attributes;
namespace NB.Game;
public class PlayerBasicCache : Entity
{
/// <summary>
/// 昵称
/// </summary>
public string NickName = "";
/// <summary>
/// 头像
/// </summary>
public string Head = "";
/// <summary>
/// 国家
/// </summary>
public string Country = "";
/// <summary>
/// 等级
/// </summary>
public int Level;
/// <summary>
/// 当前经验
/// </summary>
public int Exp;
/// <summary>
/// 是否是vip
/// </summary>
public bool IsVip;
/// <summary>
/// 缓存失效时间
/// </summary>
public long ExpirationTime;
}

View File

@@ -0,0 +1,8 @@
using Fantasy.Entitas;
namespace NB.Game;
public class PlayerBasicCacheManageComponent : Entity
{
public readonly Dictionary<long, PlayerBasicCache> Players = new();
}

View File

@@ -3,30 +3,30 @@ using MongoDB.Bson.Serialization.Attributes;
namespace NB.Game; namespace NB.Game;
public class PlayerBasic : Entity // public class PlayerBasic : Entity
{ // {
/// <summary> // /// <summary>
/// 昵称 // /// 昵称
/// </summary> // /// </summary>
public string NickName; // public string NickName;
//
/// <summary> // /// <summary>
/// 头像 // /// 头像
/// </summary> // /// </summary>
public string Head; // public string Head;
//
/// <summary> // /// <summary>
/// 国家 // /// 国家
/// </summary> // /// </summary>
public string Country; // public string Country;
//
/// <summary> // /// <summary>
/// 等级 // /// 等级
/// </summary> // /// </summary>
public int Level; // public int Level;
//
/// <summary> // /// <summary>
/// 当前经验 // /// 当前经验
/// </summary> // /// </summary>
public int Exp; // public int Exp;
} // }

View File

@@ -5,11 +5,6 @@ namespace NB;
public class PlayerVip : Entity public class PlayerVip : Entity
{ {
/// <summary>
/// 是否是vip
/// </summary>
public bool IsVip;
/// <summary> /// <summary>
/// 获取时间 /// 获取时间
/// </summary> /// </summary>

View File

@@ -7,44 +7,69 @@ namespace NB.Game;
public sealed class Player : Entity public sealed class Player : Entity
{ {
/// <summary> /// <summary>
/// 基础信息 /// 昵称
/// </summary> /// </summary>
public PlayerBasic Basic; [BsonElement("name")] public string NickName = "";
/// <summary>
/// 头像
/// </summary>
[BsonElement("head")] public string Head = "";
/// <summary>
/// 国家
/// </summary>
[BsonElement("ccy")] public string Country = "";
/// <summary>
/// 等级
/// </summary>
[BsonElement("lv")] public int Level;
/// <summary>
/// 当前经验
/// </summary>
[BsonElement("exp")] public int Exp;
/// <summary>
/// 是否是vip
/// </summary>
[BsonElement("vip")] public bool IsVip;
/// <summary> /// <summary>
/// 统计信息 /// 统计信息
/// </summary> /// </summary>
public PlayerStatistics Statistics; [BsonElement("stat")] public PlayerStatistics Statistics;
/// <summary> /// <summary>
/// 角色vip信息 /// 角色vip信息
/// </summary> /// </summary>
public PlayerVip Vip; [BsonElement("vInfo")] public PlayerVip Vip;
/// <summary> /// <summary>
/// 钱包 /// 钱包
/// </summary> /// </summary>
public PlayerWallet Wallet; [BsonElement("wallet")] public PlayerWallet Wallet;
/// <summary> /// <summary>
/// 背包 /// 背包
/// </summary> /// </summary>
public ItemContainer ItemContainer; [BsonElement("bag")] public ItemContainer ItemContainer;
/// <summary> /// <summary>
/// 鱼护 /// 鱼护
/// </summary> /// </summary>
public FishContainer FishContainer; [BsonElement("fish")] public FishContainer FishContainer;
/// <summary> /// <summary>
/// 技能 /// 技能
/// </summary> /// </summary>
public SkillContainer SkillContainer; [BsonElement("skill")] public SkillContainer SkillContainer;
/// <summary> /// <summary>
/// 成就 /// 成就
/// </summary> /// </summary>
public AchievementContainer AchievementContainer; [BsonElement("achievement")] public AchievementContainer AchievementContainer;
[BsonIgnore] public long SessionRunTimeId; [BsonIgnore] public long SessionRunTimeId;

View File

@@ -4,11 +4,6 @@ namespace NB.Game;
public sealed class PlayerManageComponent : Entity public sealed class PlayerManageComponent : Entity
{ {
/// <summary>
/// 10分钟
/// </summary>
public const long AutoSaveTime = 60000; // 600000;
public long AutoSaveTimerId; public long AutoSaveTimerId;
public readonly Dictionary<long, Player> Players = new(); public readonly Dictionary<long, Player> Players = new();

View File

@@ -34,6 +34,8 @@ namespace Fantasy
Country = default; Country = default;
Level = default; Level = default;
Exp = default; Exp = default;
Vip = default;
VipInfo = default;
#if FANTASY_NET || FANTASY_UNITY #if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<RoleBaseInfo>(this); GetScene().MessagePoolComponent.Return<RoleBaseInfo>(this);
#endif #endif
@@ -48,6 +50,10 @@ namespace Fantasy
public int Level { get; set; } public int Level { get; set; }
[ProtoMember(5)] [ProtoMember(5)]
public int Exp { get; set; } public int Exp { get; set; }
[ProtoMember(6)]
public bool Vip { get; set; }
[ProtoMember(7)]
public VipInfo VipInfo { get; set; }
} }
[ProtoContract] [ProtoContract]
public partial class KeyValueStringInt64 : AMessage, IProto public partial class KeyValueStringInt64 : AMessage, IProto
@@ -167,6 +173,7 @@ namespace Fantasy
Head = default; Head = default;
Country = default; Country = default;
Level = default; Level = default;
Vip = default;
#if FANTASY_NET || FANTASY_UNITY #if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<RoleSimpleInfo>(this); GetScene().MessagePoolComponent.Return<RoleSimpleInfo>(this);
#endif #endif
@@ -181,6 +188,8 @@ namespace Fantasy
public string Country { get; set; } public string Country { get; set; }
[ProtoMember(5)] [ProtoMember(5)]
public int Level { get; set; } public int Level { get; set; }
[ProtoMember(6)]
public bool Vip { get; set; }
} }
/// <summary> /// <summary>
/// VIP信息 /// VIP信息

View File

@@ -109,6 +109,53 @@ namespace Fantasy
public uint ErrorCode { get; set; } public uint ErrorCode { get; set; }
} }
/// <summary> /// <summary>
/// 获取玩家基础信息
/// </summary>
[ProtoContract]
public partial class S2G_GetPlayerBasicInfoRequest : AMessage, IRouteRequest, IProto
{
public static S2G_GetPlayerBasicInfoRequest Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<S2G_GetPlayerBasicInfoRequest>();
}
public override void Dispose()
{
IdList.Clear();
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<S2G_GetPlayerBasicInfoRequest>(this);
#endif
}
[ProtoIgnore]
public G2S_GetPlayerBasicInfoResponse ResponseType { get; set; }
public uint OpCode() { return InnerOpcode.S2G_GetPlayerBasicInfoRequest; }
[ProtoMember(1)]
public List<long> IdList = new List<long>();
}
/// <summary>
/// 获取玩家基础信息响应
/// </summary>
[ProtoContract]
public partial class G2S_GetPlayerBasicInfoResponse : AMessage, IRouteResponse, IProto
{
public static G2S_GetPlayerBasicInfoResponse Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<G2S_GetPlayerBasicInfoResponse>();
}
public override void Dispose()
{
ErrorCode = default;
RoleList.Clear();
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<G2S_GetPlayerBasicInfoResponse>(this);
#endif
}
public uint OpCode() { return InnerOpcode.G2S_GetPlayerBasicInfoResponse; }
[ProtoMember(1)]
public List<RoleSimpleInfo> RoleList = new List<RoleSimpleInfo>();
[ProtoMember(2)]
public uint ErrorCode { get; set; }
}
/// <summary>
/// 通知游戏服角色进入该聊天服 /// 通知游戏服角色进入该聊天服
/// </summary> /// </summary>
[ProtoContract] [ProtoContract]

View File

@@ -6,10 +6,12 @@ namespace Fantasy
public const uint Game2G_EnterResponse = 1207969553; public const uint Game2G_EnterResponse = 1207969553;
public const uint G2Game_ExitRequest = 1073751826; public const uint G2Game_ExitRequest = 1073751826;
public const uint Game2G_ExitResponse = 1207969554; public const uint Game2G_ExitResponse = 1207969554;
public const uint G2S_EnterRequest = 1073751827; public const uint S2G_GetPlayerBasicInfoRequest = 1073751827;
public const uint S2G_EnterResponse = 1207969555; public const uint G2S_GetPlayerBasicInfoResponse = 1207969555;
public const uint G2S_ExitRequest = 1073751828; public const uint G2S_EnterRequest = 1073751828;
public const uint S2G_ExitResponse = 1207969556; public const uint S2G_EnterResponse = 1207969556;
public const uint G2S_ExitRequest = 1073751829;
public const uint S2G_ExitResponse = 1207969557;
public const uint S2G_ChatMessage = 939534097; public const uint S2G_ChatMessage = 939534097;
public const uint Club2Chat_CreateChannel = 939534098; public const uint Club2Chat_CreateChannel = 939534098;
} }

View File

@@ -441,6 +441,9 @@ namespace Fantasy
[ProtoMember(2)] [ProtoMember(2)]
public uint ErrorCode { get; set; } public uint ErrorCode { get; set; }
} }
/// <summary>
/// /////////// ******** 工会 *******/////////////
/// </summary>
[ProtoContract] [ProtoContract]
public partial class ClubInfo : AMessage, IProto public partial class ClubInfo : AMessage, IProto
{ {

View File

@@ -0,0 +1,16 @@
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

@@ -59,11 +59,11 @@ public static class PlayerManageComponentSystem
account = PlayerFactory.Create(scene, accountId); account = PlayerFactory.Create(scene, accountId);
account.Basic.Level = 99; account.Level = 99;
account.Basic.NickName = "王麻子"; account.NickName = "王麻子";
account.Basic.Country = "cn"; account.Country = "cn";
account.Basic.Exp = 999; account.Exp = 999;
account.Basic.Head = "xxx.png"; account.Head = "xxx.png";
// for (int i = 0; i < 500; i++) // for (int i = 0; i < 500; i++)
// { // {

View File

@@ -12,8 +12,13 @@ public sealed class PlayerDestroySystem : DestroySystem<Player>
{ {
protected override void Destroy(Player self) protected override void Destroy(Player self)
{ {
self.Basic.Dispose(); self.NickName = string.Empty;
self.Basic = null; self.Level = 0;
self.Exp = 0;
self.Country = string.Empty;
self.IsVip = false;
self.Head = string.Empty;
self.ItemContainer.Dispose(); self.ItemContainer.Dispose();
self.ItemContainer = null; self.ItemContainer = null;
self.FishContainer.Dispose(); self.FishContainer.Dispose();

View File

@@ -12,11 +12,6 @@ public static class PlayerHelper
public static void InitializeChildEntity(this Player self) public static void InitializeChildEntity(this Player self)
{ {
if (self.Basic == null)
{
self.Basic = Entity.Create<PlayerBasic>(self.Scene, true, true);
}
if (self.ItemContainer == null) if (self.ItemContainer == null)
{ {
self.ItemContainer = Entity.Create<ItemContainer>(self.Scene, true, true); self.ItemContainer = Entity.Create<ItemContainer>(self.Scene, true, true);
@@ -54,7 +49,7 @@ public static class PlayerHelper
public static async FTask Save(this Player self) public static async FTask Save(this Player self)
{ {
self.NeedSave = true; self.NeedSave = true;
self.NeedSaveTime = TimeHelper.Now + PlayerManageComponent.AutoSaveTime; self.NeedSaveTime = TimeHelper.Now + AppConfig.PlayerDataAutoSaveTime;
//先立马保存,后续做缓存 //先立马保存,后续做缓存
await self.Scene.World.DataBase.Save(self); await self.Scene.World.DataBase.Save(self);
} }
@@ -171,10 +166,11 @@ public static class PlayerHelper
return new RoleSimpleInfo() return new RoleSimpleInfo()
{ {
RoleId = self.Id, RoleId = self.Id,
NickName = self.Basic.NickName, NickName = self.NickName,
Head = self.Basic.Head, Head = self.Head,
Country = self.Basic.Country, Country = self.Country,
Level = self.Basic.Level Level = self.Level,
Vip = self.IsVip,
}; };
} }
@@ -187,14 +183,22 @@ public static class PlayerHelper
public static RoleBaseInfo GetRoleBaseInfo(this Player self) public static RoleBaseInfo GetRoleBaseInfo(this Player self)
{ {
return new RoleBaseInfo() var ret = new RoleBaseInfo()
{ {
NickName = self.Basic.NickName, NickName = self.NickName,
Head = self.Basic.Head, Head = self.Head,
Country = self.Basic.Country, Country = self.Country,
Level = self.Basic.Level, Level = self.Level,
Exp = self.Basic.Exp, Exp = self.Exp,
}; };
if (self.IsVip)
{
ret.VipInfo = new VipInfo();
ret.VipInfo.OpenTime = self.Vip.GetTime;
ret.VipInfo.ExpirationTime = self.Vip.ExpirationTime;
}
return ret;
} }
#endregion #endregion

View File

@@ -4,6 +4,7 @@ using Fantasy.Entitas;
using Fantasy.Event; using Fantasy.Event;
using Fantasy.Helper; using Fantasy.Helper;
using Fantasy.Serialize; using Fantasy.Serialize;
using NB.Game;
using ProtoBuf; using ProtoBuf;
namespace NB; namespace NB;
@@ -28,7 +29,6 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem<OnCreateScene>
/// <returns>A task representing the asynchronous operation.</returns> /// <returns>A task representing the asynchronous operation.</returns>
protected override async FTask Handler(OnCreateScene self) protected override async FTask Handler(OnCreateScene self)
{ {
// var epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000; // var epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000;
// //
// { // {
@@ -53,7 +53,7 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem<OnCreateScene>
{ {
var subSceneTestComponent = scene.AddComponent<SubSceneTestComponent>(); var subSceneTestComponent = scene.AddComponent<SubSceneTestComponent>();
Log.Debug("增加了SubSceneTestComponent"); Log.Debug("增加了SubSceneTestComponent");
scene.EntityComponent.CustomSystem(subSceneTestComponent,CustomSystemType.RunSystem); scene.EntityComponent.CustomSystem(subSceneTestComponent, CustomSystemType.RunSystem);
break; break;
} }
case SceneType.Addressable: case SceneType.Addressable:
@@ -71,6 +71,23 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem<OnCreateScene>
{ {
break; break;
} }
case SceneType.Game:
{
// for (int i = 0; i < 100; i++)
// {
// var accountId = scene.EntityIdFactory.Create;
// var account = PlayerFactory.Create(scene, accountId);
//
// account.Level = 99;
// account.NickName = $"测试号{i + 1}";
// account.Country = "cn";
// account.Exp = 999;
// account.Head = "xxx.png";
// await account.Save();
// }
//
break;
}
case SceneType.Gate: case SceneType.Gate:
{ {
// var tasks = new List<FTask>(2000); // var tasks = new List<FTask>(2000);