缓存模块

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
{

View File

@@ -9,6 +9,8 @@ message RoleBaseInfo
string Country = 3; //国家
int32 Level = 4; //等级
int32 Exp = 5; //当前等级
bool Vip = 6; //是否vip
VipInfo VipInfo = 7; //vip信息
}
message KeyValueStringInt64
@@ -51,6 +53,7 @@ message RoleSimpleInfo
string Head = 3; //头像
string Country = 4; //国家
int32 Level = 5; //等级
bool Vip = 6; //是否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;
public class PlayerBasic : 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;
}
// public class PlayerBasic : 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;
// }

View File

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

View File

@@ -7,44 +7,69 @@ namespace NB.Game;
public sealed class Player : Entity
{
/// <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>
public PlayerStatistics Statistics;
[BsonElement("stat")] public PlayerStatistics Statistics;
/// <summary>
/// 角色vip信息
/// </summary>
public PlayerVip Vip;
[BsonElement("vInfo")] public PlayerVip Vip;
/// <summary>
/// 钱包
/// </summary>
public PlayerWallet Wallet;
[BsonElement("wallet")] public PlayerWallet Wallet;
/// <summary>
/// 背包
/// </summary>
public ItemContainer ItemContainer;
[BsonElement("bag")] public ItemContainer ItemContainer;
/// <summary>
/// 鱼护
/// </summary>
public FishContainer FishContainer;
[BsonElement("fish")] public FishContainer FishContainer;
/// <summary>
/// 技能
/// </summary>
public SkillContainer SkillContainer;
[BsonElement("skill")] public SkillContainer SkillContainer;
/// <summary>
/// 成就
/// </summary>
public AchievementContainer AchievementContainer;
[BsonElement("achievement")] public AchievementContainer AchievementContainer;
[BsonIgnore] public long SessionRunTimeId;

View File

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

View File

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

View File

@@ -109,6 +109,53 @@ namespace Fantasy
public uint ErrorCode { get; set; }
}
/// <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>
[ProtoContract]

View File

@@ -6,10 +6,12 @@ namespace Fantasy
public const uint Game2G_EnterResponse = 1207969553;
public const uint G2Game_ExitRequest = 1073751826;
public const uint Game2G_ExitResponse = 1207969554;
public const uint G2S_EnterRequest = 1073751827;
public const uint S2G_EnterResponse = 1207969555;
public const uint G2S_ExitRequest = 1073751828;
public const uint S2G_ExitResponse = 1207969556;
public const uint S2G_GetPlayerBasicInfoRequest = 1073751827;
public const uint G2S_GetPlayerBasicInfoResponse = 1207969555;
public const uint G2S_EnterRequest = 1073751828;
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 Club2Chat_CreateChannel = 939534098;
}

View File

@@ -441,6 +441,9 @@ namespace Fantasy
[ProtoMember(2)]
public uint ErrorCode { get; set; }
}
/// <summary>
/// /////////// ******** 工会 *******/////////////
/// </summary>
[ProtoContract]
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.Basic.Level = 99;
account.Basic.NickName = "王麻子";
account.Basic.Country = "cn";
account.Basic.Exp = 999;
account.Basic.Head = "xxx.png";
account.Level = 99;
account.NickName = "王麻子";
account.Country = "cn";
account.Exp = 999;
account.Head = "xxx.png";
// 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)
{
self.Basic.Dispose();
self.Basic = null;
self.NickName = string.Empty;
self.Level = 0;
self.Exp = 0;
self.Country = string.Empty;
self.IsVip = false;
self.Head = string.Empty;
self.ItemContainer.Dispose();
self.ItemContainer = null;
self.FishContainer.Dispose();

View File

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

View File

@@ -4,6 +4,7 @@ using Fantasy.Entitas;
using Fantasy.Event;
using Fantasy.Helper;
using Fantasy.Serialize;
using NB.Game;
using ProtoBuf;
namespace NB;
@@ -28,7 +29,6 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem<OnCreateScene>
/// <returns>A task representing the asynchronous operation.</returns>
protected override async FTask Handler(OnCreateScene self)
{
// var epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000;
//
// {
@@ -44,16 +44,16 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem<OnCreateScene>
// var time = (uint)((now - epochThisYear) / 1000);
// Log.Debug($"time = {time} now = {now} epochThisYear = {epochThisYear}");
// }
var scene = self.Scene;
switch (scene.SceneType)
{
case 6666:
{
var subSceneTestComponent = scene.AddComponent<SubSceneTestComponent>();
Log.Debug("增加了SubSceneTestComponent");
scene.EntityComponent.CustomSystem(subSceneTestComponent,CustomSystemType.RunSystem);
scene.EntityComponent.CustomSystem(subSceneTestComponent, CustomSystemType.RunSystem);
break;
}
case SceneType.Addressable:
@@ -71,6 +71,23 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem<OnCreateScene>
{
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:
{
// var tasks = new List<FTask>(2000);
@@ -92,7 +109,7 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem<OnCreateScene>
// }
// await FTask.WaitAll(tasks);
// }
// 执行自定义系统
var testCustomSystemComponent = scene.AddComponent<TestCustomSystemComponent>();
scene.EntityComponent.CustomSystem(testCustomSystemComponent, CustomSystemType.RunSystem);