新增私聊相关

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

View File

@@ -11,4 +11,14 @@ public class AppConfig
/// 玩家数据定时落地间隔
/// </summary>
public const long PlayerDataAutoSaveTime = 60000; // 600000;
/// <summary>
/// 聊天数据自动保存间隔
/// </summary>
public const long ChatDataAutoSaveTime = 6000;
/// <summary>
/// 最大保留对话记录数
/// </summary>
public const long MaxConversationCount = 20;
}

View File

@@ -25,13 +25,13 @@
<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.12.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.12.1" />
<PackageReference Include="ToolGood.Words" Version="3.1.0.2" />
</ItemGroup>
<ItemGroup>
<Folder Include="Social\Entity\" />
<Folder Include="Social\Mail\" />
<Folder Include="Generate\NetworkProtocol\" />
<Folder Include="Map\" />
</ItemGroup>
</Project>

View File

@@ -24,11 +24,7 @@ public class PlayerBasicCache : Entity
/// 等级
/// </summary>
public int Level;
/// <summary>
/// 当前经验
/// </summary>
public int Exp;
/// <summary>
/// 是否是vip

View File

@@ -5,4 +5,9 @@ namespace NB.Game;
public class PlayerBasicCacheManageComponent : Entity
{
public readonly Dictionary<long, PlayerBasicCache> Players = new();
/// <summary>
/// 定时检查定时器id
/// </summary>
public long checkTimerId;
}

View File

@@ -4,6 +4,9 @@ using MongoDB.Bson.Serialization.Options;
namespace NB.Game;
/// <summary>
/// 玩家基本数据
/// </summary>
public sealed class Player : Entity
{
/// <summary>
@@ -37,39 +40,15 @@ public sealed class Player : Entity
[BsonElement("vip")] public bool IsVip;
/// <summary>
/// 统计信息
/// 星数
/// </summary>
[BsonElement("stat")] public PlayerStatistics Statistics;
[BsonElement("star")] public int Star;
/// <summary>
/// 角色vip信息
/// 高光数
/// </summary>
[BsonElement("vInfo")] public PlayerVip Vip;
[BsonElement("high")] public int Highlight;
/// <summary>
/// 钱包
/// </summary>
[BsonElement("wallet")] public PlayerWallet Wallet;
/// <summary>
/// 背包
/// </summary>
[BsonElement("bag")] public ItemContainer ItemContainer;
/// <summary>
/// 鱼护
/// </summary>
[BsonElement("fish")] public FishContainer FishContainer;
/// <summary>
/// 技能
/// </summary>
[BsonElement("skill")] public SkillContainer SkillContainer;
/// <summary>
/// 成就
/// </summary>
[BsonElement("achievement")] public AchievementContainer AchievementContainer;
[BsonIgnore] public long SessionRunTimeId;

View File

@@ -0,0 +1,40 @@
using Fantasy.Entitas;
using MongoDB.Bson.Serialization.Attributes;
namespace NB.Game;
/// <summary>
/// 用户核心信息
/// </summary>
public class PlayerPrivate : Entity
{
/// <summary>
/// 角色vip信息
/// </summary>
[BsonElement("vInfo")] public PlayerVip Vip;
/// <summary>
/// 钱包
/// </summary>
[BsonElement("wallet")] public PlayerWallet Wallet;
/// <summary>
/// 背包
/// </summary>
[BsonElement("bag")] public ItemContainer ItemContainer;
/// <summary>
/// 鱼护
/// </summary>
[BsonElement("fish")] public FishContainer FishContainer;
/// <summary>
/// 技能
/// </summary>
[BsonElement("skill")] public SkillContainer SkillContainer;
/// <summary>
/// 成就
/// </summary>
[BsonElement("achievement")] public AchievementContainer AchievementContainer;
}

View File

@@ -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<MailInfo>();
}
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<MailInfo>(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<AwardInfo> Items = new List<AwardInfo>();
}
}

View File

@@ -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;

View File

@@ -18,51 +18,210 @@ using Fantasy.Serialize;
namespace Fantasy
{
/// <summary>
/// /////////// ******** 邮件 *******/////////////
/// /////////// ******** 私聊/邮件 *******/////////////
/// </summary>
/// <summary>
/// 请求邮件列表
/// 会话信息
/// </summary>
[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<C2Game_GetMailsRequest>();
return scene.MessagePoolComponent.Rent<ConversationInfo>();
}
public override void Dispose()
{
RoleInfo = default;
List.Clear();
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<ConversationInfo>(this);
#endif
}
[ProtoMember(1)]
public RoleSimpleInfo RoleInfo { get; set; }
[ProtoMember(2)]
public List<MailInfo> List = new List<MailInfo>();
}
[ProtoContract]
public partial class MailInfo : AMessage, IProto
{
public static MailInfo Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<MailInfo>();
}
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<MailInfo>(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<AwardInfo> Items = new List<AwardInfo>();
}
/// <summary>
/// 请求会话列表
/// </summary>
[ProtoContract]
public partial class C2S_GetConversationsRequest : AMessage, ICustomRouteRequest, IProto
{
public static C2S_GetConversationsRequest Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<C2S_GetConversationsRequest>();
}
public override void Dispose()
{
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<C2Game_GetMailsRequest>(this);
GetScene().MessagePoolComponent.Return<C2S_GetConversationsRequest>(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;
}
/// <summary>
/// 获取邮件列表响应
/// 请求会话列表响应
/// </summary>
[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<Game2C_GetMailsResponse>();
return scene.MessagePoolComponent.Rent<S2C_GetConversationsResponse>();
}
public override void Dispose()
{
ErrorCode = default;
Mail.Clear();
List.Clear();
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<Game2C_GetMailsResponse>(this);
GetScene().MessagePoolComponent.Return<S2C_GetConversationsResponse>(this);
#endif
}
public uint OpCode() { return OuterOpcode.Game2C_GetMailsResponse; }
public uint OpCode() { return OuterOpcode.S2C_GetConversationsResponse; }
[ProtoMember(1)]
public List<MailInfo> Mail = new List<MailInfo>();
public List<ConversationInfo> List = new List<ConversationInfo>();
[ProtoMember(2)]
public uint ErrorCode { get; set; }
}
/// <summary>
/// 发送邮件消息
/// </summary>
[ProtoContract]
public partial class C2S_SendMailRequest : AMessage, ICustomRouteRequest, IProto
{
public static C2S_SendMailRequest Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<C2S_SendMailRequest>();
}
public override void Dispose()
{
Target = default;
Content = default;
Items.Clear();
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<C2S_SendMailRequest>(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<AwardInfo> Items = new List<AwardInfo>();
}
/// <summary>
/// 发送邮件消息响应
/// </summary>
[ProtoContract]
public partial class S2C_SendMailResponse : AMessage, ICustomRouteResponse, IProto
{
public static S2C_SendMailResponse Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<S2C_SendMailResponse>();
}
public override void Dispose()
{
ErrorCode = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<S2C_SendMailResponse>(this);
#endif
}
public uint OpCode() { return OuterOpcode.S2C_SendMailResponse; }
[ProtoMember(1)]
public uint ErrorCode { get; set; }
}
/// <summary>
/// 发送删除会话消息
/// </summary>
[ProtoContract]
public partial class C2S_DeleteMailRequest : AMessage, ICustomRouteRequest, IProto
{
public static C2S_DeleteMailRequest Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<C2S_DeleteMailRequest>();
}
public override void Dispose()
{
Id = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<C2S_DeleteMailRequest>(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; }
}
/// <summary>
/// 发送删除会话消息响应
/// </summary>
[ProtoContract]
public partial class S2C_DeleteMailResponse : AMessage, ICustomRouteResponse, IProto
{
public static S2C_DeleteMailResponse Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<S2C_DeleteMailResponse>();
}
public override void Dispose()
{
ErrorCode = default;
Id = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<S2C_DeleteMailResponse>(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
/// 新邮件推送
/// </summary>
[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<Game2C_HaveMail>();
return scene.MessagePoolComponent.Rent<S2C_HaveMail>();
}
public override void Dispose()
{
Mail = default;
Key = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<Game2C_HaveMail>(this);
GetScene().MessagePoolComponent.Return<S2C_HaveMail>(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<Game2C_MailState>();
return scene.MessagePoolComponent.Rent<S2C_MailState>();
}
public override void Dispose()
{
MailState = default;
MailId = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<Game2C_MailState>(this);
GetScene().MessagePoolComponent.Return<S2C_MailState>(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; }
}
/// <summary>
/// /////////// ******** 聊天 *******/////////////
/// /////////// ******** 频道聊天 *******/////////////
/// </summary>
[ProtoContract]
public partial class ChatUserInfo : AMessage, IProto
@@ -260,7 +422,7 @@ namespace Fantasy
public uint ErrorCode { get; set; }
}
/// <summary>
/// 发送聊天
/// 发送消息
/// </summary>
[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; }
}
/// <summary>
/// 发送聊天响应
/// 发送消息响应
/// </summary>
[ProtoContract]
public partial class S2C_SendMessageResponse : AMessage, ICustomRouteResponse, IProto
@@ -312,61 +471,6 @@ namespace Fantasy
public uint ErrorCode { get; set; }
}
/// <summary>
/// 发送聊天
/// </summary>
[ProtoContract]
public partial class C2S_GetOfflineMessageRequest : AMessage, ICustomRouteRequest, IProto
{
public static C2S_GetOfflineMessageRequest Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<C2S_GetOfflineMessageRequest>();
}
public override void Dispose()
{
Type = default;
Message = default;
Target = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<C2S_GetOfflineMessageRequest>(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; }
}
/// <summary>
/// 发送聊天响应
/// </summary>
[ProtoContract]
public partial class S2C_GetOfflineMessageResponse : AMessage, ICustomRouteResponse, IProto
{
public static S2C_GetOfflineMessageResponse Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<S2C_GetOfflineMessageResponse>();
}
public override void Dispose()
{
ErrorCode = default;
Message.Clear();
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<S2C_GetOfflineMessageResponse>(this);
#endif
}
public uint OpCode() { return OuterOpcode.S2C_GetOfflineMessageResponse; }
[ProtoMember(1)]
public List<ChatMessageInfo> Message = new List<ChatMessageInfo>();
[ProtoMember(2)]
public uint ErrorCode { get; set; }
}
/// <summary>
/// 推送消息
/// </summary>
[ProtoContract]
@@ -390,58 +494,6 @@ namespace Fantasy
public ChatMessageInfo Message { get; set; }
}
/// <summary>
/// 获取聊天记录请求
/// </summary>
[ProtoContract]
public partial class C2S_GetChatRecordRequest : AMessage, ICustomRouteRequest, IProto
{
public static C2S_GetChatRecordRequest Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<C2S_GetChatRecordRequest>();
}
public override void Dispose()
{
Target = default;
Type = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<C2S_GetChatRecordRequest>(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; }
}
/// <summary>
/// 获取聊天记录响应
/// </summary>
[ProtoContract]
public partial class S2C_GetChatRecordResponse : AMessage, ICustomRouteResponse, IProto
{
public static S2C_GetChatRecordResponse Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<S2C_GetChatRecordResponse>();
}
public override void Dispose()
{
ErrorCode = default;
Messages.Clear();
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<S2C_GetChatRecordResponse>(this);
#endif
}
public uint OpCode() { return OuterOpcode.S2C_GetChatRecordResponse; }
[ProtoMember(1)]
public List<ChatMessageInfo> Messages = new List<ChatMessageInfo>();
[ProtoMember(2)]
public uint ErrorCode { get; set; }
}
/// <summary>
/// /////////// ******** 工会 *******/////////////
/// </summary>
[ProtoContract]

34
Entity/Map/MapRoom.cs Normal file
View File

@@ -0,0 +1,34 @@
using Fantasy.Entitas;
namespace NB.Map;
/// <summary>
/// 地图房间
/// </summary>
public class MapRoom : Entity
{
/// <summary>
/// 房间密码
/// </summary>
public string Password;
/// <summary>
/// 房间玩家
/// </summary>
public Dictionary<long, MapUnit> Units = new Dictionary<long, MapUnit>();
/// <summary>
/// 房主
/// </summary>
public long Owner;
/// <summary>
/// 创建时间
/// </summary>
public long CreateTime;
/// <summary>
/// 房间地图
/// </summary>
public int Map;
}

10
Entity/Map/MapUnit.cs Normal file
View File

@@ -0,0 +1,10 @@
using Fantasy.Entitas;
namespace NB.Map;
/// <summary>
/// 地图玩家单元
/// </summary>
public class MapUnit : Entity
{
}

View File

@@ -44,4 +44,9 @@ public class ErrorCode
/// 聊天频道不存在
/// </summary>
public const uint ChatNotChannel = 12011;
/// <summary>
/// 没回复前不能再发消息
/// </summary>
public const uint MailNotReply = 12021;
}

View File

@@ -4,7 +4,7 @@ using Fantasy.Helper;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Options;
namespace NB.Game;
namespace NB.Chat;
/// <summary>
/// 玩家邮件组件

View File

@@ -0,0 +1,19 @@
using Fantasy.Entitas;
namespace NB.Chat;
/// <summary>
/// 邮件管理组件
/// </summary>
public class MailManageComponent : Entity
{
/// <summary>
/// 会话列表
/// </summary>
public Dictionary<string, MailConversation> Conversations = new Dictionary<string, MailConversation>();
/// <summary>
/// 缓存了的列表
/// </summary>
public HashSet<long> CacheRoleIds = new HashSet<long>();
}

View File

@@ -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
{
/// <summary>
/// 邮件发送者
/// </summary>
[BsonElement("send")] public long Sender;
/// <summary>
/// 邮件拥有者
/// </summary>
public long OwnerId;
[BsonElement("owner")] public long OwnerId;
/// <summary>
/// 邮件状态
/// </summary>
public MailState State = MailState.None;
[BsonElement("state")] public MailState State = MailState.None;
/// <summary>
/// 邮件状态
/// </summary>
public MailType MailType = MailType.None;
/// <summary>
/// 邮件标题
/// </summary>
public string Title;
[BsonElement("type")] public MailType MailType = MailType.None;
/// <summary>
/// 邮件内容
/// </summary>
public string Content;
[BsonElement("con")] public string Content;
/// <summary>
/// 创建时间
/// </summary>
public long CreateTime;
[BsonElement("ct")] public long CreateTime;
/// <summary>
/// 过期时间
/// </summary>
public long ExpireTime;
[BsonElement("et")] public long ExpireTime;
/// <summary>
/// 邮件的附件内容
/// </summary>
public List<AwardItem> Items = new List<AwardItem>();
[BsonElement("item")] public List<AwardItem> Items = new List<AwardItem>();
}

View File

@@ -1,7 +1,10 @@
using Fantasy.Entitas;
namespace NB.Game;
namespace NB.Chat;
/// <summary>
/// 邮件箱,系统群发用
/// </summary>
public class MailBox : Entity
{
/// <summary>

View File

@@ -0,0 +1,57 @@
using Fantasy.Entitas;
using MongoDB.Bson.Serialization.Attributes;
namespace NB.Chat;
public class MailConversation : Entity
{
/// <summary>
/// 第一id
/// </summary>
[BsonElement("id1")] public long FirstId;
/// <summary>
/// 第二id
/// </summary>
[BsonElement("id2")] public long SecondId;
/// <summary>
/// 会话
/// </summary>
[BsonElement("list")] public List<Mail> Mails = new List<Mail>();
/// <summary>
/// 第一个阅读时间
/// </summary>
[BsonElement("ft")] public long FirstReadTime;
/// <summary>
/// 第二阅读时间
/// </summary>
[BsonElement("st")] public long SecondReadTime;
/// <summary>
/// 最后更新时间
/// </summary>
[BsonElement("ut")] public long UpdateTime;
/// <summary>
/// 删除人标志
/// </summary>
[BsonElement("rid")] public HashSet<long> RemoveId = new HashSet<long>();
/// <summary>
/// 会话keyid-id按大小排序
/// </summary>
[BsonIgnore] public string Key = string.Empty;
/// <summary>
/// 最后保存时间
/// </summary>
[BsonIgnore] public long NeedSaveTime = 0;
/// <summary>
/// 需要保存
/// </summary>
[BsonIgnore] public bool NeedSave;
}

View File

@@ -1,4 +1,4 @@
namespace NB.Game;
namespace NB.Chat;
public enum MailType
{

View File

@@ -8,8 +8,9 @@ public class SocialUnitManageComponent : Entity
{
public readonly Dictionary<long, SocialUnit> Units = new();
/// <summary>
/// 不在线消息缓存
/// </summary>
public readonly OneToManyList<long, ChatMessageInfo> NotSendMessage = new();
// public List<MailBox>
// /// <summary>
// /// 不在线消息缓存
// /// </summary>
// public readonly OneToManyList<long, ChatMessageInfo> NotSendMessage = new();
}