diff --git a/Config/NetworkProtocol/Outer/MapMessage.proto b/Config/NetworkProtocol/Outer/MapMessage.proto new file mode 100644 index 0000000..faf316a --- /dev/null +++ b/Config/NetworkProtocol/Outer/MapMessage.proto @@ -0,0 +1,4 @@ +syntax = "proto3"; +package Fantasy.Network.Message; + + diff --git a/Config/NetworkProtocol/Outer/SocialMessage.proto b/Config/NetworkProtocol/Outer/SocialMessage.proto index 50f9fe1..1f68903 100644 --- a/Config/NetworkProtocol/Outer/SocialMessage.proto +++ b/Config/NetworkProtocol/Outer/SocialMessage.proto @@ -1,32 +1,80 @@ syntax = "proto3"; package Fantasy.Network.Message; -////////////// ******** 邮件 *******///////////// +////////////// ******** 私聊/邮件 *******///////////// -///请求邮件列表 -message C2Game_GetMailsRequest // ICustomRouteRequest,Game2C_GetMailsResponse,GameRoute +/// 会话信息 +message ConversationInfo +{ + RoleSimpleInfo RoleInfo = 1; //对方信息 + repeated MailInfo List = 2;//对话列表 +} + +message MailInfo +{ + int64 Id = 1; //邮件id + int64 Sender = 2; //发送者 + string Content = 3; //内容 + int64 CreateTime = 4; //发送时间 + int32 MailType = 5; //邮件类型 + int32 MailState = 6; //邮件状态 + repeated AwardInfo Items = 7; //附件列表 +} + + +///请求会话列表 +message C2S_GetConversationsRequest // ICustomRouteRequest,S2C_GetConversationsResponse,SocialRoute { } -///获取邮件列表响应 -message Game2C_GetMailsResponse // ICustomRouteResponse + +///请求会话列表响应 +message S2C_GetConversationsResponse // ICustomRouteResponse { - repeated MailInfo Mail = 1; + repeated ConversationInfo List = 1; } +///发送邮件消息 +message C2S_SendMailRequest // ICustomRouteRequest,S2C_SendMailResponse,SocialRoute +{ + int64 Target = 1; //目标id + string Content = 2; //内容 + repeated AwardInfo Items = 3; //附件列表 +} + +///发送邮件消息响应 +message S2C_SendMailResponse // ICustomRouteResponse +{ + +} + +///发送删除会话消息 +message C2S_DeleteMailRequest // ICustomRouteRequest,S2C_DeleteMailResponse,SocialRoute +{ + int64 Id = 1; //会话id +} + +///发送删除会话消息响应 +message S2C_DeleteMailResponse // ICustomRouteResponse +{ + int64 Id = 1; //会话id +} + + ///新邮件推送 -message Game2C_HaveMail // ICustomRouteMessage,GameRoute +message S2C_HaveMail // ICustomRouteMessage,SocialRoute { MailInfo Mail = 1; + string Key = 2; } -message Game2C_MailState // ICustomRouteMessage,GameRoute +message S2C_MailState // ICustomRouteMessage,SocialRoute { int32 MailState = 1; int64 MailId = 2; } -////////////// ******** 聊天 *******///////////// +////////////// ******** 频道聊天 *******///////////// message ChatUserInfo { int64 Id = 1;//用户id @@ -66,34 +114,19 @@ message S2C_JoinChannelResponse // ICustomRouteResponse } -///发送聊天 +///发送消息 message C2S_SendMessageRequest // ICustomRouteRequest,S2C_SendMessageResponse,SocialRoute { - int32 Type = 1; //消息类型 0.频道聊天 1.私聊 - string Message = 2; - int64 Target = 3; //目标id,频道id或者好友id + string Message = 1; + int64 Target = 2; //目标id } -///发送聊天响应 +///发送消息响应 message S2C_SendMessageResponse // ICustomRouteResponse { } -///发送聊天 -message C2S_GetOfflineMessageRequest // ICustomRouteRequest,S2C_GetOfflineMessageResponse,SocialRoute -{ - int32 Type = 1; //消息类型 0.频道聊天 1.私聊 - string Message = 2; - int64 Target = 3; //目标id,频道id或者好友id -} - -///发送聊天响应 -message S2C_GetOfflineMessageResponse // ICustomRouteResponse -{ - repeated ChatMessageInfo Message = 1; -} - ///推送消息 message S2C_Message // ICustomRouteMessage,SocialRoute { @@ -101,20 +134,6 @@ message S2C_Message // ICustomRouteMessage,SocialRoute } -///获取聊天记录请求 -message C2S_GetChatRecordRequest // ICustomRouteRequest,S2C_GetChatRecordResponse,SocialRoute -{ - int64 Target = 1; // 好友id或频道id - int32 Type = 2; // 获取聊天记录类型 0.频道 1.好友 -} - -///获取聊天记录响应 -message S2C_GetChatRecordResponse // ICustomRouteResponse -{ - repeated ChatMessageInfo Messages = 1; //聊天记录 -} - - ////////////// ******** 工会 *******///////////// message ClubInfo diff --git a/Config/NetworkProtocol/Outer/data/Mail.proto b/Config/NetworkProtocol/Outer/data/Mail.proto deleted file mode 100644 index dbc2adb..0000000 --- a/Config/NetworkProtocol/Outer/data/Mail.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; -package Fantasy.Network.Message; - -message MailInfo -{ - int64 Id = 1; //邮件id - string Title = 2; //标题 - string Content = 3; //内容 - int64 CreateTime = 4; //发送时间 - int64 ExpireTime = 4; //发送时间 - int32 MailType = 5; //邮件类型 - int32 MailState = 6; //邮件状态 - repeated AwardInfo Items = 7; //附件列表 -} \ No newline at end of file diff --git a/Config/NetworkProtocol/RouteType.Config b/Config/NetworkProtocol/RouteType.Config index 82e1593..cd43e1f 100644 --- a/Config/NetworkProtocol/RouteType.Config +++ b/Config/NetworkProtocol/RouteType.Config @@ -1,4 +1,5 @@ // Route协议定义(需要定义1000以上、因为1000以内的框架预留) GateRoute = 1001 // Gate SocialRoute = 1002 // Social -GameRoute = 1003 // Game \ No newline at end of file +GameRoute = 1003 // Game +MapRoute = 1004 // Map \ No newline at end of file diff --git a/Entity/Def/AppConfig.cs b/Entity/Def/AppConfig.cs index 31f9071..0db946a 100644 --- a/Entity/Def/AppConfig.cs +++ b/Entity/Def/AppConfig.cs @@ -11,4 +11,14 @@ public class AppConfig /// 玩家数据定时落地间隔 /// public const long PlayerDataAutoSaveTime = 60000; // 600000; + + /// + /// 聊天数据自动保存间隔 + /// + public const long ChatDataAutoSaveTime = 6000; + + /// + /// 最大保留对话记录数 + /// + public const long MaxConversationCount = 20; } \ No newline at end of file diff --git a/Entity/Entity.csproj b/Entity/Entity.csproj index 561ebc7..6f1d222 100644 --- a/Entity/Entity.csproj +++ b/Entity/Entity.csproj @@ -25,13 +25,13 @@ + - diff --git a/Entity/Game/Cache/PlayerBasicCache.cs b/Entity/Game/Cache/PlayerBasicCache.cs index de4aeb5..8205f08 100644 --- a/Entity/Game/Cache/PlayerBasicCache.cs +++ b/Entity/Game/Cache/PlayerBasicCache.cs @@ -24,11 +24,7 @@ public class PlayerBasicCache : Entity /// 等级 /// public int Level; - - /// - /// 当前经验 - /// - public int Exp; + /// /// 是否是vip diff --git a/Entity/Game/Cache/PlayerBasicCacheManageComponent.cs b/Entity/Game/Cache/PlayerBasicCacheManageComponent.cs index 0d03837..a274bf5 100644 --- a/Entity/Game/Cache/PlayerBasicCacheManageComponent.cs +++ b/Entity/Game/Cache/PlayerBasicCacheManageComponent.cs @@ -5,4 +5,9 @@ namespace NB.Game; public class PlayerBasicCacheManageComponent : Entity { public readonly Dictionary Players = new(); + + /// + /// 定时检查定时器id + /// + public long checkTimerId; } \ No newline at end of file diff --git a/Entity/Game/Player/Player.cs b/Entity/Game/Player/Player.cs index 0d3f9ae..093f21f 100644 --- a/Entity/Game/Player/Player.cs +++ b/Entity/Game/Player/Player.cs @@ -4,6 +4,9 @@ using MongoDB.Bson.Serialization.Options; namespace NB.Game; +/// +/// 玩家基本数据 +/// public sealed class Player : Entity { /// @@ -37,39 +40,15 @@ public sealed class Player : Entity [BsonElement("vip")] public bool IsVip; /// - /// 统计信息 + /// 星数 /// - [BsonElement("stat")] public PlayerStatistics Statistics; + [BsonElement("star")] public int Star; /// - /// 角色vip信息 + /// 高光数 /// - [BsonElement("vInfo")] public PlayerVip Vip; + [BsonElement("high")] public int Highlight; - /// - /// 钱包 - /// - [BsonElement("wallet")] public PlayerWallet Wallet; - - /// - /// 背包 - /// - [BsonElement("bag")] public ItemContainer ItemContainer; - - /// - /// 鱼护 - /// - [BsonElement("fish")] public FishContainer FishContainer; - - /// - /// 技能 - /// - [BsonElement("skill")] public SkillContainer SkillContainer; - - /// - /// 成就 - /// - [BsonElement("achievement")] public AchievementContainer AchievementContainer; [BsonIgnore] public long SessionRunTimeId; diff --git a/Entity/Game/Player/PlayerBasic.cs b/Entity/Game/Player/PlayerBasic.cs new file mode 100644 index 0000000..18040fc --- /dev/null +++ b/Entity/Game/Player/PlayerBasic.cs @@ -0,0 +1,40 @@ +using Fantasy.Entitas; +using MongoDB.Bson.Serialization.Attributes; + +namespace NB.Game; + +/// +/// 用户核心信息 +/// +public class PlayerPrivate : Entity +{ + /// + /// 角色vip信息 + /// + [BsonElement("vInfo")] public PlayerVip Vip; + + /// + /// 钱包 + /// + [BsonElement("wallet")] public PlayerWallet Wallet; + + /// + /// 背包 + /// + [BsonElement("bag")] public ItemContainer ItemContainer; + + /// + /// 鱼护 + /// + [BsonElement("fish")] public FishContainer FishContainer; + + /// + /// 技能 + /// + [BsonElement("skill")] public SkillContainer SkillContainer; + + /// + /// 成就 + /// + [BsonElement("achievement")] public AchievementContainer AchievementContainer; +} \ No newline at end of file diff --git a/Entity/Generate/NetworkProtocol/Mail.cs b/Entity/Generate/NetworkProtocol/Mail.cs deleted file mode 100644 index b44fc76..0000000 --- a/Entity/Generate/NetworkProtocol/Mail.cs +++ /dev/null @@ -1,58 +0,0 @@ -using ProtoBuf; - -using System.Collections.Generic; -using MongoDB.Bson.Serialization.Attributes; -using Fantasy; -using Fantasy.Network.Interface; -using Fantasy.Serialize; -// ReSharper disable InconsistentNaming -// ReSharper disable RedundantUsingDirective -// ReSharper disable RedundantOverriddenMember -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedAutoPropertyAccessor.Global -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable CheckNamespace -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. -#pragma warning disable CS8618 - -namespace Fantasy -{ - [ProtoContract] - public partial class MailInfo : AMessage, IProto - { - public static MailInfo Create(Scene scene) - { - return scene.MessagePoolComponent.Rent(); - } - public override void Dispose() - { - Id = default; - Title = default; - Content = default; - CreateTime = default; - ExpireTime = default; - MailType = default; - MailState = default; - Items.Clear(); -#if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); -#endif - } - [ProtoMember(1)] - public long Id { get; set; } - [ProtoMember(2)] - public string Title { get; set; } - [ProtoMember(3)] - public string Content { get; set; } - [ProtoMember(4)] - public long CreateTime { get; set; } - [ProtoMember(5)] - public long ExpireTime { get; set; } - [ProtoMember(6)] - public int MailType { get; set; } - [ProtoMember(7)] - public int MailState { get; set; } - [ProtoMember(8)] - public List Items = new List(); - } -} diff --git a/Entity/Generate/NetworkProtocol/OuterOpcode.cs b/Entity/Generate/NetworkProtocol/OuterOpcode.cs index 1fc5291..b720b6c 100644 --- a/Entity/Generate/NetworkProtocol/OuterOpcode.cs +++ b/Entity/Generate/NetworkProtocol/OuterOpcode.cs @@ -9,21 +9,21 @@ namespace Fantasy public const uint G2C_RepeatLogin = 134227729; public const uint C2Game_GetRoleInfoRequest = 2281711377; public const uint Game2C_GetRoleInfoResponse = 2415929105; - public const uint C2Game_GetMailsRequest = 2281711378; - public const uint Game2C_GetMailsResponse = 2415929106; - public const uint Game2C_HaveMail = 2147493649; - public const uint Game2C_MailState = 2147493650; - public const uint C2S_CreateChannelRequest = 2281711379; - public const uint S2C_CreateChannelResponse = 2415929107; - public const uint C2S_JoinChannelRequest = 2281711380; - public const uint S2C_JoinChannelResponse = 2415929108; - public const uint C2S_SendMessageRequest = 2281711381; - public const uint S2C_SendMessageResponse = 2415929109; - public const uint C2S_GetOfflineMessageRequest = 2281711382; - public const uint S2C_GetOfflineMessageResponse = 2415929110; + public const uint C2S_GetConversationsRequest = 2281711378; + public const uint S2C_GetConversationsResponse = 2415929106; + public const uint C2S_SendMailRequest = 2281711379; + public const uint S2C_SendMailResponse = 2415929107; + public const uint C2S_DeleteMailRequest = 2281711380; + public const uint S2C_DeleteMailResponse = 2415929108; + public const uint S2C_HaveMail = 2147493649; + public const uint S2C_MailState = 2147493650; + public const uint C2S_CreateChannelRequest = 2281711381; + public const uint S2C_CreateChannelResponse = 2415929109; + public const uint C2S_JoinChannelRequest = 2281711382; + public const uint S2C_JoinChannelResponse = 2415929110; + public const uint C2S_SendMessageRequest = 2281711383; + public const uint S2C_SendMessageResponse = 2415929111; public const uint S2C_Message = 2147493651; - public const uint C2S_GetChatRecordRequest = 2281711383; - public const uint S2C_GetChatRecordResponse = 2415929111; public const uint C2S_CreateClubRequest = 2281711384; public const uint S2C_CreateClubResponse = 2415929112; public const uint C2S_GetClubInfoRequest = 2281711385; diff --git a/Entity/Generate/NetworkProtocol/SocialMessage.cs b/Entity/Generate/NetworkProtocol/SocialMessage.cs index 6a28d8a..5a802a5 100644 --- a/Entity/Generate/NetworkProtocol/SocialMessage.cs +++ b/Entity/Generate/NetworkProtocol/SocialMessage.cs @@ -18,51 +18,210 @@ using Fantasy.Serialize; namespace Fantasy { /// - /// /////////// ******** 邮件 *******///////////// + /// /////////// ******** 私聊/邮件 *******///////////// /// /// - /// 请求邮件列表 + /// 会话信息 /// [ProtoContract] - public partial class C2Game_GetMailsRequest : AMessage, ICustomRouteRequest, IProto + public partial class ConversationInfo : AMessage, IProto { - public static C2Game_GetMailsRequest Create(Scene scene) + public static ConversationInfo Create(Scene scene) { - return scene.MessagePoolComponent.Rent(); + return scene.MessagePoolComponent.Rent(); + } + public override void Dispose() + { + RoleInfo = default; + List.Clear(); +#if FANTASY_NET || FANTASY_UNITY + GetScene().MessagePoolComponent.Return(this); +#endif + } + [ProtoMember(1)] + public RoleSimpleInfo RoleInfo { get; set; } + [ProtoMember(2)] + public List List = new List(); + } + [ProtoContract] + public partial class MailInfo : AMessage, IProto + { + public static MailInfo Create(Scene scene) + { + return scene.MessagePoolComponent.Rent(); + } + public override void Dispose() + { + Id = default; + Sender = default; + Content = default; + CreateTime = default; + MailType = default; + MailState = default; + Items.Clear(); +#if FANTASY_NET || FANTASY_UNITY + GetScene().MessagePoolComponent.Return(this); +#endif + } + [ProtoMember(1)] + public long Id { get; set; } + [ProtoMember(2)] + public long Sender { get; set; } + [ProtoMember(3)] + public string Content { get; set; } + [ProtoMember(4)] + public long CreateTime { get; set; } + [ProtoMember(5)] + public int MailType { get; set; } + [ProtoMember(6)] + public int MailState { get; set; } + [ProtoMember(7)] + public List Items = new List(); + } + /// + /// 请求会话列表 + /// + [ProtoContract] + public partial class C2S_GetConversationsRequest : AMessage, ICustomRouteRequest, IProto + { + public static C2S_GetConversationsRequest Create(Scene scene) + { + return scene.MessagePoolComponent.Rent(); } public override void Dispose() { #if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); + GetScene().MessagePoolComponent.Return(this); #endif } [ProtoIgnore] - public Game2C_GetMailsResponse ResponseType { get; set; } - public uint OpCode() { return OuterOpcode.C2Game_GetMailsRequest; } + public S2C_GetConversationsResponse ResponseType { get; set; } + public uint OpCode() { return OuterOpcode.C2S_GetConversationsRequest; } [ProtoIgnore] - public int RouteType => Fantasy.RouteType.GameRoute; + public int RouteType => Fantasy.RouteType.SocialRoute; } /// - /// 获取邮件列表响应 + /// 请求会话列表响应 /// [ProtoContract] - public partial class Game2C_GetMailsResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_GetConversationsResponse : AMessage, ICustomRouteResponse, IProto { - public static Game2C_GetMailsResponse Create(Scene scene) + public static S2C_GetConversationsResponse Create(Scene scene) { - return scene.MessagePoolComponent.Rent(); + return scene.MessagePoolComponent.Rent(); } public override void Dispose() { ErrorCode = default; - Mail.Clear(); + List.Clear(); #if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); + GetScene().MessagePoolComponent.Return(this); #endif } - public uint OpCode() { return OuterOpcode.Game2C_GetMailsResponse; } + public uint OpCode() { return OuterOpcode.S2C_GetConversationsResponse; } [ProtoMember(1)] - public List Mail = new List(); + public List List = new List(); + [ProtoMember(2)] + public uint ErrorCode { get; set; } + } + /// + /// 发送邮件消息 + /// + [ProtoContract] + public partial class C2S_SendMailRequest : AMessage, ICustomRouteRequest, IProto + { + public static C2S_SendMailRequest Create(Scene scene) + { + return scene.MessagePoolComponent.Rent(); + } + public override void Dispose() + { + Target = default; + Content = default; + Items.Clear(); +#if FANTASY_NET || FANTASY_UNITY + GetScene().MessagePoolComponent.Return(this); +#endif + } + [ProtoIgnore] + public S2C_SendMailResponse ResponseType { get; set; } + public uint OpCode() { return OuterOpcode.C2S_SendMailRequest; } + [ProtoIgnore] + public int RouteType => Fantasy.RouteType.SocialRoute; + [ProtoMember(1)] + public long Target { get; set; } + [ProtoMember(2)] + public string Content { get; set; } + [ProtoMember(3)] + public List Items = new List(); + } + /// + /// 发送邮件消息响应 + /// + [ProtoContract] + public partial class S2C_SendMailResponse : AMessage, ICustomRouteResponse, IProto + { + public static S2C_SendMailResponse Create(Scene scene) + { + return scene.MessagePoolComponent.Rent(); + } + public override void Dispose() + { + ErrorCode = default; +#if FANTASY_NET || FANTASY_UNITY + GetScene().MessagePoolComponent.Return(this); +#endif + } + public uint OpCode() { return OuterOpcode.S2C_SendMailResponse; } + [ProtoMember(1)] + public uint ErrorCode { get; set; } + } + /// + /// 发送删除会话消息 + /// + [ProtoContract] + public partial class C2S_DeleteMailRequest : AMessage, ICustomRouteRequest, IProto + { + public static C2S_DeleteMailRequest Create(Scene scene) + { + return scene.MessagePoolComponent.Rent(); + } + public override void Dispose() + { + Id = default; +#if FANTASY_NET || FANTASY_UNITY + GetScene().MessagePoolComponent.Return(this); +#endif + } + [ProtoIgnore] + public S2C_DeleteMailResponse ResponseType { get; set; } + public uint OpCode() { return OuterOpcode.C2S_DeleteMailRequest; } + [ProtoIgnore] + public int RouteType => Fantasy.RouteType.SocialRoute; + [ProtoMember(1)] + public long Id { get; set; } + } + /// + /// 发送删除会话消息响应 + /// + [ProtoContract] + public partial class S2C_DeleteMailResponse : AMessage, ICustomRouteResponse, IProto + { + public static S2C_DeleteMailResponse Create(Scene scene) + { + return scene.MessagePoolComponent.Rent(); + } + public override void Dispose() + { + ErrorCode = default; + Id = default; +#if FANTASY_NET || FANTASY_UNITY + GetScene().MessagePoolComponent.Return(this); +#endif + } + public uint OpCode() { return OuterOpcode.S2C_DeleteMailResponse; } + [ProtoMember(1)] + public long Id { get; set; } [ProtoMember(2)] public uint ErrorCode { get; set; } } @@ -70,50 +229,53 @@ namespace Fantasy /// 新邮件推送 /// [ProtoContract] - public partial class Game2C_HaveMail : AMessage, ICustomRouteMessage, IProto + public partial class S2C_HaveMail : AMessage, ICustomRouteMessage, IProto { - public static Game2C_HaveMail Create(Scene scene) + public static S2C_HaveMail Create(Scene scene) { - return scene.MessagePoolComponent.Rent(); + return scene.MessagePoolComponent.Rent(); } public override void Dispose() { Mail = default; + Key = default; #if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); + GetScene().MessagePoolComponent.Return(this); #endif } - public uint OpCode() { return OuterOpcode.Game2C_HaveMail; } + public uint OpCode() { return OuterOpcode.S2C_HaveMail; } [ProtoIgnore] - public int RouteType => Fantasy.RouteType.GameRoute; + public int RouteType => Fantasy.RouteType.SocialRoute; [ProtoMember(1)] public MailInfo Mail { get; set; } + [ProtoMember(2)] + public string Key { get; set; } } [ProtoContract] - public partial class Game2C_MailState : AMessage, ICustomRouteMessage, IProto + public partial class S2C_MailState : AMessage, ICustomRouteMessage, IProto { - public static Game2C_MailState Create(Scene scene) + public static S2C_MailState Create(Scene scene) { - return scene.MessagePoolComponent.Rent(); + return scene.MessagePoolComponent.Rent(); } public override void Dispose() { MailState = default; MailId = default; #if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); + GetScene().MessagePoolComponent.Return(this); #endif } - public uint OpCode() { return OuterOpcode.Game2C_MailState; } + public uint OpCode() { return OuterOpcode.S2C_MailState; } [ProtoIgnore] - public int RouteType => Fantasy.RouteType.GameRoute; + public int RouteType => Fantasy.RouteType.SocialRoute; [ProtoMember(1)] public int MailState { get; set; } [ProtoMember(2)] public long MailId { get; set; } } /// - /// /////////// ******** 聊天 *******///////////// + /// /////////// ******** 频道聊天 *******///////////// /// [ProtoContract] public partial class ChatUserInfo : AMessage, IProto @@ -260,7 +422,7 @@ namespace Fantasy public uint ErrorCode { get; set; } } /// - /// 发送聊天 + /// 发送消息 /// [ProtoContract] public partial class C2S_SendMessageRequest : AMessage, ICustomRouteRequest, IProto @@ -271,7 +433,6 @@ namespace Fantasy } public override void Dispose() { - Type = default; Message = default; Target = default; #if FANTASY_NET || FANTASY_UNITY @@ -284,14 +445,12 @@ namespace Fantasy [ProtoIgnore] public int RouteType => Fantasy.RouteType.SocialRoute; [ProtoMember(1)] - public int Type { get; set; } - [ProtoMember(2)] public string Message { get; set; } - [ProtoMember(3)] + [ProtoMember(2)] public long Target { get; set; } } /// - /// 发送聊天响应 + /// 发送消息响应 /// [ProtoContract] public partial class S2C_SendMessageResponse : AMessage, ICustomRouteResponse, IProto @@ -312,61 +471,6 @@ namespace Fantasy public uint ErrorCode { get; set; } } /// - /// 发送聊天 - /// - [ProtoContract] - public partial class C2S_GetOfflineMessageRequest : AMessage, ICustomRouteRequest, IProto - { - public static C2S_GetOfflineMessageRequest Create(Scene scene) - { - return scene.MessagePoolComponent.Rent(); - } - public override void Dispose() - { - Type = default; - Message = default; - Target = default; -#if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); -#endif - } - [ProtoIgnore] - public S2C_GetOfflineMessageResponse ResponseType { get; set; } - public uint OpCode() { return OuterOpcode.C2S_GetOfflineMessageRequest; } - [ProtoIgnore] - public int RouteType => Fantasy.RouteType.SocialRoute; - [ProtoMember(1)] - public int Type { get; set; } - [ProtoMember(2)] - public string Message { get; set; } - [ProtoMember(3)] - public long Target { get; set; } - } - /// - /// 发送聊天响应 - /// - [ProtoContract] - public partial class S2C_GetOfflineMessageResponse : AMessage, ICustomRouteResponse, IProto - { - public static S2C_GetOfflineMessageResponse Create(Scene scene) - { - return scene.MessagePoolComponent.Rent(); - } - public override void Dispose() - { - ErrorCode = default; - Message.Clear(); -#if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); -#endif - } - public uint OpCode() { return OuterOpcode.S2C_GetOfflineMessageResponse; } - [ProtoMember(1)] - public List Message = new List(); - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - /// /// 推送消息 /// [ProtoContract] @@ -390,58 +494,6 @@ namespace Fantasy public ChatMessageInfo Message { get; set; } } /// - /// 获取聊天记录请求 - /// - [ProtoContract] - public partial class C2S_GetChatRecordRequest : AMessage, ICustomRouteRequest, IProto - { - public static C2S_GetChatRecordRequest Create(Scene scene) - { - return scene.MessagePoolComponent.Rent(); - } - public override void Dispose() - { - Target = default; - Type = default; -#if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); -#endif - } - [ProtoIgnore] - public S2C_GetChatRecordResponse ResponseType { get; set; } - public uint OpCode() { return OuterOpcode.C2S_GetChatRecordRequest; } - [ProtoIgnore] - public int RouteType => Fantasy.RouteType.SocialRoute; - [ProtoMember(1)] - public long Target { get; set; } - [ProtoMember(2)] - public int Type { get; set; } - } - /// - /// 获取聊天记录响应 - /// - [ProtoContract] - public partial class S2C_GetChatRecordResponse : AMessage, ICustomRouteResponse, IProto - { - public static S2C_GetChatRecordResponse Create(Scene scene) - { - return scene.MessagePoolComponent.Rent(); - } - public override void Dispose() - { - ErrorCode = default; - Messages.Clear(); -#if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); -#endif - } - public uint OpCode() { return OuterOpcode.S2C_GetChatRecordResponse; } - [ProtoMember(1)] - public List Messages = new List(); - [ProtoMember(2)] - public uint ErrorCode { get; set; } - } - /// /// /////////// ******** 工会 *******///////////// /// [ProtoContract] diff --git a/Entity/Map/MapRoom.cs b/Entity/Map/MapRoom.cs new file mode 100644 index 0000000..a088240 --- /dev/null +++ b/Entity/Map/MapRoom.cs @@ -0,0 +1,34 @@ +using Fantasy.Entitas; + +namespace NB.Map; + +/// +/// 地图房间 +/// +public class MapRoom : Entity +{ + /// + /// 房间密码 + /// + public string Password; + + /// + /// 房间玩家 + /// + public Dictionary Units = new Dictionary(); + + /// + /// 房主 + /// + public long Owner; + + /// + /// 创建时间 + /// + public long CreateTime; + + /// + /// 房间地图 + /// + public int Map; +} \ No newline at end of file diff --git a/Entity/Map/MapUnit.cs b/Entity/Map/MapUnit.cs new file mode 100644 index 0000000..06ed88d --- /dev/null +++ b/Entity/Map/MapUnit.cs @@ -0,0 +1,10 @@ +using Fantasy.Entitas; + +namespace NB.Map; + +/// +/// 地图玩家单元 +/// +public class MapUnit : Entity +{ +} \ No newline at end of file diff --git a/Entity/Model/Def/ErrorCode.cs b/Entity/Model/Def/ErrorCode.cs index 676eeb2..636a0f8 100644 --- a/Entity/Model/Def/ErrorCode.cs +++ b/Entity/Model/Def/ErrorCode.cs @@ -44,4 +44,9 @@ public class ErrorCode /// 聊天频道不存在 /// public const uint ChatNotChannel = 12011; + + /// + /// 没回复前不能再发消息 + /// + public const uint MailNotReply = 12021; } \ No newline at end of file diff --git a/Entity/Social/Mail/Components/MailComponent.cs b/Entity/Social/Mail/Components/MailComponent.cs index fc8935f..03f7bab 100644 --- a/Entity/Social/Mail/Components/MailComponent.cs +++ b/Entity/Social/Mail/Components/MailComponent.cs @@ -4,7 +4,7 @@ using Fantasy.Helper; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Options; -namespace NB.Game; +namespace NB.Chat; /// /// 玩家邮件组件 diff --git a/Entity/Social/Mail/Components/MailManageComponent.cs b/Entity/Social/Mail/Components/MailManageComponent.cs new file mode 100644 index 0000000..4ced51e --- /dev/null +++ b/Entity/Social/Mail/Components/MailManageComponent.cs @@ -0,0 +1,19 @@ +using Fantasy.Entitas; + +namespace NB.Chat; + +/// +/// 邮件管理组件 +/// +public class MailManageComponent : Entity +{ + /// + /// 会话列表 + /// + public Dictionary Conversations = new Dictionary(); + + /// + /// 缓存了的列表 + /// + public HashSet CacheRoleIds = new HashSet(); +} \ No newline at end of file diff --git a/Entity/Social/Mail/Entity/Mail.cs b/Entity/Social/Mail/Entity/Mail.cs index 2465f64..fbc324e 100644 --- a/Entity/Social/Mail/Entity/Mail.cs +++ b/Entity/Social/Mail/Entity/Mail.cs @@ -1,46 +1,48 @@ using Fantasy.Entitas; +using MongoDB.Bson.Serialization.Attributes; +using NB.Game; -namespace NB.Game; +namespace NB.Chat; public sealed class Mail : Entity { + /// + /// 邮件发送者 + /// + [BsonElement("send")] public long Sender; + /// /// 邮件拥有者 /// - public long OwnerId; + [BsonElement("owner")] public long OwnerId; /// /// 邮件状态 /// - public MailState State = MailState.None; + [BsonElement("state")] public MailState State = MailState.None; /// /// 邮件状态 /// - public MailType MailType = MailType.None; - - /// - /// 邮件标题 - /// - public string Title; + [BsonElement("type")] public MailType MailType = MailType.None; /// /// 邮件内容 /// - public string Content; + [BsonElement("con")] public string Content; /// /// 创建时间 /// - public long CreateTime; + [BsonElement("ct")] public long CreateTime; /// /// 过期时间 /// - public long ExpireTime; + [BsonElement("et")] public long ExpireTime; /// /// 邮件的附件内容 /// - public List Items = new List(); + [BsonElement("item")] public List Items = new List(); } \ No newline at end of file diff --git a/Entity/Social/Mail/Entity/MailBox.cs b/Entity/Social/Mail/Entity/MailBox.cs index b57adfb..40e7081 100644 --- a/Entity/Social/Mail/Entity/MailBox.cs +++ b/Entity/Social/Mail/Entity/MailBox.cs @@ -1,7 +1,10 @@ using Fantasy.Entitas; -namespace NB.Game; +namespace NB.Chat; +/// +/// 邮件箱,系统群发用 +/// public class MailBox : Entity { /// diff --git a/Entity/Social/Mail/Entity/MailConversation.cs b/Entity/Social/Mail/Entity/MailConversation.cs new file mode 100644 index 0000000..7100bd5 --- /dev/null +++ b/Entity/Social/Mail/Entity/MailConversation.cs @@ -0,0 +1,57 @@ +using Fantasy.Entitas; +using MongoDB.Bson.Serialization.Attributes; + +namespace NB.Chat; + +public class MailConversation : Entity +{ + /// + /// 第一id + /// + [BsonElement("id1")] public long FirstId; + + /// + /// 第二id + /// + [BsonElement("id2")] public long SecondId; + + /// + /// 会话 + /// + [BsonElement("list")] public List Mails = new List(); + + /// + /// 第一个阅读时间 + /// + [BsonElement("ft")] public long FirstReadTime; + + /// + /// 第二阅读时间 + /// + [BsonElement("st")] public long SecondReadTime; + + /// + /// 最后更新时间 + /// + [BsonElement("ut")] public long UpdateTime; + + /// + /// 删除人标志 + /// + [BsonElement("rid")] public HashSet RemoveId = new HashSet(); + + /// + /// 会话key,id-id,按大小排序 + /// + [BsonIgnore] public string Key = string.Empty; + + /// + /// 最后保存时间 + /// + [BsonIgnore] public long NeedSaveTime = 0; + + /// + /// 需要保存 + /// + [BsonIgnore] public bool NeedSave; +} \ No newline at end of file diff --git a/Entity/Social/Mail/Enum/MailEnum.cs b/Entity/Social/Mail/Enum/MailEnum.cs index 16ccbe0..9068185 100644 --- a/Entity/Social/Mail/Enum/MailEnum.cs +++ b/Entity/Social/Mail/Enum/MailEnum.cs @@ -1,4 +1,4 @@ -namespace NB.Game; +namespace NB.Chat; public enum MailType { diff --git a/Entity/Social/SocialUnitManageComponent.cs b/Entity/Social/SocialUnitManageComponent.cs index 7db93ea..7d5e2b1 100644 --- a/Entity/Social/SocialUnitManageComponent.cs +++ b/Entity/Social/SocialUnitManageComponent.cs @@ -8,8 +8,9 @@ public class SocialUnitManageComponent : Entity { public readonly Dictionary Units = new(); - /// - /// 不在线消息缓存 - /// - public readonly OneToManyList NotSendMessage = new(); + // public List + // /// + // /// 不在线消息缓存 + // /// + // public readonly OneToManyList NotSendMessage = new(); } \ No newline at end of file diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/MongoDataBase.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/MongoDataBase.cs index 49948f4..afb7f09 100644 --- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/MongoDataBase.cs +++ b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/DataBase/MongoDataBase.cs @@ -92,6 +92,11 @@ namespace Fantasy.DataBase return data == null ? 0 : Convert.ToInt64(data["Result"]); } + /// + /// Mongo 注释 + /// + public MongoClient Client => _mongoClient; + #endregion #region GetCollection diff --git a/Hotfix/Game/Cache/Handler/CacheHandler.cs b/Hotfix/Game/Cache/Handler/CacheHandler.cs deleted file mode 100644 index f911111..0000000 --- a/Hotfix/Game/Cache/Handler/CacheHandler.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Fantasy; - -namespace NB.Game; - -public static class CacheHandler -{ - public static List GetPlayerBasicCacheInfos(List id) - { - - } - - public static RoleSimpleInfo GetPlayerBasicCacheInfos(long id) - { - - } -} \ No newline at end of file diff --git a/Hotfix/Game/Cache/Handler/S2G_GetPlayerBasicInfoRequestHandler.cs b/Hotfix/Game/Cache/Handler/S2G_GetPlayerBasicInfoRequestHandler.cs new file mode 100644 index 0000000..5f5921c --- /dev/null +++ b/Hotfix/Game/Cache/Handler/S2G_GetPlayerBasicInfoRequestHandler.cs @@ -0,0 +1,24 @@ +using Fantasy; +using Fantasy.Async; +using Fantasy.Network.Interface; + +namespace NB.Game; + +public class + S2G_GetPlayerBasicInfoRequestHandler : RouteRPC +{ + protected override async FTask Run(Scene scene, S2G_GetPlayerBasicInfoRequest request, + G2S_GetPlayerBasicInfoResponse response, Action reply) + { + var playerBasicCacheManageComponent = scene.GetComponent(); + if (playerBasicCacheManageComponent != null) + { + var list = await playerBasicCacheManageComponent.GetPlayerBasicCacheInfos(request.IdList); + if (list != null && list.Count > 0) + { + response.RoleList.AddRange(list); + } + } + } +} \ No newline at end of file diff --git a/Hotfix/Game/Cache/Helper/CacheHandler.cs b/Hotfix/Game/Cache/Helper/CacheHandler.cs new file mode 100644 index 0000000..bf36af5 --- /dev/null +++ b/Hotfix/Game/Cache/Helper/CacheHandler.cs @@ -0,0 +1,49 @@ +using Fantasy; +using Fantasy.Async; + +namespace NB.Game; + +public static class CacheHandler +{ + /// + /// 查询玩家基础信息 + /// + /// + /// + /// + public static async FTask> GetPlayerBasicCacheInfos(Scene scene, List 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(); + } + + return gameResponse.RoleList; + } + + /// + /// 获取玩家基础信息 + /// + /// + /// + /// + public static async FTask GetPlayerBasicCacheInfo(Scene scene, long id) + { + var list = await GetPlayerBasicCacheInfos(scene, [id]); + if (list.Count > 0) + { + return list[0]; + } + + return null; + } +} \ No newline at end of file diff --git a/Hotfix/Game/Cache/Helper/PlayerBasicCacheFactory.cs b/Hotfix/Game/Cache/Helper/PlayerBasicCacheFactory.cs new file mode 100644 index 0000000..5e102b5 --- /dev/null +++ b/Hotfix/Game/Cache/Helper/PlayerBasicCacheFactory.cs @@ -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(scene, id, true, true); + return player; + } +} \ No newline at end of file diff --git a/Hotfix/Game/Cache/System/PlayerBasicCacheManageComponentSystem.cs b/Hotfix/Game/Cache/System/PlayerBasicCacheManageComponentSystem.cs new file mode 100644 index 0000000..eaea42a --- /dev/null +++ b/Hotfix/Game/Cache/System/PlayerBasicCacheManageComponentSystem.cs @@ -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 +{ + protected override void Awake(PlayerBasicCacheManageComponent self) + { + // var timerId = self.Scene.TimerComponent.Net.RepeatedTimer(1000 * 60, new TestEvent()); + } +} + +public class PlayerBasicCacheManageComponentDestroySystem : DestroySystem +{ + protected override void Destroy(PlayerBasicCacheManageComponent self) + { + foreach (var (_, player) in self.Players) + { + player.Dispose(); + } + + self.Players.Clear(); + } +} + +public static class PlayerBasicCacheManageComponentSystem +{ + /// + /// 获取一组玩家基本信息 + /// + /// + /// + /// + public static async FTask> GetPlayerBasicCacheInfos( + this PlayerBasicCacheManageComponent manage, + List list) + { + var ret = new List(); + var notCacheIdList = new List(); + 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; + } + + /// + /// 获取缓存的单个玩家基本信息 + /// + /// + /// + /// + public static RoleSimpleInfo? GetPlayerBasicCacheInfos(this PlayerBasicCacheManageComponent manage, + long id) + { + if (manage.Players.TryGetValue(id, out var cache)) + { + return cache.ToInfo(); + } + + return null; + } + + /// + /// 从数据库中加载玩家基本信息 + /// + /// + /// + /// + public static async FTask> LoadPlayerBasicCacheByDB( + this PlayerBasicCacheManageComponent manage, + List ids) + { + // Stopwatch stopwatch = new Stopwatch(); + // stopwatch.Start(); + var ret = new List(); + //TODO:需要考虑如果数量过大是否需要分页 + List players = + await manage.Scene.World.DataBase.QueryByPage(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; + } +} \ No newline at end of file diff --git a/Hotfix/Game/Cache/System/PlayerBasicCacheSystem.cs b/Hotfix/Game/Cache/System/PlayerBasicCacheSystem.cs new file mode 100644 index 0000000..57f3afd --- /dev/null +++ b/Hotfix/Game/Cache/System/PlayerBasicCacheSystem.cs @@ -0,0 +1,33 @@ +using Fantasy; +using Fantasy.Entitas.Interface; + +namespace NB.Game; + +public class PlayerBasicCacheDestroySystem : DestroySystem +{ + 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; + } +} \ No newline at end of file diff --git a/Hotfix/Game/Helper/GameSceneHelper.cs b/Hotfix/Game/Helper/GameSceneHelper.cs index fea7601..d93db66 100644 --- a/Hotfix/Game/Helper/GameSceneHelper.cs +++ b/Hotfix/Game/Helper/GameSceneHelper.cs @@ -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 + + } \ No newline at end of file diff --git a/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs b/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs index 1193168..22f8ab6 100644 --- a/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs +++ b/Hotfix/Game/Player/Components/PlayerManageComponentSystem.cs @@ -103,7 +103,7 @@ public static class PlayerManageComponentSystem } } - account.Statistics.LoginTime = TimeHelper.Now; + // account.Statistics.LoginTime = TimeHelper.Now; await account.Save(); diff --git a/Hotfix/Game/Player/Entity/PlayerSystem.cs b/Hotfix/Game/Player/Entity/PlayerSystem.cs index 68dcc1e..b1e2609 100644 --- a/Hotfix/Game/Player/Entity/PlayerSystem.cs +++ b/Hotfix/Game/Player/Entity/PlayerSystem.cs @@ -19,16 +19,16 @@ public sealed class PlayerDestroySystem : DestroySystem 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; } diff --git a/Hotfix/Game/Player/Helper/PlayerHelper.cs b/Hotfix/Game/Player/Helper/PlayerHelper.cs index c370d38..923fb5f 100644 --- a/Hotfix/Game/Player/Helper/PlayerHelper.cs +++ b/Hotfix/Game/Player/Helper/PlayerHelper.cs @@ -12,31 +12,31 @@ public static class PlayerHelper public static void InitializeChildEntity(this Player self) { - 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; - } + // 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) @@ -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; diff --git a/Hotfix/Hotfix.csproj b/Hotfix/Hotfix.csproj index efcebd9..b86eb25 100644 --- a/Hotfix/Hotfix.csproj +++ b/Hotfix/Hotfix.csproj @@ -13,6 +13,9 @@ + + + diff --git a/Hotfix/OnCreateSceneEvent.cs b/Hotfix/OnCreateSceneEvent.cs index a820d2e..7322027 100644 --- a/Hotfix/OnCreateSceneEvent.cs +++ b/Hotfix/OnCreateSceneEvent.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using Fantasy; using Fantasy.Async; using Fantasy.Entitas; @@ -73,6 +74,46 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem } case SceneType.Game: { + + // // Begins transaction + // using (var session = mongoClient.StartSession()) + // { + // session.StartTransaction(); + // try + // { + // // Creates sample data + // var book = new Book + // { + // Title = "Beloved", + // Author = "Toni Morrison", + // InStock = true + // }; + // var film = new Film + // { + // Title = "Star Wars", + // Director = "George Lucas", + // InStock = true + // }; + // // Inserts sample data + // books.InsertOne(session, book); + // films.InsertOne(session, film); + // // Commits our transaction + // session.CommitTransaction(); + // } + // catch (Exception e) + // { + // Console.WriteLine("Error writing to MongoDB: " + e.Message); + // return; + // } + // // Prints a success message if no error thrown + // Console.WriteLine("Successfully committed transaction!"); + // } + + // var client = self.Scene.World.DataBase; + + // List tasks = new List(); + // Stopwatch stopwatch = new Stopwatch(); + // stopwatch.Start(); // for (int i = 0; i < 100; i++) // { // var accountId = scene.EntityIdFactory.Create; @@ -83,9 +124,15 @@ public sealed class OnCreateSceneEvent : AsyncEventSystem // account.Country = "cn"; // account.Exp = 999; // account.Head = "xxx.png"; - // await account.Save(); + // tasks.Add(account.Save()); // } + // await FTask.WaitAll(tasks); + // // self.Scene.World.DataBase.InsertBatch() // + // stopwatch.Stop(); + // Log.Info($"创建100个号入库耗时={stopwatch.ElapsedMilliseconds}ms"); + + break; } case SceneType.Gate: diff --git a/Hotfix/OnSceneCreate_Init.cs b/Hotfix/OnSceneCreate_Init.cs index 7e6af12..5738c24 100644 --- a/Hotfix/OnSceneCreate_Init.cs +++ b/Hotfix/OnSceneCreate_Init.cs @@ -36,6 +36,7 @@ public class OnSceneCreate_Init : AsyncEventSystem { //用于管理玩家的组件 scene.AddComponent(); + scene.AddComponent(); break; } case SceneType.Social: @@ -43,6 +44,7 @@ public class OnSceneCreate_Init : AsyncEventSystem //用于管理玩家的组件 scene.AddComponent(); scene.AddComponent(); + scene.AddComponent(); break; } } diff --git a/Hotfix/Social/Handler/C2S_CreateChannelRequestHandler.cs b/Hotfix/Social/Chat/Handler/C2S_CreateChannelRequestHandler.cs similarity index 100% rename from Hotfix/Social/Handler/C2S_CreateChannelRequestHandler.cs rename to Hotfix/Social/Chat/Handler/C2S_CreateChannelRequestHandler.cs diff --git a/Hotfix/Social/Chat/Handler/C2S_GetOfflineMessageRequestHandler.cs b/Hotfix/Social/Chat/Handler/C2S_GetOfflineMessageRequestHandler.cs new file mode 100644 index 0000000..5da5cbd --- /dev/null +++ b/Hotfix/Social/Chat/Handler/C2S_GetOfflineMessageRequestHandler.cs @@ -0,0 +1,24 @@ +// using Fantasy; +// using Fantasy.Async; +// using Fantasy.Network.Interface; +// +// namespace NB.Chat; +// +// public class +// C2S_GetOfflineMessageRequestHandler : RouteRPC +// { +// protected override async FTask Run(SocialUnit entity, C2S_GetOfflineMessageRequest request, +// S2C_GetOfflineMessageResponse response, +// Action reply) +// { +// var chatUnitManage = entity.Scene.GetComponent(); +// if (chatUnitManage.NotSendMessage.TryGetValue(entity.Id, out var list)) +// { +// response.Message.AddRange(list); +// chatUnitManage.NotSendMessage.RemoveByKey(entity.Id); +// } +// +// await FTask.CompletedTask; +// } +// } \ No newline at end of file diff --git a/Hotfix/Social/Handler/C2S_JoinChannelRequestHandler.cs b/Hotfix/Social/Chat/Handler/C2S_JoinChannelRequestHandler.cs similarity index 100% rename from Hotfix/Social/Handler/C2S_JoinChannelRequestHandler.cs rename to Hotfix/Social/Chat/Handler/C2S_JoinChannelRequestHandler.cs diff --git a/Hotfix/Social/Chat/Handler/C2S_SendMessageRequestHandler.cs b/Hotfix/Social/Chat/Handler/C2S_SendMessageRequestHandler.cs new file mode 100644 index 0000000..7222f4b --- /dev/null +++ b/Hotfix/Social/Chat/Handler/C2S_SendMessageRequestHandler.cs @@ -0,0 +1,155 @@ +using System.Diagnostics; +using System.Text; +using Fantasy; +using Fantasy.Async; +using Fantasy.Helper; +using Fantasy.Network.Interface; +using NB.Game; + +namespace NB.Chat; + +public sealed class + C2S_SendMessageRequestHandler : RouteRPC +{ + protected override async FTask Run(SocialUnit socialUnit, C2S_SendMessageRequest request, + S2C_SendMessageResponse response, Action reply) + { + if (request.Target < 1) + { + response.ErrorCode = ErrorCode.ErrArgs; + return; + } + + SocialSceneHelper.BroadcastChannel(socialUnit.Scene, request.Target, new ChatMessageInfo() + { + SendTime = TimeHelper.Now, + Content = request.Message, + }); + // if (request.Type == 0) //频道聊天 + // { + // } + // else if (request.Type == 1) //私聊 + // { + // //发送私聊 + // SocialSceneHelper.PrivateMessage(socialUnit.Scene, socialUnit.Id, request.Target, new ChatMessageInfo() + // { + // SendTime = TimeHelper.Now, + // Content = request.Message, + // }); + // } + + + // var list = new List() + // { + // 337951357380329472, + // 337951357380329473, + // 337951357380329474, + // 337951357380329475, + // 337951357380329476, + // 337951357380329477, + // 337951357380329478, + // 337951357380329479, + // 337951357380329480, + // 337951357380329481, + // 337951357380329482, + // 337951357380329483, + // 337951357380329484, + // 337951357380329485, + // 337951357380329486, + // 337951357380329487, + // 337951357380329488, + // 337951357380329489, + // 337951357380329490, + // 337951357380329491, + // 337951357380329492, + // 337951357380329493, + // 337951357380329494, + // 337951357380329495, + // 337951357380329496, + // 337951357380329497, + // 337951357380329498, + // 337951357380329499, + // 337951357380329500, + // 337951357380329501, + // 337951357380329502, + // 337951357380329503, + // 337951357380329504, + // 337951357380329505, + // 337951357380329506, + // 337951357380329507, + // 337951357380329508, + // 337951357380329509, + // 337951357380329510, + // 337951357380329511, + // 337951357380329512, + // 337951357380329513, + // 337951357380329514, + // 337951357380329515, + // 337951357380329516, + // 337951357380329517, + // 337951357380329518, + // 337951357380329519, + // 337951357380329520, + // 337951357380329521, + // 337951357380329522, + // 337951357380329523, + // 337951357380329524, + // 337951357380329525, + // 337951357380329526, + // 337951357380329527, + // 337951357380329528, + // 337951357380329529, + // 337951357380329530, + // 337951357380329531, + // 337951357380329532, + // 337951357380329533, + // 337951357380329534, + // 337951357380329535, + // 337951357380329536, + // 337951357380329537, + // 337951357380329538, + // 337951357380329539, + // 337951357380329540, + // 337951357380329541, + // 337951357380329542, + // 337951357380329543, + // 337951357380329544, + // 337951357380329545, + // 337951357380329546, + // 337951357380329547, + // 337951357380329548, + // 337951357380329549, + // 337951357380329550, + // 337951357380329551, + // 337951357380329552, + // 337951357380329553, + // 337951357380329554, + // 337951357380329555, + // 337951357380329556, + // 337951357380329557, + // 337951357380329558, + // 337951357380329559, + // 337951357380329560, + // 337951357380329561, + // 337951357380329562, + // 337951357380329563, + // 337951357380329564, + // 337951357380329565, + // 337951357380329566, + // 337951357380329567, + // 337951357380329568, + // 337951357380329569, + // 337951357380329570, + // 337951357380329571 + // }; + // + // Stopwatch stopwatch = new Stopwatch(); + // stopwatch.Start(); + // var infoList = await CacheHandler.GetPlayerBasicCacheInfos(socialUnit.Scene,list); + // stopwatch.Stop(); + // Log.Info($"查询数量={infoList.Count} 耗时={stopwatch.ElapsedMilliseconds}"); + // + + await FTask.CompletedTask; + } +} \ No newline at end of file diff --git a/Hotfix/Social/Handler/Inner/G2S_EnterRequestHandler.cs b/Hotfix/Social/Chat/Handler/Inner/G2S_EnterRequestHandler.cs similarity index 100% rename from Hotfix/Social/Handler/Inner/G2S_EnterRequestHandler.cs rename to Hotfix/Social/Chat/Handler/Inner/G2S_EnterRequestHandler.cs diff --git a/Hotfix/Social/Handler/Inner/G2S_ExitRequestHandler.cs b/Hotfix/Social/Chat/Handler/Inner/G2S_ExitRequestHandler.cs similarity index 100% rename from Hotfix/Social/Handler/Inner/G2S_ExitRequestHandler.cs rename to Hotfix/Social/Chat/Handler/Inner/G2S_ExitRequestHandler.cs diff --git a/Hotfix/Social/Helper/ChatUnitFactory.cs b/Hotfix/Social/Chat/Helper/ChatUnitFactory.cs similarity index 100% rename from Hotfix/Social/Helper/ChatUnitFactory.cs rename to Hotfix/Social/Chat/Helper/ChatUnitFactory.cs diff --git a/Hotfix/Social/Helper/SocialSceneHelper.cs b/Hotfix/Social/Chat/Helper/SocialSceneHelper.cs similarity index 100% rename from Hotfix/Social/Helper/SocialSceneHelper.cs rename to Hotfix/Social/Chat/Helper/SocialSceneHelper.cs diff --git a/Hotfix/Social/System/ChatChannelCenterComponentSystem.cs b/Hotfix/Social/Chat/System/ChatChannelCenterComponentSystem.cs similarity index 100% rename from Hotfix/Social/System/ChatChannelCenterComponentSystem.cs rename to Hotfix/Social/Chat/System/ChatChannelCenterComponentSystem.cs diff --git a/Hotfix/Social/System/ChatChannelSystem.cs b/Hotfix/Social/Chat/System/ChatChannelSystem.cs similarity index 100% rename from Hotfix/Social/System/ChatChannelSystem.cs rename to Hotfix/Social/Chat/System/ChatChannelSystem.cs diff --git a/Hotfix/Social/System/ChatUnitManageComponentSystem.cs b/Hotfix/Social/Chat/System/ChatUnitManageComponentSystem.cs similarity index 98% rename from Hotfix/Social/System/ChatUnitManageComponentSystem.cs rename to Hotfix/Social/Chat/System/ChatUnitManageComponentSystem.cs index 85352e6..7aa95b8 100644 --- a/Hotfix/Social/System/ChatUnitManageComponentSystem.cs +++ b/Hotfix/Social/Chat/System/ChatUnitManageComponentSystem.cs @@ -17,7 +17,7 @@ public static class ChatUnitManageComponentSystem /// public static void SaveOfflineMessage(this SocialUnitManageComponent self, long targetId, ChatMessageInfo message) { - self.NotSendMessage.Add(targetId, message); + // self.NotSendMessage.Add(targetId, message); } #endregion diff --git a/Hotfix/Social/System/ChatUnitSystem.cs b/Hotfix/Social/Chat/System/ChatUnitSystem.cs similarity index 100% rename from Hotfix/Social/System/ChatUnitSystem.cs rename to Hotfix/Social/Chat/System/ChatUnitSystem.cs diff --git a/Hotfix/Social/Handler/C2S_GetOfflineMessageRequestHandler.cs b/Hotfix/Social/Handler/C2S_GetOfflineMessageRequestHandler.cs deleted file mode 100644 index 3e5b64d..0000000 --- a/Hotfix/Social/Handler/C2S_GetOfflineMessageRequestHandler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Fantasy; -using Fantasy.Async; -using Fantasy.Network.Interface; - -namespace NB.Chat; - -public class - C2S_GetOfflineMessageRequestHandler : RouteRPC -{ - protected override async FTask Run(SocialUnit entity, C2S_GetOfflineMessageRequest request, - S2C_GetOfflineMessageResponse response, - Action reply) - { - var chatUnitManage = entity.Scene.GetComponent(); - if (chatUnitManage.NotSendMessage.TryGetValue(entity.Id, out var list)) - { - response.Message.AddRange(list); - chatUnitManage.NotSendMessage.RemoveByKey(entity.Id); - } - - await FTask.CompletedTask; - } -} \ No newline at end of file diff --git a/Hotfix/Social/Handler/C2S_SendMessageRequestHandler.cs b/Hotfix/Social/Handler/C2S_SendMessageRequestHandler.cs deleted file mode 100644 index 01f9a3e..0000000 --- a/Hotfix/Social/Handler/C2S_SendMessageRequestHandler.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Text; -using Fantasy; -using Fantasy.Async; -using Fantasy.Helper; -using Fantasy.Network.Interface; - -namespace NB.Chat; - -public sealed class - C2S_SendMessageRequestHandler : RouteRPC -{ - protected override async FTask Run(SocialUnit socialUnit, C2S_SendMessageRequest request, - S2C_SendMessageResponse response, Action reply) - { - if (request.Target < 1) - { - response.ErrorCode = ErrorCode.ErrArgs; - return; - } - - if (request.Type == 0) //频道聊天 - { - SocialSceneHelper.BroadcastChannel(socialUnit.Scene, request.Target, new ChatMessageInfo() - { - SendTime = TimeHelper.Now, - Content = request.Message, - }); - } - else if (request.Type == 1) //私聊 - { - //发送私聊 - SocialSceneHelper.PrivateMessage(socialUnit.Scene, socialUnit.Id, request.Target, new ChatMessageInfo() - { - SendTime = TimeHelper.Now, - Content = request.Message, - }); - } - - await FTask.CompletedTask; - } -} \ No newline at end of file diff --git a/Hotfix/Social/Mail/Handler/C2S_DeleteMailRequestHandler.cs b/Hotfix/Social/Mail/Handler/C2S_DeleteMailRequestHandler.cs new file mode 100644 index 0000000..65e0354 --- /dev/null +++ b/Hotfix/Social/Mail/Handler/C2S_DeleteMailRequestHandler.cs @@ -0,0 +1,44 @@ +using Fantasy; +using Fantasy.Async; +using Fantasy.Network.Interface; + +namespace NB.Chat; + +public class C2S_DeleteMailRequestHandler : RouteRPC +{ + protected override async FTask Run(SocialUnit entity, C2S_DeleteMailRequest request, + S2C_DeleteMailResponse response, Action reply) + { + if (request.Id < 1) + { + response.ErrorCode = ErrorCode.ErrArgs; + return; + } + + var mailManageComponent = entity.Scene.GetComponent(); + if (mailManageComponent == null) + { + Log.Error("组件不存在 MailManageComponent"); + response.ErrorCode = ErrorCode.ErrServer; + return; + } + + var conversation = await mailManageComponent.GetConversation(entity.Id, request.Id); + if (conversation == null) + { + response.ErrorCode = ErrorCode.ErrArgs; + return; + } + + conversation.RemoveId.Add(entity.Id); + if (conversation.RemoveId.Count > 1) + { + //都删除了,则吧会话直接移除掉 + await mailManageComponent.DeleteConversation(entity.Id, request.Id); + } + else + { + await conversation.Save(); + } + } +} \ No newline at end of file diff --git a/Hotfix/Social/Mail/Handler/C2S_GetConversationsRequestHandler.cs b/Hotfix/Social/Mail/Handler/C2S_GetConversationsRequestHandler.cs new file mode 100644 index 0000000..e505a05 --- /dev/null +++ b/Hotfix/Social/Mail/Handler/C2S_GetConversationsRequestHandler.cs @@ -0,0 +1,22 @@ +using System.Diagnostics; +using Fantasy; +using Fantasy.Async; +using Fantasy.Network.Interface; + +namespace NB.Chat; + +public class + C2S_GetConversationsRequestHandler : RouteRPC +{ + protected override async FTask Run(SocialUnit entity, C2S_GetConversationsRequest request, + S2C_GetConversationsResponse response, Action reply) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var mailManageComponent = entity.Scene.GetComponent(); + var list = await mailManageComponent.GetConversations(entity.Id); + response.List = await list.ToInfo(entity.Scene, entity.Id); + stopwatch.Stop(); + Log.Info($"查询会话列表耗时={stopwatch.ElapsedMilliseconds}"); + } +} \ No newline at end of file diff --git a/Hotfix/Social/Mail/Handler/C2S_SendMailRequestHandler.cs b/Hotfix/Social/Mail/Handler/C2S_SendMailRequestHandler.cs new file mode 100644 index 0000000..c16cc72 --- /dev/null +++ b/Hotfix/Social/Mail/Handler/C2S_SendMailRequestHandler.cs @@ -0,0 +1,68 @@ +using Fantasy; +using Fantasy.Async; +using Fantasy.Network.Interface; + +namespace NB.Chat; + +public class C2S_SendMailRequestHandler : RouteRPC +{ + protected override async FTask Run(SocialUnit entity, C2S_SendMailRequest request, S2C_SendMailResponse response, + Action reply) + { + if (request.Target < 1) + { + response.ErrorCode = ErrorCode.ErrArgs; + return; + } + + var mailManageComponent = entity.Scene.GetComponent(); + if (mailManageComponent == null) + { + Log.Error("组件不存在 MailManageComponent"); + response.ErrorCode = ErrorCode.ErrServer; + return; + } + + var chatUnitManage = entity.Scene.GetComponent(); + if (chatUnitManage == null) + { + Log.Error("组件不存在 SocialUnitManageComponent"); + response.ErrorCode = ErrorCode.ErrServer; + return; + } + + var conversation = await mailManageComponent.GetConversation(entity.Id, request.Target); + if (conversation == null) + { + response.ErrorCode = ErrorCode.ErrArgs; + return; + } + //检查是否可以发消息,如果会话只有一句,则不允许再发 + if (!conversation.CanSend(entity.Id)) + { + response.ErrorCode = ErrorCode.MailNotReply; + return; + } + + var mail = MailFactory.Create(entity.Scene, request.Content); + mail.Sender = entity.Id; + mail.OwnerId = request.Target; + await conversation.Add(mail); + + var res = new S2C_HaveMail() + { + Mail = mail.ToMailInfo(), + Key = conversation.Key + }; + //同步客户端 + entity.Scene.NetworkMessagingComponent.SendInnerRoute(entity.GateRouteId, res); + + var chatUnit = chatUnitManage.Get(request.Target); + + if (chatUnit != null) + { + //对方在线 + entity.Scene.NetworkMessagingComponent.SendInnerRoute(chatUnit.GateRouteId, res); + } + } +} \ No newline at end of file diff --git a/Hotfix/Game/Mail/Helper/MailBoxFactory.cs b/Hotfix/Social/Mail/Helper/MailBoxFactory.cs similarity index 89% rename from Hotfix/Game/Mail/Helper/MailBoxFactory.cs rename to Hotfix/Social/Mail/Helper/MailBoxFactory.cs index 5f5f7b8..c2c1a62 100644 --- a/Hotfix/Game/Mail/Helper/MailBoxFactory.cs +++ b/Hotfix/Social/Mail/Helper/MailBoxFactory.cs @@ -1,8 +1,9 @@ using Fantasy; using Fantasy.Entitas; using Fantasy.Helper; +using NB.Game; -namespace NB.Game; +namespace NB.Chat; public static class MailBoxFactory { @@ -42,14 +43,13 @@ public static class MailBoxFactory /// /// /// - /// /// /// /// - public static MailBox Create(Scene scene, long sendAccountId, int expireTime, List accountIds, string title, + public static MailBox Create(Scene scene, long sendAccountId, int expireTime, List accountIds, string content, List items = null) { - var mail = MailFactory.Create(scene, title, content, items); + var mail = MailFactory.Create(scene, content, items); return Create(scene, sendAccountId, mail, expireTime, accountIds); } } \ No newline at end of file diff --git a/Hotfix/Social/Mail/Helper/MailConversationHelper.cs b/Hotfix/Social/Mail/Helper/MailConversationHelper.cs new file mode 100644 index 0000000..e6c89d7 --- /dev/null +++ b/Hotfix/Social/Mail/Helper/MailConversationHelper.cs @@ -0,0 +1,38 @@ +using Fantasy; +using Fantasy.Async; +using NB.Game; + +namespace NB.Chat; + +public static class MailConversationHelper +{ + /// + /// 从数据库中读取GameAccount + /// + /// + /// + /// + /// + public static async FTask LoadDataBase(Scene scene, long firstId, long secondId) + { + var conversation = + await scene.World.DataBase.First(d => d.FirstId == firstId && d.SecondId == secondId); + if (conversation == null) + { + return null; + } + + conversation.Deserialize(scene); + return conversation; + } + + /// + /// 从数据库中移除 + /// + /// + /// + public static async FTask DeleteDataBase(Scene scene,long id) + { + await scene.World.DataBase.Remove(id); + } +} \ No newline at end of file diff --git a/Hotfix/Game/Mail/Helper/MailFactory.cs b/Hotfix/Social/Mail/Helper/MailFactory.cs similarity index 81% rename from Hotfix/Game/Mail/Helper/MailFactory.cs rename to Hotfix/Social/Mail/Helper/MailFactory.cs index b43a4b1..e6a17c5 100644 --- a/Hotfix/Game/Mail/Helper/MailFactory.cs +++ b/Hotfix/Social/Mail/Helper/MailFactory.cs @@ -2,17 +2,17 @@ using Fantasy.Entitas; using Fantasy.Helper; using Fantasy.Serialize; +using NB.Game; -namespace NB.Game; +namespace NB.Chat; public static class MailFactory { private static readonly ISerialize _serializer = SerializerManager.GetSerializer(FantasySerializerType.Bson); - public static Mail Create(Scene scene, string title, string content, List items = null) + public static Mail Create(Scene scene, string content, List items = null) { var mail = Entity.Create(scene, true, true); - mail.Title = title; mail.Content = content; mail.State = MailState.Unread; mail.CreateTime = TimeHelper.Now; diff --git a/Hotfix/Game/Mail/Helper/MailHelper.cs b/Hotfix/Social/Mail/Helper/MailHelper.cs similarity index 95% rename from Hotfix/Game/Mail/Helper/MailHelper.cs rename to Hotfix/Social/Mail/Helper/MailHelper.cs index 1e0aa09..3ae20fd 100644 --- a/Hotfix/Game/Mail/Helper/MailHelper.cs +++ b/Hotfix/Social/Mail/Helper/MailHelper.cs @@ -1,13 +1,14 @@ using Fantasy; using Fantasy.Async; -namespace NB.Game; +namespace NB.Chat; /// /// 发送邮件接口 /// public static class MailHelper { + public static async FTask Send(Scene scene, MailBox mailBox) { if (mailBox.BoxType == MailBoxType.None) diff --git a/Hotfix/Game/Mail/Entity/MailBoxSystem.cs b/Hotfix/Social/Mail/System/MailBoxSystem.cs similarity index 96% rename from Hotfix/Game/Mail/Entity/MailBoxSystem.cs rename to Hotfix/Social/Mail/System/MailBoxSystem.cs index c16daa1..0019f06 100644 --- a/Hotfix/Game/Mail/Entity/MailBoxSystem.cs +++ b/Hotfix/Social/Mail/System/MailBoxSystem.cs @@ -1,6 +1,6 @@ using Fantasy.Entitas.Interface; -namespace NB.Game; +namespace NB.Chat; public class MailBoxDestroySystem : DestroySystem { diff --git a/Hotfix/Game/Mail/Components/MailComponentSystem.cs b/Hotfix/Social/Mail/System/MailComponentSystem.cs similarity index 96% rename from Hotfix/Game/Mail/Components/MailComponentSystem.cs rename to Hotfix/Social/Mail/System/MailComponentSystem.cs index e647123..354866c 100644 --- a/Hotfix/Game/Mail/Components/MailComponentSystem.cs +++ b/Hotfix/Social/Mail/System/MailComponentSystem.cs @@ -3,7 +3,7 @@ using Fantasy.Async; using Fantasy.Entitas.Interface; using Fantasy.Helper; -namespace NB.Game; +namespace NB.Chat; public class MailComponentDestroySystem : DestroySystem { @@ -42,7 +42,7 @@ public static class MailComponentSystem if (sync) { //同步客户端 - self.Scene.NetworkMessagingComponent.SendInnerRoute(0,new Game2C_HaveMail() + self.Scene.NetworkMessagingComponent.SendInnerRoute(0,new S2C_HaveMail() { Mail = mail.ToMailInfo(), }); @@ -65,7 +65,7 @@ public static class MailComponentSystem if (sync) { //同步客户端 - self.Scene.NetworkMessagingComponent.SendInnerRoute(0,new Game2C_MailState() + self.Scene.NetworkMessagingComponent.SendInnerRoute(0,new S2C_MailState() { MailState = (int)MailState.Deleted, MailId = mailId, diff --git a/Hotfix/Social/Mail/System/MailConversationSystem.cs b/Hotfix/Social/Mail/System/MailConversationSystem.cs new file mode 100644 index 0000000..96c5abf --- /dev/null +++ b/Hotfix/Social/Mail/System/MailConversationSystem.cs @@ -0,0 +1,126 @@ +using Fantasy; +using Fantasy.Async; +using Fantasy.Entitas.Interface; +using Fantasy.Helper; +using NB.Game; + +namespace NB.Chat; + +public class MailConversationDeserializeSystem : DeserializeSystem +{ + protected override void Deserialize(MailConversation self) + { + self.Key = $"{self.FirstId}-{self.SecondId}"; + } +} + +public class MailConversationDestroySystem : DestroySystem +{ + protected override void Destroy(MailConversation self) + { + foreach (var mail in self.Mails) + { + mail.Dispose(); + } + + self.Mails.Clear(); + self.FirstId = 0; + self.SecondId = 0; + self.Key = string.Empty; + } +} + +public static class MailConversationSystem +{ + public static async FTask Add(this MailConversation self, Mail mail) + { + self.Mails.Add(mail); + if (self.Mails.Count > AppConfig.MaxConversationCount) + { + self.Mails.RemoveAt(0); + } + + if (mail.Items != null && mail.Items.Count > 0) + { + //有附件需要立马保存 + await self.Save(true); + } + else + { + await self.Save(false); + } + } + + public static async FTask Save(this MailConversation self, bool forceSave = true) + { + // self.NeedSave = true; + // self.NeedSaveTime = TimeHelper.Now + AppConfig.PlayerDataAutoSaveTime; + if (forceSave) + { + self.UpdateTime = TimeHelper.Now; + await self.Scene.World.DataBase.Save(self); + } + else + { + self.NeedSave = true; + self.NeedSaveTime = TimeHelper.Now + AppConfig.ChatDataAutoSaveTime; + } + } + + /// + /// 是否可以发送邮件 + /// + /// + /// + /// + public static bool CanSend(this MailConversation self, long sendId) + { + if (self.Mails.Count < 1) return true; + foreach (var mail in self.Mails) + { + if (mail.Sender != sendId) + { + return true; + } + } + + return false; + } + + #region 转换 + + public static async FTask> ToInfo(this List self, Scene scene, long selfId) + { + List ret = new List(); + HashSet ids = new HashSet(); + foreach (var conversation in self) + { + if (conversation.RemoveId.Contains(selfId)) continue; + ids.Add(conversation.FirstId); + ids.Add(conversation.SecondId); + } + + ids.Remove(selfId); + + var infos = await CacheHandler.GetPlayerBasicCacheInfos(scene, ids.ToList()); + foreach (var conversation in self) + { + if (conversation.RemoveId.Contains(selfId)) continue; + var item = new ConversationInfo(); + item.List = conversation.Mails.ToMailInfo(); + var otherId = conversation.FirstId == selfId ? conversation.SecondId : conversation.FirstId; + var info = infos.Find(t => t.RoleId == otherId); + if (info != null) + { + item.RoleInfo = info; + } + + ret.Add(item); + } + + + return ret; + } + + #endregion +} \ No newline at end of file diff --git a/Hotfix/Social/Mail/System/MailManageComponentSystem.cs b/Hotfix/Social/Mail/System/MailManageComponentSystem.cs new file mode 100644 index 0000000..eed9fb4 --- /dev/null +++ b/Hotfix/Social/Mail/System/MailManageComponentSystem.cs @@ -0,0 +1,93 @@ +using Fantasy; +using Fantasy.Async; +using Fantasy.Entitas; +using Fantasy.Entitas.Interface; +using Fantasy.Helper; +using NB.Game; + +namespace NB.Chat; + +public class MailManageComponentDestroySystem : DestroySystem +{ + protected override void Destroy(MailManageComponent self) + { + foreach (var (_, conversation) in self.Conversations) + { + conversation.Dispose(); + } + + self.Conversations.Clear(); + } +} + +public static class MailManageComponentSystem +{ + public static async FTask DeleteConversation(this MailManageComponent self, long selfId, long otherId) + { + var firstId = selfId; + var secondId = otherId; + if (otherId < selfId) + { + firstId = otherId; + secondId = selfId; + } + + var key = $"{firstId}-{secondId}"; + + if (self.Conversations.Remove(key, out var conversation)) + { + await MailConversationHelper.DeleteDataBase(conversation.Scene, conversation.Id); + conversation.Dispose(); + } + } + + public static async FTask GetConversation(this MailManageComponent self, long selfId, + long otherId) + { + var firstId = selfId; + var secondId = otherId; + if (otherId < selfId) + { + firstId = otherId; + secondId = selfId; + } + + var key = $"{firstId}-{secondId}"; + if (!self.Conversations.TryGetValue(key, out var conversation)) + { + //检查数据库中是否存在 + conversation = await MailConversationHelper.LoadDataBase(self.Scene, firstId, secondId); + if (conversation == null) + { + //检查id是否合法 + var roleInfo = await CacheHandler.GetPlayerBasicCacheInfo(self.Scene, otherId); + if (roleInfo == null) + { + return null; + } + + conversation = Entity.Create(self.Scene, true, true); + + conversation.FirstId = firstId; + conversation.SecondId = secondId; + + conversation.Key = key; + await conversation.Save(false); + } + + self.Conversations.Add(key, conversation); + } + + return conversation; + } + + public static async FTask> GetConversations(this MailManageComponent self, long id) + { + List players = + await self.Scene.World.DataBase.QueryByPageOrderBy( + d => d.FirstId == id || d.SecondId == id, 1, 50, + d => d.UpdateTime); + + return players; + } +} \ No newline at end of file diff --git a/Hotfix/Game/Mail/Entity/MailSystem.cs b/Hotfix/Social/Mail/System/MailSystem.cs similarity index 89% rename from Hotfix/Game/Mail/Entity/MailSystem.cs rename to Hotfix/Social/Mail/System/MailSystem.cs index c754982..aae7ca0 100644 --- a/Hotfix/Game/Mail/Entity/MailSystem.cs +++ b/Hotfix/Social/Mail/System/MailSystem.cs @@ -1,14 +1,15 @@ using Fantasy; using Fantasy.Entitas.Interface; +using NB.Game; -namespace NB.Game; +namespace NB.Chat; public class MailDestroySystem : DestroySystem { protected override void Destroy(Mail self) { self.OwnerId = 0; - self.Title = string.Empty; + self.Sender = 0; self.Content = string.Empty; self.ExpireTime = 0; self.CreateTime = 0; @@ -30,9 +31,7 @@ public static class MailSystem 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, diff --git a/Server.sln.DotSettings.user b/Server.sln.DotSettings.user index f98cd84..b23042f 100644 --- a/Server.sln.DotSettings.user +++ b/Server.sln.DotSettings.user @@ -24,8 +24,10 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -36,6 +38,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -44,6 +47,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded diff --git a/Tools/ProtocolTest/test002/Protocol/C2S_DeleteMailRequest b/Tools/ProtocolTest/test002/Protocol/C2S_DeleteMailRequest new file mode 100644 index 0000000..980ca7a --- /dev/null +++ b/Tools/ProtocolTest/test002/Protocol/C2S_DeleteMailRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002,"Id":331929091475505154} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2S_GetConversationsRequest b/Tools/ProtocolTest/test002/Protocol/C2S_GetConversationsRequest new file mode 100644 index 0000000..dcc6071 --- /dev/null +++ b/Tools/ProtocolTest/test002/Protocol/C2S_GetConversationsRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2S_SendMailRequest b/Tools/ProtocolTest/test002/Protocol/C2S_SendMailRequest new file mode 100644 index 0000000..429d3fa --- /dev/null +++ b/Tools/ProtocolTest/test002/Protocol/C2S_SendMailRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002,"Target":337951357380329486,"Content":"\u5206\u516C\u53F8\u7535\u996D\u9505\u7535\u996D\u9505"} \ No newline at end of file diff --git a/Tools/ProtocolTest/test003/Protocol/C2S_SendMailRequest b/Tools/ProtocolTest/test003/Protocol/C2S_SendMailRequest new file mode 100644 index 0000000..3d9c462 --- /dev/null +++ b/Tools/ProtocolTest/test003/Protocol/C2S_SendMailRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002,"Target":324468767642091522,"Content":"\u7B2C\u4E09\u65B9\u7B2C\u4E09\u65B9\u4EE3\u53D1111"} \ No newline at end of file