diff --git a/Config/NetworkProtocol/Inner/InnerMessage.proto b/Config/NetworkProtocol/Inner/InnerMessage.proto index 44a945b..3c79a91 100644 --- a/Config/NetworkProtocol/Inner/InnerMessage.proto +++ b/Config/NetworkProtocol/Inner/InnerMessage.proto @@ -12,10 +12,21 @@ message Game2G_EnterResponse // IRouteResponse int64 RoleRouteId = 1; //角色实体的路由id RoleSimpleInfo RoleInfo = 2; //角色信息 } +message G2Game_ExitRequest // IRouteRequest,Game2G_ExitResponse +{ + int64 AccountId = 1; //账号id + int64 GateRouteId = 2;//网关路由地址 +} + +message Game2G_ExitResponse // IRouteResponse +{ +} + + ///通知游戏服角色进入该聊天服 -message G2Chat_EnterRequest // IRouteRequest,Game2G_EnterResponse +message G2Chat_EnterRequest // IRouteRequest,Chat2G_EnterResponse { RoleSimpleInfo Role = 1; //角色信息 int64 GateRouteId = 2;//网关路由地址 @@ -26,9 +37,22 @@ message Chat2G_EnterResponse // IRouteResponse int64 RoleRouteId = 1; //角色实体的路由id } +message G2Chat_ExitRequest // IRouteRequest,Chat2G_ExitResponse +{ + int64 AccountId = 1; //账号id + int64 GateRouteId = 2;//网关路由地址 +} + +message Chat2G_ExitResponse // IRouteResponse +{ + +} + + message Chat2G_ChatMessage // IRouteMessage { ChatMessageInfo Message = 1; //聊天内容 + repeated int64 IdList = 2; // 群发列表 } ///创建聊天频道 diff --git a/Config/NetworkProtocol/Outer/ChatMessage.proto b/Config/NetworkProtocol/Outer/ChatMessage.proto index fd97047..792251b 100644 --- a/Config/NetworkProtocol/Outer/ChatMessage.proto +++ b/Config/NetworkProtocol/Outer/ChatMessage.proto @@ -65,6 +65,18 @@ message Caht2C_SendMessageResponse // ICustomRouteResponse } +///获取离线时的未读私聊 +message C2Chat_GetOfflineMessageRequest // ICustomRouteRequest,Caht2C_GetOfflineMessageResponse,ChatRoute +{ + +} + +///发送聊天响应 +message Caht2C_GetOfflineMessageResponse // ICustomRouteResponse +{ + repeated ChatMessageInfo Message = 1; +} + ///推送消息 message Chat2C_Message // ICustomRouteMessage,ChatRoute { diff --git a/Config/NetworkProtocol/Outer/SocialMessage.proto b/Config/NetworkProtocol/Outer/SocialMessage.proto index 9f85331..eb4abf7 100644 --- a/Config/NetworkProtocol/Outer/SocialMessage.proto +++ b/Config/NetworkProtocol/Outer/SocialMessage.proto @@ -11,13 +11,13 @@ message ClubInfo } ///请求创建工会 -message C2S_CreateRequest // ICustomRouteRequest,Caht2C_GetChatRecordResponse,SocialRoute +message C2S_CreateClubRequest // ICustomRouteRequest,S2C_CreateClubResponse,SocialRoute { string Name = 1; //工会名称 } ///创建工会响应 -message S2C_CreateResponse // ICustomRouteResponse +message S2C_CreateClubResponse // ICustomRouteResponse { ClubInfo Club = 1; //创建的工会信息 } diff --git a/Config/NetworkProtocol/Outer/data/GlobalData.proto b/Config/NetworkProtocol/Outer/data/GlobalData.proto index c3f545f..4530562 100644 --- a/Config/NetworkProtocol/Outer/data/GlobalData.proto +++ b/Config/NetworkProtocol/Outer/data/GlobalData.proto @@ -10,7 +10,7 @@ message ChatUserInfo message ChatMessageInfo { int32 Type = 1; //消息类型 - int32 Source = 2; //消息来源 + int64 Source = 2; //消息来源 ChatUserInfo Trigger = 3; //触发者 string Content = 4; //内容 } \ No newline at end of file diff --git a/Entity/Chat/Component/ChatUnitManageComponent.cs b/Entity/Chat/Component/ChatUnitManageComponent.cs index 3d679e2..9fa5da8 100644 --- a/Entity/Chat/Component/ChatUnitManageComponent.cs +++ b/Entity/Chat/Component/ChatUnitManageComponent.cs @@ -1,8 +1,17 @@ -using Fantasy.Entitas; +using Fantasy; +using Fantasy.DataStructure.Collection; +using Fantasy.Entitas; namespace NB.Chat; public class ChatUnitManageComponent : Entity { public readonly Dictionary ChatUnits = new(); + + /// + /// 不在线消息缓存 + /// + public readonly OneToManyList NotSendMessage = new(); + + public readonly OneToManyList PrivateMessage = new(); } \ No newline at end of file diff --git a/Entity/Gate/GateUnitSessionComponent.cs b/Entity/Gate/GateUnitSessionComponent.cs index 88dcba7..1036a2b 100644 --- a/Entity/Gate/GateUnitSessionComponent.cs +++ b/Entity/Gate/GateUnitSessionComponent.cs @@ -5,4 +5,5 @@ namespace NB.Gate; public sealed class GateUnitSessionComponent : Entity { public long AccountID; + public long SessionId; } \ No newline at end of file diff --git a/Entity/Generate/NetworkProtocol/ChatMessage.cs b/Entity/Generate/NetworkProtocol/ChatMessage.cs index 26e34c5..9e608fd 100644 --- a/Entity/Generate/NetworkProtocol/ChatMessage.cs +++ b/Entity/Generate/NetworkProtocol/ChatMessage.cs @@ -260,6 +260,52 @@ namespace Fantasy public uint ErrorCode { get; set; } } /// + /// 获取离线时的未读私聊 + /// + [ProtoContract] + public partial class C2Chat_GetOfflineMessageRequest : AMessage, ICustomRouteRequest, IProto + { + public static C2Chat_GetOfflineMessageRequest Create(Scene scene) + { + return scene.MessagePoolComponent.Rent(); + } + public override void Dispose() + { +#if FANTASY_NET || FANTASY_UNITY + GetScene().MessagePoolComponent.Return(this); +#endif + } + [ProtoIgnore] + public Caht2C_GetOfflineMessageResponse ResponseType { get; set; } + public uint OpCode() { return OuterOpcode.C2Chat_GetOfflineMessageRequest; } + [ProtoIgnore] + public int RouteType => Fantasy.RouteType.ChatRoute; + } + /// + /// 发送聊天响应 + /// + [ProtoContract] + public partial class Caht2C_GetOfflineMessageResponse : AMessage, ICustomRouteResponse, IProto + { + public static Caht2C_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.Caht2C_GetOfflineMessageResponse; } + [ProtoMember(1)] + public List Message = new List(); + [ProtoMember(2)] + public uint ErrorCode { get; set; } + } + /// /// 推送消息 /// [ProtoContract] diff --git a/Entity/Generate/NetworkProtocol/GlobalData.cs b/Entity/Generate/NetworkProtocol/GlobalData.cs index 316cf4a..4b42718 100644 --- a/Entity/Generate/NetworkProtocol/GlobalData.cs +++ b/Entity/Generate/NetworkProtocol/GlobalData.cs @@ -57,7 +57,7 @@ namespace Fantasy [ProtoMember(1)] public int Type { get; set; } [ProtoMember(2)] - public int Source { get; set; } + public long Source { get; set; } [ProtoMember(3)] public ChatUserInfo Trigger { get; set; } [ProtoMember(4)] diff --git a/Entity/Generate/NetworkProtocol/InnerMessage.cs b/Entity/Generate/NetworkProtocol/InnerMessage.cs index 92003f5..28e4889 100644 --- a/Entity/Generate/NetworkProtocol/InnerMessage.cs +++ b/Entity/Generate/NetworkProtocol/InnerMessage.cs @@ -67,6 +67,47 @@ namespace Fantasy [ProtoMember(3)] public uint ErrorCode { get; set; } } + [ProtoContract] + public partial class G2Game_ExitRequest : AMessage, IRouteRequest, IProto + { + public static G2Game_ExitRequest Create(Scene scene) + { + return scene.MessagePoolComponent.Rent(); + } + public override void Dispose() + { + AccountId = default; + GateRouteId = default; +#if FANTASY_NET || FANTASY_UNITY + GetScene().MessagePoolComponent.Return(this); +#endif + } + [ProtoIgnore] + public Game2G_ExitResponse ResponseType { get; set; } + public uint OpCode() { return InnerOpcode.G2Game_ExitRequest; } + [ProtoMember(1)] + public long AccountId { get; set; } + [ProtoMember(2)] + public long GateRouteId { get; set; } + } + [ProtoContract] + public partial class Game2G_ExitResponse : AMessage, IRouteResponse, IProto + { + public static Game2G_ExitResponse 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 InnerOpcode.Game2G_ExitResponse; } + [ProtoMember(1)] + public uint ErrorCode { get; set; } + } /// /// 通知游戏服角色进入该聊天服 /// @@ -86,7 +127,7 @@ namespace Fantasy #endif } [ProtoIgnore] - public Game2G_EnterResponse ResponseType { get; set; } + public Chat2G_EnterResponse ResponseType { get; set; } public uint OpCode() { return InnerOpcode.G2Chat_EnterRequest; } [ProtoMember(1)] public RoleSimpleInfo Role { get; set; } @@ -115,6 +156,47 @@ namespace Fantasy public uint ErrorCode { get; set; } } [ProtoContract] + public partial class G2Chat_ExitRequest : AMessage, IRouteRequest, IProto + { + public static G2Chat_ExitRequest Create(Scene scene) + { + return scene.MessagePoolComponent.Rent(); + } + public override void Dispose() + { + AccountId = default; + GateRouteId = default; +#if FANTASY_NET || FANTASY_UNITY + GetScene().MessagePoolComponent.Return(this); +#endif + } + [ProtoIgnore] + public Chat2G_ExitResponse ResponseType { get; set; } + public uint OpCode() { return InnerOpcode.G2Chat_ExitRequest; } + [ProtoMember(1)] + public long AccountId { get; set; } + [ProtoMember(2)] + public long GateRouteId { get; set; } + } + [ProtoContract] + public partial class Chat2G_ExitResponse : AMessage, IRouteResponse, IProto + { + public static Chat2G_ExitResponse 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 InnerOpcode.Chat2G_ExitResponse; } + [ProtoMember(1)] + public uint ErrorCode { get; set; } + } + [ProtoContract] public partial class Chat2G_ChatMessage : AMessage, IRouteMessage, IProto { public static Chat2G_ChatMessage Create(Scene scene) @@ -124,6 +206,7 @@ namespace Fantasy public override void Dispose() { Message = default; + IdList.Clear(); #if FANTASY_NET || FANTASY_UNITY GetScene().MessagePoolComponent.Return(this); #endif @@ -131,6 +214,8 @@ namespace Fantasy public uint OpCode() { return InnerOpcode.Chat2G_ChatMessage; } [ProtoMember(1)] public ChatMessageInfo Message { get; set; } + [ProtoMember(2)] + public List IdList = new List(); } /// /// 创建聊天频道 diff --git a/Entity/Generate/NetworkProtocol/InnerOpcode.cs b/Entity/Generate/NetworkProtocol/InnerOpcode.cs index bd618a4..bbc80f6 100644 --- a/Entity/Generate/NetworkProtocol/InnerOpcode.cs +++ b/Entity/Generate/NetworkProtocol/InnerOpcode.cs @@ -4,8 +4,12 @@ namespace Fantasy { public const uint G2Game_EnterRequest = 1073751825; public const uint Game2G_EnterResponse = 1207969553; - public const uint G2Chat_EnterRequest = 1073751826; - public const uint Chat2G_EnterResponse = 1207969554; + public const uint G2Game_ExitRequest = 1073751826; + public const uint Game2G_ExitResponse = 1207969554; + public const uint G2Chat_EnterRequest = 1073751827; + public const uint Chat2G_EnterResponse = 1207969555; + public const uint G2Chat_ExitRequest = 1073751828; + public const uint Chat2G_ExitResponse = 1207969556; public const uint Chat2G_ChatMessage = 939534097; public const uint Club2Chat_CreateChannel = 939534098; } diff --git a/Entity/Generate/NetworkProtocol/OuterOpcode.cs b/Entity/Generate/NetworkProtocol/OuterOpcode.cs index cdfadff..82a8453 100644 --- a/Entity/Generate/NetworkProtocol/OuterOpcode.cs +++ b/Entity/Generate/NetworkProtocol/OuterOpcode.cs @@ -12,32 +12,34 @@ namespace Fantasy public const uint Caht2C_JoinChannelResponse = 2415929107; public const uint C2Chat_SendMessageRequest = 2281711380; public const uint Caht2C_SendMessageResponse = 2415929108; + public const uint C2Chat_GetOfflineMessageRequest = 2281711381; + public const uint Caht2C_GetOfflineMessageResponse = 2415929109; public const uint Chat2C_Message = 2147493651; - public const uint C2Chat_GetChatRecordRequest = 2281711381; - public const uint Caht2C_GetChatRecordResponse = 2415929109; + public const uint C2Chat_GetChatRecordRequest = 2281711382; + public const uint Caht2C_GetChatRecordResponse = 2415929110; public const uint C2A_LoginRequest = 268445457; public const uint A2C_LoginResponse = 402663185; public const uint C2G_LoginRequest = 268445458; public const uint G2C_LoginResponse = 402663186; public const uint G2C_RepeatLogin = 134227729; - public const uint C2Game_GetRoleInfoRequest = 2281711382; - public const uint Game2C_GetRoleInfoResponse = 2415929110; - public const uint C2S_CreateRequest = 2281711383; - public const uint S2C_CreateResponse = 2415929111; - public const uint C2S_GetClubInfoRequest = 2281711384; - public const uint S2C_GetClubInfoResponse = 2415929112; - public const uint C2S_GetMemberListRequest = 2281711385; - public const uint S2C_GetMemberListResponse = 2415929113; - public const uint C2S_GetClubListRequest = 2281711386; - public const uint S2C_GetClubListResponse = 2415929114; - public const uint C2S_JoinClubRequest = 2281711387; - public const uint S2C_JoinClubResponse = 2415929115; - public const uint C2S_LeaveClubRequest = 2281711388; - public const uint S2C_LeaveClubResponse = 2415929116; - public const uint C2S_DissolveClubRequest = 2281711389; - public const uint S2C_DissolveClubResponse = 2415929117; - public const uint C2S_DisposeJoinRequest = 2281711390; - public const uint S2C_DisposeJoinResponse = 2415929118; + public const uint C2Game_GetRoleInfoRequest = 2281711383; + public const uint Game2C_GetRoleInfoResponse = 2415929111; + public const uint C2S_CreateClubRequest = 2281711384; + public const uint S2C_CreateClubResponse = 2415929112; + public const uint C2S_GetClubInfoRequest = 2281711385; + public const uint S2C_GetClubInfoResponse = 2415929113; + public const uint C2S_GetMemberListRequest = 2281711386; + public const uint S2C_GetMemberListResponse = 2415929114; + public const uint C2S_GetClubListRequest = 2281711387; + public const uint S2C_GetClubListResponse = 2415929115; + public const uint C2S_JoinClubRequest = 2281711388; + public const uint S2C_JoinClubResponse = 2415929116; + public const uint C2S_LeaveClubRequest = 2281711389; + public const uint S2C_LeaveClubResponse = 2415929117; + public const uint C2S_DissolveClubRequest = 2281711390; + public const uint S2C_DissolveClubResponse = 2415929118; + public const uint C2S_DisposeJoinRequest = 2281711391; + public const uint S2C_DisposeJoinResponse = 2415929119; public const uint S2C_ClubChange = 2147493652; } } diff --git a/Entity/Generate/NetworkProtocol/SocialMessage.cs b/Entity/Generate/NetworkProtocol/SocialMessage.cs index 0cb7c95..d93441f 100644 --- a/Entity/Generate/NetworkProtocol/SocialMessage.cs +++ b/Entity/Generate/NetworkProtocol/SocialMessage.cs @@ -50,22 +50,22 @@ namespace Fantasy /// 请求创建工会 /// [ProtoContract] - public partial class C2S_CreateRequest : AMessage, ICustomRouteRequest, IProto + public partial class C2S_CreateClubRequest : AMessage, ICustomRouteRequest, IProto { - public static C2S_CreateRequest Create(Scene scene) + public static C2S_CreateClubRequest Create(Scene scene) { - return scene.MessagePoolComponent.Rent(); + return scene.MessagePoolComponent.Rent(); } public override void Dispose() { Name = default; #if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); + GetScene().MessagePoolComponent.Return(this); #endif } [ProtoIgnore] - public Caht2C_GetChatRecordResponse ResponseType { get; set; } - public uint OpCode() { return OuterOpcode.C2S_CreateRequest; } + public S2C_CreateClubResponse ResponseType { get; set; } + public uint OpCode() { return OuterOpcode.C2S_CreateClubRequest; } [ProtoIgnore] public int RouteType => Fantasy.RouteType.SocialRoute; [ProtoMember(1)] @@ -75,21 +75,21 @@ namespace Fantasy /// 创建工会响应 /// [ProtoContract] - public partial class S2C_CreateResponse : AMessage, ICustomRouteResponse, IProto + public partial class S2C_CreateClubResponse : AMessage, ICustomRouteResponse, IProto { - public static S2C_CreateResponse Create(Scene scene) + public static S2C_CreateClubResponse Create(Scene scene) { - return scene.MessagePoolComponent.Rent(); + return scene.MessagePoolComponent.Rent(); } public override void Dispose() { ErrorCode = default; Club = default; #if FANTASY_NET || FANTASY_UNITY - GetScene().MessagePoolComponent.Return(this); + GetScene().MessagePoolComponent.Return(this); #endif } - public uint OpCode() { return OuterOpcode.S2C_CreateResponse; } + public uint OpCode() { return OuterOpcode.S2C_CreateClubResponse; } [ProtoMember(1)] public ClubInfo Club { get; set; } [ProtoMember(2)] diff --git a/Hotfix/Chat/Handler/C2Chat_CreateChannelRequestHandler.cs b/Hotfix/Chat/Handler/C2Chat_CreateChannelRequestHandler.cs index 7b12fec..d50bd8f 100644 --- a/Hotfix/Chat/Handler/C2Chat_CreateChannelRequestHandler.cs +++ b/Hotfix/Chat/Handler/C2Chat_CreateChannelRequestHandler.cs @@ -21,6 +21,7 @@ public class } var channel = await channelCenter.Create(entity); - + + response.ChannelId = channel.Id; } } \ No newline at end of file diff --git a/Hotfix/Chat/Handler/C2Chat_GetOfflineMessageRequestHandler.cs b/Hotfix/Chat/Handler/C2Chat_GetOfflineMessageRequestHandler.cs new file mode 100644 index 0000000..9c6fb7d --- /dev/null +++ b/Hotfix/Chat/Handler/C2Chat_GetOfflineMessageRequestHandler.cs @@ -0,0 +1,24 @@ +using Fantasy; +using Fantasy.Async; +using Fantasy.Network.Interface; + +namespace NB.Chat; + +public class + C2Chat_GetOfflineMessageRequestHandler : RouteRPC +{ + protected override async FTask Run(ChatUnit entity, C2Chat_GetOfflineMessageRequest request, + Caht2C_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/Chat/Handler/C2Chat_JoinChannelRequestHandler.cs b/Hotfix/Chat/Handler/C2Chat_JoinChannelRequestHandler.cs index 9805851..6b05fa6 100644 --- a/Hotfix/Chat/Handler/C2Chat_JoinChannelRequestHandler.cs +++ b/Hotfix/Chat/Handler/C2Chat_JoinChannelRequestHandler.cs @@ -13,6 +13,11 @@ public class protected override async FTask Run(ChatUnit entity, C2Chat_JoinChannelRequest request, Caht2C_JoinChannelResponse response, Action reply) { + if (request.Target < 1) + { + response.ErrorCode = ErrorCode.ErrArgs; + return; + } var channelCenter = entity.Scene.GetComponent(); if (channelCenter == null) { diff --git a/Hotfix/Chat/Handler/C2Chat_SendMessageRequestHandler.cs b/Hotfix/Chat/Handler/C2Chat_SendMessageRequestHandler.cs index d3a08e9..8851a9e 100644 --- a/Hotfix/Chat/Handler/C2Chat_SendMessageRequestHandler.cs +++ b/Hotfix/Chat/Handler/C2Chat_SendMessageRequestHandler.cs @@ -11,18 +11,35 @@ public sealed class protected override async FTask Run(ChatUnit chatUnit, C2Chat_SendMessageRequest request, Caht2C_SendMessageResponse response, Action reply) { + if (request.Target < 1) + { + response.ErrorCode = ErrorCode.ErrArgs; + return; + } + if (request.Type == 0) //频道聊天 { - + ChatSceneHelper.BroadcastChannel(chatUnit.Scene, request.Target, new ChatMessageInfo() + { + Content = request.Message, + }); } else if (request.Type == 1) //私聊 { - + //发送私聊 + ChatSceneHelper.PrivateMessage(chatUnit.Scene, chatUnit.Id, request.Target, new ChatMessageInfo() + { + Content = request.Message, + }); } - ChatSceneHelper.Broadcast(chatUnit.Scene, new ChatMessageInfo() + else if (request.Type == 3) //广播聊天 { - Content = request.Message, - }); + ChatSceneHelper.BroadcastAll(chatUnit.Scene, new ChatMessageInfo() + { + Content = request.Message, + }); + } + await FTask.CompletedTask; } } \ No newline at end of file diff --git a/Hotfix/Chat/Handler/G2Chat_EnterRequestHandler.cs b/Hotfix/Chat/Handler/Inner/G2Chat_EnterRequestHandler.cs similarity index 95% rename from Hotfix/Chat/Handler/G2Chat_EnterRequestHandler.cs rename to Hotfix/Chat/Handler/Inner/G2Chat_EnterRequestHandler.cs index ad840e1..276b9bd 100644 --- a/Hotfix/Chat/Handler/G2Chat_EnterRequestHandler.cs +++ b/Hotfix/Chat/Handler/Inner/G2Chat_EnterRequestHandler.cs @@ -12,13 +12,11 @@ public class G2Chat_EnterRequestHandler : RouteRPC(); var account = await chatUnitManageComponent.Online(scene, request.Role, request.GateRouteId); response.RoleRouteId = account.RuntimeId; - await FTask.CompletedTask; } } \ No newline at end of file diff --git a/Hotfix/Chat/Handler/Inner/G2Chat_ExitRequestHandler.cs b/Hotfix/Chat/Handler/Inner/G2Chat_ExitRequestHandler.cs new file mode 100644 index 0000000..c99489d --- /dev/null +++ b/Hotfix/Chat/Handler/Inner/G2Chat_ExitRequestHandler.cs @@ -0,0 +1,16 @@ +using Fantasy; +using Fantasy.Async; +using Fantasy.Network.Interface; + +namespace NB.Chat; + +public class G2Chat_ExitRequestHandler : RouteRPC +{ + protected override async FTask Run(Scene scene, G2Chat_ExitRequest request, Chat2G_ExitResponse response, + Action reply) + { + // 在缓存中检查该账号是否存在 + var chatUnitManageComponent = scene.GetComponent(); + await chatUnitManageComponent.Offline(scene, request.AccountId, request.GateRouteId); + } +} \ No newline at end of file diff --git a/Hotfix/Chat/Helper/ChatSceneHelper.cs b/Hotfix/Chat/Helper/ChatSceneHelper.cs index a279fcf..298c289 100644 --- a/Hotfix/Chat/Helper/ChatSceneHelper.cs +++ b/Hotfix/Chat/Helper/ChatSceneHelper.cs @@ -8,22 +8,107 @@ public static class ChatSceneHelper { #region 消息发送 - - + /// + /// 发送一条私聊 + /// + /// + /// + /// + /// + public static void PrivateMessage(Scene scene, long selfId, long targetId, ChatMessageInfo message) + { + var chatUnitManage = scene.GetComponent(); + if (chatUnitManage == null) return; + var chatUnit = chatUnitManage.Get(targetId); + message.Type = 1; + message.Source = selfId; + if (chatUnit != null) + { + //对方在线 + BroadcastAll(scene, message, [targetId]); + } + else + { + //对方不在线,存入待领取列表,等待玩家下次登录领取 + chatUnitManage.SaveOfflineMessage(targetId, message); + } + } + + /// + /// 发送一条地图消息 + /// + /// + /// + /// + public static void BroadcastMap(Scene scene, long mapId, ChatMessageInfo message) + { + var chatUnitManage = scene.GetComponent(); + if (chatUnitManage == null) return; + HashSet targets = new HashSet(); + foreach (var (_, chatUnit) in chatUnitManage.ChatUnits) + { + if (chatUnit.MapId == mapId) + { + targets.Add(chatUnit.Id); + } + } + + if (targets.Count < 1) + { + Log.Info("地图在线人数为0,群发取消"); + return; + } + + BroadcastAll(scene, message, targets); + } + + /// + /// 发送一条频道消息 + /// + /// + /// + /// + public static void BroadcastChannel(Scene scene, long channelId, ChatMessageInfo message) + { + var chatUnitManage = scene.GetComponent(); + if (chatUnitManage == null) return; + HashSet targets = new HashSet(); + foreach (var (_, chatUnit) in chatUnitManage.ChatUnits) + { + if (chatUnit.CurrentChannel == channelId) + { + targets.Add(chatUnit.Id); + } + } + + if (targets.Count < 1) + { + Log.Info("频道在线人数为0,群发取消"); + return; + } + + BroadcastAll(scene, message, targets); + } + /// /// 广播消息给所有人 /// /// /// - public static void Broadcast(Scene scene, ChatMessageInfo message) + /// + public static void BroadcastAll(Scene scene, ChatMessageInfo message, HashSet? targets = null) { - Log.Info("广播消息==="); //发送给所有Gate服务器,让Gate转发给其他客户端 var gateConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Gate); var sendMessage = new Chat2G_ChatMessage() { - Message = message + Message = message, }; + if (targets != null && targets.Count > 0) + { + sendMessage.IdList.AddRange(targets); + } + var networkMessagingComponent = scene.NetworkMessagingComponent; foreach (var config in gateConfigs) { @@ -37,7 +122,7 @@ public static class ChatSceneHelper #region 上线下线 - public static async FTask Online(Scene scene, RoleSimpleInfo roleSimple, long gateRuntimeId) + public static async FTask<(long, long)> Online(Scene scene, RoleSimpleInfo roleSimple, long gateRuntimeId) { var gameSceneConfig = GetSceneConfig(); var gameRouteId = gameSceneConfig.RouteId; @@ -51,10 +136,30 @@ public static class ChatSceneHelper if (gameResponse.ErrorCode != 0) { - return 0; + return (0, 0); } - return gameResponse.RoleRouteId; + return (gameResponse.RoleRouteId, gameRouteId); + // return gameRouteId; + } + + public static async FTask Offline(Scene scene, long accountId, long gateRuntimeId, long sceneRouteId) + { + for (int i = 0; i < 10; i++) + { + var gameResponse = (Chat2G_ExitResponse)await scene.NetworkMessagingComponent.CallInnerRoute( + sceneRouteId, new G2Chat_ExitRequest() + { + AccountId = accountId, + GateRouteId = gateRuntimeId + }); + if (gameResponse.ErrorCode == 0) + { + return; + } + } + + Log.Error("重试多次还是退出失败,需检查"); } private static SceneConfig GetSceneConfig() diff --git a/Hotfix/Chat/System/ChatChannelCenterComponentSystem.cs b/Hotfix/Chat/System/ChatChannelCenterComponentSystem.cs index bb3188e..851e9d2 100644 --- a/Hotfix/Chat/System/ChatChannelCenterComponentSystem.cs +++ b/Hotfix/Chat/System/ChatChannelCenterComponentSystem.cs @@ -37,7 +37,11 @@ public static class ChatChannelCenterComponentSystem //查数据库 channel = await self.Scene.World.DataBase.Query(channelId, true); - self.Channels.Add(channel.Id, channel); + if (channel != null) + { + self.Channels.Add(channel.Id, channel); + } + return channel; } diff --git a/Hotfix/Chat/System/ChatUnitManageComponentSystem.cs b/Hotfix/Chat/System/ChatUnitManageComponentSystem.cs index d6eb199..ba86221 100644 --- a/Hotfix/Chat/System/ChatUnitManageComponentSystem.cs +++ b/Hotfix/Chat/System/ChatUnitManageComponentSystem.cs @@ -6,6 +6,21 @@ namespace NB.Chat; public static class ChatUnitManageComponentSystem { + #region 消息缓存 + + /// + /// 离线消息,进入待领取队列 + /// + /// + /// + /// + public static void SaveOfflineMessage(this ChatUnitManageComponent self, long targetId, ChatMessageInfo message) + { + self.NotSendMessage.Add(targetId, message); + } + + #endregion + #region 上线下线 /// @@ -15,7 +30,8 @@ public static class ChatUnitManageComponentSystem /// /// /// - public static async FTask Online(this ChatUnitManageComponent self, Scene scene, RoleSimpleInfo roleSimpleInfo, + public static async FTask Online(this ChatUnitManageComponent self, Scene scene, + RoleSimpleInfo roleSimpleInfo, long gateRouteId) { var accountId = roleSimpleInfo.RoleId; @@ -30,14 +46,22 @@ public static class ChatUnitManageComponentSystem account.GateRouteId = gateRouteId; account.Role = roleSimpleInfo; } - + await FTask.CompletedTask; return account; } - public static async FTask Offline(this ChatUnitManageComponent self, Scene scene, long accountId) + public static async FTask Offline(this ChatUnitManageComponent self, Scene scene, long accountId, long gateRouteId) { - self.Remove(accountId); + if (self.TryGet(accountId, out var unit) && unit != null) + { + if (unit.GateRouteId == gateRouteId) + { + Log.Info("退出当前聊天服=="); + self.Remove(accountId); //如果当前网关和下线的网关一致 + } + } + await FTask.CompletedTask; } diff --git a/Hotfix/Game/Helper/GameSceneHelper.cs b/Hotfix/Game/Helper/GameSceneHelper.cs index 77ee818..fea7601 100644 --- a/Hotfix/Game/Helper/GameSceneHelper.cs +++ b/Hotfix/Game/Helper/GameSceneHelper.cs @@ -34,4 +34,8 @@ public static class GameSceneHelper return (gameResponse.RoleRouteId, gameResponse.RoleInfo); } + + public static async FTask Offline(Scene scene, long accountId, long gateRuntimeId) + { + } } \ No newline at end of file diff --git a/Hotfix/Gate/Handler/Inner/Chat2G_ChatMessageHandler.cs b/Hotfix/Gate/Handler/Inner/Chat2G_ChatMessageHandler.cs index 9ada6a5..02caf9b 100644 --- a/Hotfix/Gate/Handler/Inner/Chat2G_ChatMessageHandler.cs +++ b/Hotfix/Gate/Handler/Inner/Chat2G_ChatMessageHandler.cs @@ -15,14 +15,34 @@ public class Chat2G_ChatMessageHandler : Route { Message = message.Message, }; - + var idList = message.IdList; + bool isAll = !(idList != null && idList.Count > 0); var gateUnitManage = scene.GetComponent(); - foreach (var session in gateUnitManage.ForEachUnitSession()) + if (isAll) { - session.Send(chatMessage); + foreach (var session in gateUnitManage.ForEachUnitSession()) + { + session.Send(chatMessage); + } } + else + { + if (idList == null) return; + foreach (var (_, gateUnit) in gateUnitManage.Units) + { + if (gateUnit.AccountID > 0 && idList.Contains(gateUnit.AccountID)) + { + Session session = gateUnit.Session; + if (session != null) + { + session.Send(chatMessage); + } + } + } + } + await FTask.CompletedTask; } diff --git a/Hotfix/Gate/Handler/Outer/C2G_LoginRequestHandler.cs b/Hotfix/Gate/Handler/Outer/C2G_LoginRequestHandler.cs index 607a931..38673e9 100644 --- a/Hotfix/Gate/Handler/Outer/C2G_LoginRequestHandler.cs +++ b/Hotfix/Gate/Handler/Outer/C2G_LoginRequestHandler.cs @@ -29,10 +29,8 @@ public sealed class C2G_LoginRequestHandler : MessageRPC(); - if (!gateUnitManageComponent.TryGet(accountId, out var gateUnit)) - { - gateUnit = gateUnitManageComponent.Add(session, accountId); - } + + var gateUnit = gateUnitManageComponent.Online(session, accountId); if (gateUnit == null) { @@ -40,11 +38,11 @@ public sealed class C2G_LoginRequestHandler : MessageRPC(); // accountFlagComponent.AccountID = accountId; - } } \ No newline at end of file diff --git a/Hotfix/Gate/Helper/GateLoginHelper.cs b/Hotfix/Gate/Helper/GateLoginHelper.cs index 5571076..3477a1d 100644 --- a/Hotfix/Gate/Helper/GateLoginHelper.cs +++ b/Hotfix/Gate/Helper/GateLoginHelper.cs @@ -40,6 +40,7 @@ public static class GateLoginHelper } gateUnitSessionComponent.AccountID = gateUnit.AccountID; + gateUnitSessionComponent.SessionId = session.RuntimeId; //安排游戏服务器,并通知进入 @@ -56,14 +57,15 @@ public static class GateLoginHelper //安排进入的聊天服 - var chatRouteId = await ChatSceneHelper.Online(session.Scene, roleSimpleInfo, session.RuntimeId); + var (chatRouteId, sceneRouteId) = + await ChatSceneHelper.Online(session.Scene, roleSimpleInfo, session.RuntimeId); if (chatRouteId <= 0) { return ErrorCode.OnlineSceneFailed; } routeComponent.AddAddress(RouteType.ChatRoute, chatRouteId); - gateUnit.ChatSceneRouteId = chatRouteId; + gateUnit.ChatSceneRouteId = sceneRouteId; Log.Info($"连接聊天服成功,gameRouteId:{gameRouteId}"); return ErrorCode.Successful; } @@ -75,12 +77,15 @@ public static class GateLoginHelper /// /// 网关通知其他服务器下线 /// - /// /// - public static async FTask Offline(GateUnit gateUnit) + /// + public static async FTask Offline(GateUnit gateUnit, long sessionId) { - await FTask.CompletedTask; //通知服务器下线 + Log.Info($"断线的session id={sessionId} ChatSceneRouteId={gateUnit.ChatSceneRouteId}"); + await GameSceneHelper.Offline(gateUnit.Scene, gateUnit.AccountID, sessionId); + await ChatSceneHelper.Offline(gateUnit.Scene, gateUnit.AccountID, sessionId, + gateUnit.ChatSceneRouteId); return ErrorCode.Successful; } diff --git a/Hotfix/Gate/System/GateUnitManageComponentSystem.cs b/Hotfix/Gate/System/GateUnitManageComponentSystem.cs index a0efea5..85b1b7e 100644 --- a/Hotfix/Gate/System/GateUnitManageComponentSystem.cs +++ b/Hotfix/Gate/System/GateUnitManageComponentSystem.cs @@ -9,7 +9,7 @@ namespace NB.Gate; public static class GateUnitManageComponentSystem { - public static GateUnit Add(this GateUnitManageComponent self, Session session, long accountId) + public static GateUnit Online(this GateUnitManageComponent self, Session session, long accountId) { if (self.Units.TryGetValue(accountId, out var unit)) { @@ -34,11 +34,12 @@ public static class GateUnitManageComponentSystem return self.Units.TryGetValue(accountId, out unit); } - public static async FTask Remove(this GateUnitManageComponent self, long accountId, bool isDispose = true) + public static async FTask Offline(this GateUnitManageComponent self, long accountId, long sessionId, + bool isDispose = true) { if (!self.Units.TryGetValue(accountId, out var unit)) return; //通知其他服务器下线 - var result = await GateLoginHelper.Offline(unit); + var result = await GateLoginHelper.Offline(unit, sessionId); if (result != 0) { Log.Error($"通知其他服务器下线失败,错误码:{result}"); @@ -52,9 +53,10 @@ public static class GateUnitManageComponentSystem unit.Dispose(); } } - + + /// - /// 回话迭代器 + /// 会话迭代器 /// /// /// diff --git a/Hotfix/Gate/System/GateUnitSessionComponentSystem.cs b/Hotfix/Gate/System/GateUnitSessionComponentSystem.cs index 98c1fe1..e6287da 100644 --- a/Hotfix/Gate/System/GateUnitSessionComponentSystem.cs +++ b/Hotfix/Gate/System/GateUnitSessionComponentSystem.cs @@ -9,7 +9,7 @@ public class GateUnitSessionComponentSystem : DestroySystem(); if (gateUnitManageComponent != null) { - _ = gateUnitManageComponent.Remove(self.AccountID); + _ = gateUnitManageComponent.Offline(self.AccountID, self.SessionId); } self.AccountID = 0; diff --git a/Server.sln.DotSettings.user b/Server.sln.DotSettings.user index ed77459..f98cd84 100644 --- a/Server.sln.DotSettings.user +++ b/Server.sln.DotSettings.user @@ -13,6 +13,8 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded diff --git a/Tools/ProtocolTest/Config.json b/Tools/ProtocolTest/Config.json index 1e7fae5..453faa6 100644 --- a/Tools/ProtocolTest/Config.json +++ b/Tools/ProtocolTest/Config.json @@ -1 +1 @@ -{"Server":"127.0.0.1:20001","Heartbeat":5,"ProtocolScriptPath":"D:\\work\\Fishing2\\Assets\\Scripts\\Generate","Accounts":["test002"]} \ No newline at end of file +{"Server":"127.0.0.1:20001","Heartbeat":5,"ProtocolScriptPath":"D:\\myself\\Games\\Fishing2\\Assets\\Scripts\\Generate\\NetworkProtocol","Accounts":["test002","test003"]} \ No newline at end of file diff --git a/Tools/ProtocolTest/FantasyNetTest.dll b/Tools/ProtocolTest/FantasyNetTest.dll index e3deada..12e8dba 100644 Binary files a/Tools/ProtocolTest/FantasyNetTest.dll and b/Tools/ProtocolTest/FantasyNetTest.dll differ diff --git a/Tools/ProtocolTest/FantasyNetTest.exe b/Tools/ProtocolTest/FantasyNetTest.exe index e51fe90..ff81337 100644 Binary files a/Tools/ProtocolTest/FantasyNetTest.exe and b/Tools/ProtocolTest/FantasyNetTest.exe differ diff --git a/Tools/ProtocolTest/FantasyNetTest.pdb b/Tools/ProtocolTest/FantasyNetTest.pdb index c94036b..e1e2b2d 100644 Binary files a/Tools/ProtocolTest/FantasyNetTest.pdb and b/Tools/ProtocolTest/FantasyNetTest.pdb differ diff --git a/Tools/ProtocolTest/Protocol/C2A_LoginRequest b/Tools/ProtocolTest/Protocol/C2A_LoginRequest new file mode 100644 index 0000000..cb9a3d0 --- /dev/null +++ b/Tools/ProtocolTest/Protocol/C2A_LoginRequest @@ -0,0 +1 @@ +{"ResponseType":null,"Username":"test002","Password":"test002","LoginType":1,"Region":3} \ No newline at end of file diff --git a/Tools/ProtocolTest/Protocol/C2Chat_SendMessageRequest b/Tools/ProtocolTest/Protocol/C2Chat_SendMessageRequest new file mode 100644 index 0000000..c3ceae6 --- /dev/null +++ b/Tools/ProtocolTest/Protocol/C2Chat_SendMessageRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002,"Type":1,"Message":"\u4F1A\u8986\u76D644545","Target":0} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2Chat_JoinChannelRequest b/Tools/ProtocolTest/test002/Protocol/C2Chat_JoinChannelRequest new file mode 100644 index 0000000..a38fa2c --- /dev/null +++ b/Tools/ProtocolTest/test002/Protocol/C2Chat_JoinChannelRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002,"Target":331859667959676928} \ No newline at end of file diff --git a/Tools/ProtocolTest/test002/Protocol/C2Chat_SendMessageRequest b/Tools/ProtocolTest/test002/Protocol/C2Chat_SendMessageRequest new file mode 100644 index 0000000..06f15f6 --- /dev/null +++ b/Tools/ProtocolTest/test002/Protocol/C2Chat_SendMessageRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002,"Type":1,"Message":"11111\u5927\u6CD5\u5E08\u7684\u65B9\u6CD5343411","Target":323063059205849090} \ No newline at end of file diff --git a/Tools/ProtocolTest/test003/Protocol/C2Chat_GetOfflineMessageRequest b/Tools/ProtocolTest/test003/Protocol/C2Chat_GetOfflineMessageRequest new file mode 100644 index 0000000..dcc6071 --- /dev/null +++ b/Tools/ProtocolTest/test003/Protocol/C2Chat_GetOfflineMessageRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002} \ No newline at end of file diff --git a/Tools/ProtocolTest/test003/Protocol/C2Chat_JoinChannelRequest b/Tools/ProtocolTest/test003/Protocol/C2Chat_JoinChannelRequest new file mode 100644 index 0000000..a38fa2c --- /dev/null +++ b/Tools/ProtocolTest/test003/Protocol/C2Chat_JoinChannelRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002,"Target":331859667959676928} \ No newline at end of file diff --git a/Tools/ProtocolTest/test003/Protocol/C2Chat_SendMessageRequest b/Tools/ProtocolTest/test003/Protocol/C2Chat_SendMessageRequest new file mode 100644 index 0000000..534374c --- /dev/null +++ b/Tools/ProtocolTest/test003/Protocol/C2Chat_SendMessageRequest @@ -0,0 +1 @@ +{"ResponseType":null,"RouteType":1002,"Type":0,"Message":"\u554A\u6536\u5230\u53D1\u65AF\u8482\u82AC334","Target":323063059205849090} \ No newline at end of file