diff --git a/Entity/Entity.csproj b/Entity/Entity.csproj
index be2ab6d..a23094a 100644
--- a/Entity/Entity.csproj
+++ b/Entity/Entity.csproj
@@ -29,7 +29,6 @@
-
diff --git a/Entity/Game/Container/ContainerComponent.cs b/Entity/Game/Container/ContainerComponent.cs
deleted file mode 100644
index 92b7ea9..0000000
--- a/Entity/Game/Container/ContainerComponent.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using Fantasy.Entitas;
-
-namespace NB;
-
-public enum ContainerType : uint
-{
- ///
- /// 背包
- ///
- Bag,
-
- ///
- /// 鱼护
- ///
- FishBag,
-}
-
-///
-/// 物品容器组件
-///
-public class ContainerComponent : Entity
-{
-}
\ No newline at end of file
diff --git a/Entity/Game/Fish/Fish.cs b/Entity/Game/Fish/Fish.cs
index a15edfe..08c7746 100644
--- a/Entity/Game/Fish/Fish.cs
+++ b/Entity/Game/Fish/Fish.cs
@@ -24,4 +24,14 @@ public class Fish : Entity
/// 失效时间
///
[BsonElement("et")] public long ExpirationTime;
+
+ ///
+ /// 获取地图
+ ///
+ [BsonElement("map")] public int Map;
+
+ ///
+ /// 物品所属的容器
+ ///
+ [BsonIgnore] FishContainer Container;
}
\ No newline at end of file
diff --git a/Entity/Game/Fish/FishContainer.cs b/Entity/Game/Fish/FishContainer.cs
new file mode 100644
index 0000000..1dd3112
--- /dev/null
+++ b/Entity/Game/Fish/FishContainer.cs
@@ -0,0 +1,19 @@
+using Fantasy.Entitas;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Bson.Serialization.Options;
+
+namespace NB.Game;
+
+public class FishContainer : Entity
+{
+ ///
+ /// 最大格子数量
+ ///
+ public int CellCountMax;
+
+ ///
+ /// 容器内的物品
+ ///
+ [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
+ public Dictionary Fishes = new Dictionary();
+}
\ No newline at end of file
diff --git a/Entity/Game/Item/Item.cs b/Entity/Game/Item/Item.cs
index b6e0be6..e394885 100644
--- a/Entity/Game/Item/Item.cs
+++ b/Entity/Game/Item/Item.cs
@@ -11,8 +11,6 @@ public enum ItemType
Fish,
}
-
-
public class Item : Entity
{
///
@@ -43,5 +41,10 @@ public class Item : Entity
///
/// 耐久度
///
- [BsonElement("a")] public int Abrasion;
+ [BsonElement("abr")] public int Abrasion;
+
+ ///
+ /// 物品所属的容器
+ ///
+ [BsonIgnore] ItemContainer Container;
}
\ No newline at end of file
diff --git a/Entity/Game/Container/Container.cs b/Entity/Game/Item/ItemContainer.cs
similarity index 66%
rename from Entity/Game/Container/Container.cs
rename to Entity/Game/Item/ItemContainer.cs
index 7ec1262..b0713e7 100644
--- a/Entity/Game/Container/Container.cs
+++ b/Entity/Game/Item/ItemContainer.cs
@@ -6,34 +6,20 @@ using NB.Game;
namespace NB;
-public sealed class Container : Entity
+public sealed class ItemContainer : Entity
{
- ///
- /// 可用格子数量
- ///
- public int CellCount;
-
///
/// 最大格子数量
///
public int CellCountMax;
-
- ///
- /// 当前已经使用格子数量
- ///
- public int CurrentCellCount;
-
+
///
/// 容器内的物品
///
[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
public Dictionary Items = new Dictionary();
-
- ///
- /// 容器内物品,按格子进行分组
- ///
- [BsonIgnore] public Dictionary ItemsByCell = new Dictionary();
-
+
+
///
/// 按物品id分组
///
diff --git a/Entity/Game/Mission/Mission.cs b/Entity/Game/Mission/Mission.cs
new file mode 100644
index 0000000..76c1a23
--- /dev/null
+++ b/Entity/Game/Mission/Mission.cs
@@ -0,0 +1,10 @@
+using Fantasy.Entitas;
+
+namespace NB.Game;
+
+///
+/// 角色任务
+///
+public class Mission : Entity
+{
+}
\ No newline at end of file
diff --git a/Entity/Game/Player/Child/PlayerBasic.cs b/Entity/Game/Player/Child/PlayerBasic.cs
new file mode 100644
index 0000000..71017db
--- /dev/null
+++ b/Entity/Game/Player/Child/PlayerBasic.cs
@@ -0,0 +1,32 @@
+using Fantasy.Entitas;
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace NB.Game;
+
+public class PlayerBasic : Entity
+{
+ ///
+ /// 昵称
+ ///
+ public string NickName;
+
+ ///
+ /// 头像
+ ///
+ public string Head;
+
+ ///
+ /// 国家
+ ///
+ public string Country;
+
+ ///
+ /// 等级
+ ///
+ public int Level;
+
+ ///
+ /// 当前经验
+ ///
+ public int Exp;
+}
\ No newline at end of file
diff --git a/Entity/Game/Player/Child/PlayerSlot.cs b/Entity/Game/Player/Child/PlayerSlot.cs
new file mode 100644
index 0000000..525dda0
--- /dev/null
+++ b/Entity/Game/Player/Child/PlayerSlot.cs
@@ -0,0 +1,34 @@
+using Fantasy.Entitas;
+
+namespace NB.Game;
+
+public enum SlotType
+{
+ None,
+
+ ///
+ /// 物品
+ ///
+ Item,
+
+ ///
+ /// 钓组
+ ///
+ Tackle
+}
+
+///
+/// 快速使用插槽
+///
+public class PlayerSlot : Entity
+{
+ ///
+ /// 插槽类型
+ ///
+ public SlotType SlotType;
+
+ ///
+ /// 绑定快速使用的id
+ ///
+ public long BindId;
+}
\ No newline at end of file
diff --git a/Entity/Game/Player/Child/PlayerStatistics.cs b/Entity/Game/Player/Child/PlayerStatistics.cs
index c1aad96..08057f6 100644
--- a/Entity/Game/Player/Child/PlayerStatistics.cs
+++ b/Entity/Game/Player/Child/PlayerStatistics.cs
@@ -1,4 +1,5 @@
using Fantasy.Entitas;
+using MongoDB.Bson.Serialization.Attributes;
namespace NB;
diff --git a/Entity/Game/Player/Child/PlayerDayFlags.cs b/Entity/Game/Player/Child/PlayerTackle.cs
similarity index 56%
rename from Entity/Game/Player/Child/PlayerDayFlags.cs
rename to Entity/Game/Player/Child/PlayerTackle.cs
index 22b612a..4b2d85b 100644
--- a/Entity/Game/Player/Child/PlayerDayFlags.cs
+++ b/Entity/Game/Player/Child/PlayerTackle.cs
@@ -3,8 +3,9 @@
namespace NB;
///
-/// 角色状态标志量
+/// 玩家钓组
///
-public class PlayerDayFlags
+public class PlayerTackle : Entity
{
+
}
\ No newline at end of file
diff --git a/Entity/Game/Player/Child/PlayerVip.cs b/Entity/Game/Player/Child/PlayerVip.cs
index 7deddfe..3124a60 100644
--- a/Entity/Game/Player/Child/PlayerVip.cs
+++ b/Entity/Game/Player/Child/PlayerVip.cs
@@ -1,6 +1,9 @@
-namespace NB;
+using Fantasy.Entitas;
+using MongoDB.Bson.Serialization.Attributes;
-public class PlayerVip
+namespace NB;
+
+public class PlayerVip : Entity
{
///
/// 是否是vip
diff --git a/Entity/Game/Player/Child/PlayerWallet.cs b/Entity/Game/Player/Child/PlayerWallet.cs
new file mode 100644
index 0000000..c4ee134
--- /dev/null
+++ b/Entity/Game/Player/Child/PlayerWallet.cs
@@ -0,0 +1,27 @@
+using Fantasy.Entitas;
+using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Bson.Serialization.Options;
+
+namespace NB.Game;
+
+///
+/// 用户钱包
+///
+public class PlayerWallet : Entity
+{
+ ///
+ /// 余额
+ ///
+ public int Money;
+
+ ///
+ /// 金币
+ ///
+ public int Gold;
+
+ ///
+ /// 其他货币
+ ///
+ [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
+ public Dictionary Other = new();
+}
\ No newline at end of file
diff --git a/Entity/Game/Player/Player.cs b/Entity/Game/Player/Player.cs
index a3bac85..9244c58 100644
--- a/Entity/Game/Player/Player.cs
+++ b/Entity/Game/Player/Player.cs
@@ -6,72 +6,35 @@ namespace NB.Game;
public sealed class Player : Entity
{
- [BsonElement("ct")] public long CreateTime;
- [BsonElement("lt")] public long LoginTime;
+ ///
+ /// 基础信息
+ ///
+ public PlayerBasic Basic;
///
- /// 昵称
+ /// 统计信息
///
- [BsonElement("name")] public string NickName;
+ public PlayerStatistics Statistics;
///
- /// 头像
+ /// 角色vip信息
///
- public string Head;
+ public PlayerVip Vip;
///
- /// 国家
+ /// 钱包
///
- public string Country;
+ public PlayerWallet Wallet;
///
- /// 等级
+ /// 背包
///
- [BsonElement("lv")] public int Level;
-
- ///
- /// 当前经验
- ///
- public int Exp;
-
- ///
- /// 余额
- ///
- public int Money;
-
- ///
- /// 金币
- ///
- public int Gold;
-
- // public PlayerStatistics Statistics = new PlayerStatistics();
- // public PlayerDayFlags DayFlags = new PlayerDayFlags();
- // public PlayerVip Vip = new PlayerVip();
-
-
- ///
- /// 其他货币
- ///
- [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
- public Dictionary Currency = new();
-
- ///
- /// 插槽
- ///
- [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
- public Dictionary Slots = new Dictionary();
-
- ///
- /// 背包物品
- ///
- [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
- public Dictionary Items = new Dictionary();
+ public ItemContainer ItemContainer;
///
/// 鱼护
///
- [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
- public Dictionary Fishes = new Dictionary();
+ public FishContainer FishContainer;
[BsonIgnore] public long SessionRunTimeId;
@@ -82,7 +45,7 @@ public sealed class Player : Entity
[BsonIgnore] public bool NeedSave;
///
- /// 最后保存时间
+ /// 需要保存数据库时间
///
- [BsonIgnore] public long LastSaveTime;
+ [BsonIgnore] public long NeedSaveTime;
}
\ No newline at end of file
diff --git a/Entity/Game/Player/PlayerAutoSaveComponent.cs b/Entity/Game/Player/PlayerAutoSaveComponent.cs
deleted file mode 100644
index 86b02e5..0000000
--- a/Entity/Game/Player/PlayerAutoSaveComponent.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Fantasy.Entitas;
-
-namespace NB.Game;
-
-public class PlayerAutoSaveComponent : Entity
-{
-
-}
\ No newline at end of file
diff --git a/Entity/Game/Player/PlayerManageComponent.cs b/Entity/Game/Player/PlayerManageComponent.cs
index 1965dca..99bbac4 100644
--- a/Entity/Game/Player/PlayerManageComponent.cs
+++ b/Entity/Game/Player/PlayerManageComponent.cs
@@ -4,5 +4,17 @@ namespace NB.Game;
public sealed class PlayerManageComponent : Entity
{
+ ///
+ /// 10分钟
+ ///
+ public const long AutoSaveTime = 60000; // 600000;
+
+ public long AutoSaveTimerId;
+
public readonly Dictionary Players = new();
+
+ ///
+ /// 需要保存到数据库的玩家
+ ///
+ public readonly HashSet NeedSavePlayer = new();
}
\ No newline at end of file
diff --git a/Entity/Game/Skill/Skill.cs b/Entity/Game/Skill/Skill.cs
new file mode 100644
index 0000000..09d0b5d
--- /dev/null
+++ b/Entity/Game/Skill/Skill.cs
@@ -0,0 +1,11 @@
+using Fantasy.Entitas;
+
+namespace NB.Game;
+
+///
+/// 角色技能
+///
+public class Skill : Entity
+{
+
+}
\ No newline at end of file
diff --git a/Hotfix/Game/Handler/G2Game_EnterRequestHandler.cs b/Hotfix/Game/Handler/G2Game_EnterRequestHandler.cs
index fd66e40..5aa93d1 100644
--- a/Hotfix/Game/Handler/G2Game_EnterRequestHandler.cs
+++ b/Hotfix/Game/Handler/G2Game_EnterRequestHandler.cs
@@ -16,89 +16,13 @@ public class G2Game_EnterRequestHandler : RouteRPC();
- Log.Debug("检查账号是否在缓存中");
- if (!gameAccountManageComponent.TryGet(accountId, out var account))
- {
- // 首先要先到数据库中查询是否有这个账号
- account = await PlayerHelper.LoadDataBase(scene, accountId);
- // 如果有的话,就直接加入在缓存中就可以了
- if (account == null)
- {
- Log.Debug("检查到账号没有在数据库中,需要创建一个新的账号并且保存到数据库中");
- // 如果没有,就要创建一个新的并且保存到数据库。
- // 如果不存在,表示这是一个新的账号,需要创建一下这个账号。
- account = await PlayerFactory.Create(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- (scene, true, true);
- account.Items.Add(item.Id, item);
- }
-
- for (int i = 0; i < 500; i++)
- {
- var item = Entity.Create(scene, true, true);
- account.Fishes.Add(item.Id, item);
- }
- // account.Items
-
- account.NeedSave = true;
-
- await account.SaveDataBase();
- }
- else
- {
- Log.Debug("检查到账号在数据库中");
- }
-
- Log.Debug("把当前账号添加到缓存中");
- // 把创建完成的Account放入到缓存中
- gameAccountManageComponent.Add(account);
- }
- else
- {
- Log.Debug("检测到当前账号已经在缓存中了");
- // 如果有延迟下线的计划任务,那就先取消一下。
- account.CancelTimeout();
- // 如果在Gate的缓存中已经存在了该账号那只能以下几种可能:
- // 1、同一客户端发送了重复登录的请求数据。
- // 2、客户端经历的断线然后又重新连接到这个服务器上了(断线重连)。
- // 3、多个客户端同时登录了这个账号(顶号)。
-
- if (request.GateRouteId == account.SessionRunTimeId)
- {
- // 如果执行到这里,说明是客户端发送了多次登录的请求,这样的情况下,直接返回就可以了,不需要做任何操作。
- return;
- }
- }
-
- account.LoginTime = TimeHelper.Now;
+ var account = await gameAccountManageComponent.Online(scene, request.AccountId, request.GateRouteId);
response.RoleRouteId = account.RuntimeId;
- if (account.GetComponent() == null)
- {
- var mailComponent = await scene.World.DataBase.Query(account.Id, true);
- if (mailComponent == null)
- {
- //如果没有邮件组件
- account.AddComponent();
- }
- else
- {
- account.AddComponent(mailComponent);
- }
- }
-
await FTask.CompletedTask;
}
}
\ No newline at end of file
diff --git a/Hotfix/Game/Handler/ItemFactory.cs b/Hotfix/Game/Item/Helper/ItemFactory.cs
similarity index 100%
rename from Hotfix/Game/Handler/ItemFactory.cs
rename to Hotfix/Game/Item/Helper/ItemFactory.cs
diff --git a/Hotfix/Game/Container/ContainerSystem.cs b/Hotfix/Game/Item/ItemContainerSystem.cs
similarity index 59%
rename from Hotfix/Game/Container/ContainerSystem.cs
rename to Hotfix/Game/Item/ItemContainerSystem.cs
index 1c546a7..97ea7e4 100644
--- a/Hotfix/Game/Container/ContainerSystem.cs
+++ b/Hotfix/Game/Item/ItemContainerSystem.cs
@@ -2,13 +2,11 @@
namespace NB.Game;
-public sealed class ContainerDestroySystem : DestroySystem
+public sealed class ItemContainerDestroySystem : DestroySystem
{
- protected override void Destroy(Container self)
+ protected override void Destroy(ItemContainer self)
{
- self.CellCount = 0;
self.CellCountMax = 0;
- self.CurrentCellCount = 0;
foreach (var (_, item) in self.Items)
{
@@ -16,13 +14,12 @@ public sealed class ContainerDestroySystem : DestroySystem
}
self.Items.Clear();
- self.ItemsByCell.Clear();
self.ItemsByConfigId.Clear();
self.ItemsByType.Clear();
}
}
-public static class ContainerSystem
+public static class ItemContainerSystem
{
#region Get
@@ -33,30 +30,18 @@ public static class ContainerSystem
///
///
///
- public static bool GetItemById(this Container self, uint id, out Item item)
+ public static bool GetItemById(this ItemContainer self, uint id, out Item item)
{
return self.Items.TryGetValue(id, out item);
}
- ///
- /// 通过格子位置获取物品
- ///
- ///
- ///
- ///
- ///
- public static bool GetItemByCell(this Container self, uint cell, out Item item)
- {
- return self.ItemsByCell.TryGetValue(cell, out item);
- }
-
///
/// 通过配置id获取物品
///
///
///
///
- public static void GetItemByConfigId(this Container self, uint configId, List
- items)
+ public static void GetItemByConfigId(this ItemContainer self, uint configId, List
- items)
{
if (!self.ItemsByConfigId.TryGetValue(configId, out var itemList))
{
@@ -72,7 +57,7 @@ public static class ContainerSystem
///
///
///
- public static void GetItemByType(this Container self, ItemType type, List
- items)
+ public static void GetItemByType(this ItemContainer self, ItemType type, List
- items)
{
if (!self.ItemsByType.TryGetValue((uint)type, out var itemList))
{
diff --git a/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs b/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs
new file mode 100644
index 0000000..5b99bee
--- /dev/null
+++ b/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs
@@ -0,0 +1,178 @@
+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
+{
+ protected override void Awake(PlayerManageComponent self)
+ {
+ self.AutoSaveTimerId =
+ self.Scene.TimerComponent.Net.RepeatedTimer(1000 * 60, () => { _ = self.CheckAutoSave(); });
+ }
+}
+
+public sealed class PlayerManageComponentDestroySystem : DestroySystem
+{
+ 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 上线下线
+
+ ///
+ /// 玩家上线
+ ///
+ ///
+ ///
+ ///
+ public static async FTask Online(this PlayerManageComponent self, Scene scene, long accountId,
+ long gateRouteId)
+ {
+ Log.Debug("检查账号是否在缓存中");
+ if (!self.TryGet(accountId, out var account))
+ {
+ // 首先要先到数据库中查询是否有这个账号
+ account = await PlayerHelper.LoadDataBase(scene, accountId);
+ // 如果有的话,就直接加入在缓存中就可以了
+ if (account == null)
+ {
+ Log.Debug("检查到账号没有在数据库中,需要创建一个新的账号并且保存到数据库中");
+ // 如果没有,就要创建一个新的并且保存到数据库。
+ // 如果不存在,表示这是一个新的账号,需要创建一下这个账号。
+ 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";
+
+ // for (int i = 0; i < 500; i++)
+ // {
+ // var item = Entity.Create
- (scene, true, true);
+ // account.ItemContainer.Add(item.Id, item);
+ // }
+ //
+ // for (int i = 0; i < 500; i++)
+ // {
+ // var item = Entity.Create(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;
+
+
+ if (account.GetComponent() == null)
+ {
+ var mailComponent = await scene.World.DataBase.Query(account.Id, true);
+ if (mailComponent == null)
+ {
+ //如果没有邮件组件
+ account.AddComponent();
+ }
+ else
+ {
+ account.AddComponent(mailComponent);
+ }
+ }
+
+ await account.Save();
+
+ return account;
+ }
+
+ #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
+}
\ No newline at end of file
diff --git a/Hotfix/Game/Player/Entity/PlayerSystem.cs b/Hotfix/Game/Player/Entity/PlayerSystem.cs
new file mode 100644
index 0000000..e3dbff5
--- /dev/null
+++ b/Hotfix/Game/Player/Entity/PlayerSystem.cs
@@ -0,0 +1,35 @@
+using Fantasy;
+using Fantasy.Async;
+using Fantasy.Entitas;
+using Fantasy.Entitas.Interface;
+using Fantasy.Helper;
+
+#pragma warning disable CS8625 // 无法将 null 字面量转换为非 null 的引用类型。
+
+namespace NB.Game;
+
+public sealed class PlayerDestroySystem : DestroySystem
+{
+ protected override void Destroy(Player self)
+ {
+ self.Basic.Dispose();
+ self.Basic = 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;
+ }
+}
+
+public static class PlayerSystem
+{
+
+}
\ No newline at end of file
diff --git a/Hotfix/Game/System/Player/PlayerFactory.cs b/Hotfix/Game/Player/Helper/PlayerFactory.cs
similarity index 54%
rename from Hotfix/Game/System/Player/PlayerFactory.cs
rename to Hotfix/Game/Player/Helper/PlayerFactory.cs
index 019f7d4..3d2a611 100644
--- a/Hotfix/Game/System/Player/PlayerFactory.cs
+++ b/Hotfix/Game/Player/Helper/PlayerFactory.cs
@@ -15,17 +15,10 @@ public static class PlayerFactory
/// ToKen令牌传递过来的aId
/// 是否在创建的过程中保存到数据库
///
- public static async FTask Create(Scene scene, long aId, bool isSaveDataBase = true)
+ public static Player Create(Scene scene, long aId)
{
- var gameAccount = Entity.Create(scene, aId, false, false);
- gameAccount.LoginTime = gameAccount.CreateTime = TimeHelper.Now;
-
-
- if (isSaveDataBase)
- {
- await gameAccount.SaveDataBase();
- }
-
- return gameAccount;
+ var player = Entity.Create(scene, aId, true, true);
+ player.InitializeChildEntity();
+ return player;
}
}
\ No newline at end of file
diff --git a/Hotfix/Game/System/Player/PlayerHelper.cs b/Hotfix/Game/Player/Helper/PlayerHelper.cs
similarity index 70%
rename from Hotfix/Game/System/Player/PlayerHelper.cs
rename to Hotfix/Game/Player/Helper/PlayerHelper.cs
index 8d64f06..fd5aade 100644
--- a/Hotfix/Game/System/Player/PlayerHelper.cs
+++ b/Hotfix/Game/Player/Helper/PlayerHelper.cs
@@ -1,11 +1,63 @@
using Fantasy;
using Fantasy.Async;
+using Fantasy.Entitas;
+using Fantasy.Helper;
using Fantasy.Network;
namespace NB.Game;
public static class PlayerHelper
{
+ public static void InitializeChildEntity(this Player self)
+ {
+ if (self.Basic == null)
+ {
+ self.Basic = Entity.Create(self.Scene, true, true);
+ }
+
+ if (self.ItemContainer == null)
+ {
+ self.ItemContainer = Entity.Create(self.Scene, true, true);
+ }
+
+ if (self.FishContainer == null)
+ {
+ self.FishContainer = Entity.Create(self.Scene, true, true);
+ }
+
+ if (self.Wallet == null)
+ {
+ self.Wallet = Entity.Create(self.Scene, true, true);
+ }
+
+ if (self.Vip == null)
+ {
+ self.Vip = Entity.Create(self.Scene, true, true);
+ }
+
+ if (self.Statistics == null)
+ {
+ self.Statistics = Entity.Create(self.Scene, true, true);
+ self.Statistics.LoginTime = self.Statistics.CreateTime = TimeHelper.Now;
+ }
+ }
+
+ public static async FTask SaveImmediately(this Player self)
+ {
+ await self.Scene.World.DataBase.Save(self);
+ self.NeedSave = false;
+ Log.Info($"player id:{self.Id} save data to dataBase");
+ }
+
+ public static async FTask Save(this Player self)
+ {
+ self.NeedSave = true;
+ self.NeedSaveTime = TimeHelper.Now + PlayerManageComponent.AutoSaveTime;
+ //先立马保存,后续做缓存
+ await self.Scene.World.DataBase.Save(self);
+ }
+
+
///
/// 从数据库中读取GameAccount
///
@@ -24,14 +76,6 @@ public static class PlayerHelper
return account;
}
- ///
- /// 保存账号到数据库中
- ///
- ///
- public static async FTask SaveDataBase(this Player self)
- {
- await self.Scene.World.DataBase.Save(self);
- }
///
/// 执行该账号的断开逻辑,不要非必要不要使用这个接口,这个接口是内部使用。
@@ -40,7 +84,7 @@ public static class PlayerHelper
public static async FTask Disconnect(this Player self)
{
// 保存该账号信息到数据库中。
- await SaveDataBase(self);
+ await SaveImmediately(self);
// 在缓存中移除自己,并且执行自己的Dispose方法。
self.Scene.GetComponent().Remove(self.Id);
}
@@ -59,7 +103,7 @@ public static class PlayerHelper
// 如果是心跳检测断开的Session,我怎么能拿到当前的这个账号来进行下线处理呢?
// 通过给当前的Session挂载一个组件,当销毁这个Session时候呢,也会销毁这个组件。
// 这样的话,是不是可以在登录的时候,给这个组件把AccountId存到这个组件呢?
-
+
// 要检查当前缓存中是否存在该账号的数据
var gameAccountManageComponent = scene.GetComponent();
if (!gameAccountManageComponent.TryGet(accountId, out var account))
@@ -68,19 +112,23 @@ public static class PlayerHelper
Log.Warning($"GameAccountHelper Disconnect accountId : {accountId} not found");
return;
}
+
// 为了防止逻辑的错误,加一个警告来排除下
if (!scene.TryGetEntity(account.SessionRunTimeId, out var session))
{
// 如果没有找到对应的Session,那只有一种可能就是当前的链接会话已经断开了,一般的情况下也不会出现的,所以咱们也要打印一个警告。
- Log.Warning($"GameAccountHelper Disconnect accountId : {accountId} SessionRunTimeId : {account.SessionRunTimeId} not found");
+ Log.Warning(
+ $"GameAccountHelper Disconnect accountId : {accountId} SessionRunTimeId : {account.SessionRunTimeId} not found");
return;
}
+
// 如果不存在定时任务的组件,那就添加并设置定时任务
if (account.IsTimeOutComponent())
{
// 如果已经存在了,那就表示当然已经有一个延时断开的任务了,那就不需要重复添加了
return;
}
+
// 立即下线处理
if (timeOut <= 0)
{
@@ -88,6 +136,7 @@ public static class PlayerHelper
await account.Disconnect();
return;
}
+
// 设置延迟下线
account.SetTimeout(timeOut, account.Disconnect);
}
@@ -102,11 +151,11 @@ public static class PlayerHelper
// 其实可以不用每次都NEW一个新的GameAccountInfo
// 可以在当前账号下创建一个GameAccountInfo,每次变动会提前通知这个GameAccountInfo
// 又或者每次调用该方法的时候,把值重新赋值一下。
-
+
return new GameAccountInfo()
{
- CreateTime = self.CreateTime,
- LoginTime = self.LoginTime
+ CreateTime = self.Statistics.CreateTime,
+ LoginTime = self.Statistics.LoginTime
};
}
}
\ No newline at end of file
diff --git a/Hotfix/Game/System/ItemManagerComponentSystem.cs b/Hotfix/Game/System/ItemManagerComponentSystem.cs
deleted file mode 100644
index feb7270..0000000
--- a/Hotfix/Game/System/ItemManagerComponentSystem.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace NB.Game.System;
-
-public class ItemManagerComponentSystem
-{
-
-}
\ No newline at end of file
diff --git a/Hotfix/Game/System/Player/PlayerAutoSaveComponentSystem.cs b/Hotfix/Game/System/Player/PlayerAutoSaveComponentSystem.cs
deleted file mode 100644
index 49410e4..0000000
--- a/Hotfix/Game/System/Player/PlayerAutoSaveComponentSystem.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace NB.Game;
-
-public class PlayerAutoSaveComponentSystem
-{
-
-}
\ No newline at end of file
diff --git a/Hotfix/Game/System/Player/PlayerDestroySystem.cs b/Hotfix/Game/System/Player/PlayerDestroySystem.cs
deleted file mode 100644
index 90aa06a..0000000
--- a/Hotfix/Game/System/Player/PlayerDestroySystem.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Fantasy.Entitas.Interface;
-
-namespace NB.Game;
-
-public sealed class PlayerDestroySystem : DestroySystem
-{
- protected override void Destroy(Player self)
- {
- self.CreateTime = 0;
- self.LoginTime = 0;
- self.SessionRunTimeId = 0;
- }
-}
\ No newline at end of file
diff --git a/Hotfix/Game/System/PlayerManageComponentSystem.cs b/Hotfix/Game/System/PlayerManageComponentSystem.cs
deleted file mode 100644
index c626983..0000000
--- a/Hotfix/Game/System/PlayerManageComponentSystem.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using Fantasy.Entitas.Interface;
-
-namespace NB.Game;
-
-public sealed class PlayerManageComponentDestroySystem : DestroySystem
-{
- protected override void Destroy(PlayerManageComponent self)
- {
- foreach (var (_, gameAccount) in self.Players)
- {
- gameAccount.Dispose();
- }
-
- self.Players.Clear();
- }
-}
-
-public static class PlayerManageComponentSystem
-{
- 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();
- }
-}
\ No newline at end of file
diff --git a/Hotfix/Hotfix.csproj b/Hotfix/Hotfix.csproj
index 99d72ad..2707d36 100644
--- a/Hotfix/Hotfix.csproj
+++ b/Hotfix/Hotfix.csproj
@@ -12,8 +12,4 @@
-
-
-
-
diff --git a/Server.sln.DotSettings.user b/Server.sln.DotSettings.user
index 6c23b67..3bbff5d 100644
--- a/Server.sln.DotSettings.user
+++ b/Server.sln.DotSettings.user
@@ -8,6 +8,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded