完成离线消息发送和上线获取离线消息

This commit is contained in:
2025-08-13 23:44:59 +08:00
parent f8b876ca2f
commit 022cc1ac3e
39 changed files with 499 additions and 85 deletions

View File

@@ -12,10 +12,21 @@ message Game2G_EnterResponse // IRouteResponse
int64 RoleRouteId = 1; //角色实体的路由id int64 RoleRouteId = 1; //角色实体的路由id
RoleSimpleInfo RoleInfo = 2; //角色信息 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; //角色信息 RoleSimpleInfo Role = 1; //角色信息
int64 GateRouteId = 2;//网关路由地址 int64 GateRouteId = 2;//网关路由地址
@@ -26,9 +37,22 @@ message Chat2G_EnterResponse // IRouteResponse
int64 RoleRouteId = 1; //角色实体的路由id 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 message Chat2G_ChatMessage // IRouteMessage
{ {
ChatMessageInfo Message = 1; //聊天内容 ChatMessageInfo Message = 1; //聊天内容
repeated int64 IdList = 2; // 群发列表
} }
///创建聊天频道 ///创建聊天频道

View File

@@ -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 message Chat2C_Message // ICustomRouteMessage,ChatRoute
{ {

View File

@@ -11,13 +11,13 @@ message ClubInfo
} }
///请求创建工会 ///请求创建工会
message C2S_CreateRequest // ICustomRouteRequest,Caht2C_GetChatRecordResponse,SocialRoute message C2S_CreateClubRequest // ICustomRouteRequest,S2C_CreateClubResponse,SocialRoute
{ {
string Name = 1; //工会名称 string Name = 1; //工会名称
} }
///创建工会响应 ///创建工会响应
message S2C_CreateResponse // ICustomRouteResponse message S2C_CreateClubResponse // ICustomRouteResponse
{ {
ClubInfo Club = 1; //创建的工会信息 ClubInfo Club = 1; //创建的工会信息
} }

View File

@@ -10,7 +10,7 @@ message ChatUserInfo
message ChatMessageInfo message ChatMessageInfo
{ {
int32 Type = 1; //消息类型 int32 Type = 1; //消息类型
int32 Source = 2; //消息来源 int64 Source = 2; //消息来源
ChatUserInfo Trigger = 3; //触发者 ChatUserInfo Trigger = 3; //触发者
string Content = 4; //内容 string Content = 4; //内容
} }

View File

@@ -1,8 +1,17 @@
using Fantasy.Entitas; using Fantasy;
using Fantasy.DataStructure.Collection;
using Fantasy.Entitas;
namespace NB.Chat; namespace NB.Chat;
public class ChatUnitManageComponent : Entity public class ChatUnitManageComponent : Entity
{ {
public readonly Dictionary<long, ChatUnit> ChatUnits = new(); public readonly Dictionary<long, ChatUnit> ChatUnits = new();
/// <summary>
/// 不在线消息缓存
/// </summary>
public readonly OneToManyList<long, ChatMessageInfo> NotSendMessage = new();
public readonly OneToManyList<string, ChatMessageInfo> PrivateMessage = new();
} }

View File

@@ -5,4 +5,5 @@ namespace NB.Gate;
public sealed class GateUnitSessionComponent : Entity public sealed class GateUnitSessionComponent : Entity
{ {
public long AccountID; public long AccountID;
public long SessionId;
} }

View File

@@ -260,6 +260,52 @@ namespace Fantasy
public uint ErrorCode { get; set; } public uint ErrorCode { get; set; }
} }
/// <summary> /// <summary>
/// 获取离线时的未读私聊
/// </summary>
[ProtoContract]
public partial class C2Chat_GetOfflineMessageRequest : AMessage, ICustomRouteRequest, IProto
{
public static C2Chat_GetOfflineMessageRequest Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<C2Chat_GetOfflineMessageRequest>();
}
public override void Dispose()
{
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<C2Chat_GetOfflineMessageRequest>(this);
#endif
}
[ProtoIgnore]
public Caht2C_GetOfflineMessageResponse ResponseType { get; set; }
public uint OpCode() { return OuterOpcode.C2Chat_GetOfflineMessageRequest; }
[ProtoIgnore]
public int RouteType => Fantasy.RouteType.ChatRoute;
}
/// <summary>
/// 发送聊天响应
/// </summary>
[ProtoContract]
public partial class Caht2C_GetOfflineMessageResponse : AMessage, ICustomRouteResponse, IProto
{
public static Caht2C_GetOfflineMessageResponse Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<Caht2C_GetOfflineMessageResponse>();
}
public override void Dispose()
{
ErrorCode = default;
Message.Clear();
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<Caht2C_GetOfflineMessageResponse>(this);
#endif
}
public uint OpCode() { return OuterOpcode.Caht2C_GetOfflineMessageResponse; }
[ProtoMember(1)]
public List<ChatMessageInfo> Message = new List<ChatMessageInfo>();
[ProtoMember(2)]
public uint ErrorCode { get; set; }
}
/// <summary>
/// 推送消息 /// 推送消息
/// </summary> /// </summary>
[ProtoContract] [ProtoContract]

View File

@@ -57,7 +57,7 @@ namespace Fantasy
[ProtoMember(1)] [ProtoMember(1)]
public int Type { get; set; } public int Type { get; set; }
[ProtoMember(2)] [ProtoMember(2)]
public int Source { get; set; } public long Source { get; set; }
[ProtoMember(3)] [ProtoMember(3)]
public ChatUserInfo Trigger { get; set; } public ChatUserInfo Trigger { get; set; }
[ProtoMember(4)] [ProtoMember(4)]

View File

@@ -67,6 +67,47 @@ namespace Fantasy
[ProtoMember(3)] [ProtoMember(3)]
public uint ErrorCode { get; set; } 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<G2Game_ExitRequest>();
}
public override void Dispose()
{
AccountId = default;
GateRouteId = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<G2Game_ExitRequest>(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<Game2G_ExitResponse>();
}
public override void Dispose()
{
ErrorCode = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<Game2G_ExitResponse>(this);
#endif
}
public uint OpCode() { return InnerOpcode.Game2G_ExitResponse; }
[ProtoMember(1)]
public uint ErrorCode { get; set; }
}
/// <summary> /// <summary>
/// 通知游戏服角色进入该聊天服 /// 通知游戏服角色进入该聊天服
/// </summary> /// </summary>
@@ -86,7 +127,7 @@ namespace Fantasy
#endif #endif
} }
[ProtoIgnore] [ProtoIgnore]
public Game2G_EnterResponse ResponseType { get; set; } public Chat2G_EnterResponse ResponseType { get; set; }
public uint OpCode() { return InnerOpcode.G2Chat_EnterRequest; } public uint OpCode() { return InnerOpcode.G2Chat_EnterRequest; }
[ProtoMember(1)] [ProtoMember(1)]
public RoleSimpleInfo Role { get; set; } public RoleSimpleInfo Role { get; set; }
@@ -115,6 +156,47 @@ namespace Fantasy
public uint ErrorCode { get; set; } public uint ErrorCode { get; set; }
} }
[ProtoContract] [ProtoContract]
public partial class G2Chat_ExitRequest : AMessage, IRouteRequest, IProto
{
public static G2Chat_ExitRequest Create(Scene scene)
{
return scene.MessagePoolComponent.Rent<G2Chat_ExitRequest>();
}
public override void Dispose()
{
AccountId = default;
GateRouteId = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<G2Chat_ExitRequest>(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<Chat2G_ExitResponse>();
}
public override void Dispose()
{
ErrorCode = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<Chat2G_ExitResponse>(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 partial class Chat2G_ChatMessage : AMessage, IRouteMessage, IProto
{ {
public static Chat2G_ChatMessage Create(Scene scene) public static Chat2G_ChatMessage Create(Scene scene)
@@ -124,6 +206,7 @@ namespace Fantasy
public override void Dispose() public override void Dispose()
{ {
Message = default; Message = default;
IdList.Clear();
#if FANTASY_NET || FANTASY_UNITY #if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<Chat2G_ChatMessage>(this); GetScene().MessagePoolComponent.Return<Chat2G_ChatMessage>(this);
#endif #endif
@@ -131,6 +214,8 @@ namespace Fantasy
public uint OpCode() { return InnerOpcode.Chat2G_ChatMessage; } public uint OpCode() { return InnerOpcode.Chat2G_ChatMessage; }
[ProtoMember(1)] [ProtoMember(1)]
public ChatMessageInfo Message { get; set; } public ChatMessageInfo Message { get; set; }
[ProtoMember(2)]
public List<long> IdList = new List<long>();
} }
/// <summary> /// <summary>
/// 创建聊天频道 /// 创建聊天频道

View File

@@ -4,8 +4,12 @@ namespace Fantasy
{ {
public const uint G2Game_EnterRequest = 1073751825; public const uint G2Game_EnterRequest = 1073751825;
public const uint Game2G_EnterResponse = 1207969553; public const uint Game2G_EnterResponse = 1207969553;
public const uint G2Chat_EnterRequest = 1073751826; public const uint G2Game_ExitRequest = 1073751826;
public const uint Chat2G_EnterResponse = 1207969554; 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 Chat2G_ChatMessage = 939534097;
public const uint Club2Chat_CreateChannel = 939534098; public const uint Club2Chat_CreateChannel = 939534098;
} }

View File

@@ -12,32 +12,34 @@ namespace Fantasy
public const uint Caht2C_JoinChannelResponse = 2415929107; public const uint Caht2C_JoinChannelResponse = 2415929107;
public const uint C2Chat_SendMessageRequest = 2281711380; public const uint C2Chat_SendMessageRequest = 2281711380;
public const uint Caht2C_SendMessageResponse = 2415929108; 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 Chat2C_Message = 2147493651;
public const uint C2Chat_GetChatRecordRequest = 2281711381; public const uint C2Chat_GetChatRecordRequest = 2281711382;
public const uint Caht2C_GetChatRecordResponse = 2415929109; public const uint Caht2C_GetChatRecordResponse = 2415929110;
public const uint C2A_LoginRequest = 268445457; public const uint C2A_LoginRequest = 268445457;
public const uint A2C_LoginResponse = 402663185; public const uint A2C_LoginResponse = 402663185;
public const uint C2G_LoginRequest = 268445458; public const uint C2G_LoginRequest = 268445458;
public const uint G2C_LoginResponse = 402663186; public const uint G2C_LoginResponse = 402663186;
public const uint G2C_RepeatLogin = 134227729; public const uint G2C_RepeatLogin = 134227729;
public const uint C2Game_GetRoleInfoRequest = 2281711382; public const uint C2Game_GetRoleInfoRequest = 2281711383;
public const uint Game2C_GetRoleInfoResponse = 2415929110; public const uint Game2C_GetRoleInfoResponse = 2415929111;
public const uint C2S_CreateRequest = 2281711383; public const uint C2S_CreateClubRequest = 2281711384;
public const uint S2C_CreateResponse = 2415929111; public const uint S2C_CreateClubResponse = 2415929112;
public const uint C2S_GetClubInfoRequest = 2281711384; public const uint C2S_GetClubInfoRequest = 2281711385;
public const uint S2C_GetClubInfoResponse = 2415929112; public const uint S2C_GetClubInfoResponse = 2415929113;
public const uint C2S_GetMemberListRequest = 2281711385; public const uint C2S_GetMemberListRequest = 2281711386;
public const uint S2C_GetMemberListResponse = 2415929113; public const uint S2C_GetMemberListResponse = 2415929114;
public const uint C2S_GetClubListRequest = 2281711386; public const uint C2S_GetClubListRequest = 2281711387;
public const uint S2C_GetClubListResponse = 2415929114; public const uint S2C_GetClubListResponse = 2415929115;
public const uint C2S_JoinClubRequest = 2281711387; public const uint C2S_JoinClubRequest = 2281711388;
public const uint S2C_JoinClubResponse = 2415929115; public const uint S2C_JoinClubResponse = 2415929116;
public const uint C2S_LeaveClubRequest = 2281711388; public const uint C2S_LeaveClubRequest = 2281711389;
public const uint S2C_LeaveClubResponse = 2415929116; public const uint S2C_LeaveClubResponse = 2415929117;
public const uint C2S_DissolveClubRequest = 2281711389; public const uint C2S_DissolveClubRequest = 2281711390;
public const uint S2C_DissolveClubResponse = 2415929117; public const uint S2C_DissolveClubResponse = 2415929118;
public const uint C2S_DisposeJoinRequest = 2281711390; public const uint C2S_DisposeJoinRequest = 2281711391;
public const uint S2C_DisposeJoinResponse = 2415929118; public const uint S2C_DisposeJoinResponse = 2415929119;
public const uint S2C_ClubChange = 2147493652; public const uint S2C_ClubChange = 2147493652;
} }
} }

View File

@@ -50,22 +50,22 @@ namespace Fantasy
/// 请求创建工会 /// 请求创建工会
/// </summary> /// </summary>
[ProtoContract] [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<C2S_CreateRequest>(); return scene.MessagePoolComponent.Rent<C2S_CreateClubRequest>();
} }
public override void Dispose() public override void Dispose()
{ {
Name = default; Name = default;
#if FANTASY_NET || FANTASY_UNITY #if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<C2S_CreateRequest>(this); GetScene().MessagePoolComponent.Return<C2S_CreateClubRequest>(this);
#endif #endif
} }
[ProtoIgnore] [ProtoIgnore]
public Caht2C_GetChatRecordResponse ResponseType { get; set; } public S2C_CreateClubResponse ResponseType { get; set; }
public uint OpCode() { return OuterOpcode.C2S_CreateRequest; } public uint OpCode() { return OuterOpcode.C2S_CreateClubRequest; }
[ProtoIgnore] [ProtoIgnore]
public int RouteType => Fantasy.RouteType.SocialRoute; public int RouteType => Fantasy.RouteType.SocialRoute;
[ProtoMember(1)] [ProtoMember(1)]
@@ -75,21 +75,21 @@ namespace Fantasy
/// 创建工会响应 /// 创建工会响应
/// </summary> /// </summary>
[ProtoContract] [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<S2C_CreateResponse>(); return scene.MessagePoolComponent.Rent<S2C_CreateClubResponse>();
} }
public override void Dispose() public override void Dispose()
{ {
ErrorCode = default; ErrorCode = default;
Club = default; Club = default;
#if FANTASY_NET || FANTASY_UNITY #if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return<S2C_CreateResponse>(this); GetScene().MessagePoolComponent.Return<S2C_CreateClubResponse>(this);
#endif #endif
} }
public uint OpCode() { return OuterOpcode.S2C_CreateResponse; } public uint OpCode() { return OuterOpcode.S2C_CreateClubResponse; }
[ProtoMember(1)] [ProtoMember(1)]
public ClubInfo Club { get; set; } public ClubInfo Club { get; set; }
[ProtoMember(2)] [ProtoMember(2)]

View File

@@ -22,5 +22,6 @@ public class
var channel = await channelCenter.Create(entity); var channel = await channelCenter.Create(entity);
response.ChannelId = channel.Id;
} }
} }

View File

@@ -0,0 +1,24 @@
using Fantasy;
using Fantasy.Async;
using Fantasy.Network.Interface;
namespace NB.Chat;
public class
C2Chat_GetOfflineMessageRequestHandler : RouteRPC<ChatUnit, C2Chat_GetOfflineMessageRequest,
Caht2C_GetOfflineMessageResponse>
{
protected override async FTask Run(ChatUnit entity, C2Chat_GetOfflineMessageRequest request,
Caht2C_GetOfflineMessageResponse response,
Action reply)
{
var chatUnitManage = entity.Scene.GetComponent<ChatUnitManageComponent>();
if (chatUnitManage.NotSendMessage.TryGetValue(entity.Id, out var list))
{
response.Message.AddRange(list);
chatUnitManage.NotSendMessage.RemoveByKey(entity.Id);
}
await FTask.CompletedTask;
}
}

View File

@@ -13,6 +13,11 @@ public class
protected override async FTask Run(ChatUnit entity, C2Chat_JoinChannelRequest request, protected override async FTask Run(ChatUnit entity, C2Chat_JoinChannelRequest request,
Caht2C_JoinChannelResponse response, Action reply) Caht2C_JoinChannelResponse response, Action reply)
{ {
if (request.Target < 1)
{
response.ErrorCode = ErrorCode.ErrArgs;
return;
}
var channelCenter = entity.Scene.GetComponent<ChatChannelCenterComponent>(); var channelCenter = entity.Scene.GetComponent<ChatChannelCenterComponent>();
if (channelCenter == null) if (channelCenter == null)
{ {

View File

@@ -11,18 +11,35 @@ public sealed class
protected override async FTask Run(ChatUnit chatUnit, C2Chat_SendMessageRequest request, protected override async FTask Run(ChatUnit chatUnit, C2Chat_SendMessageRequest request,
Caht2C_SendMessageResponse response, Action reply) Caht2C_SendMessageResponse response, Action reply)
{ {
if (request.Target < 1)
{
response.ErrorCode = ErrorCode.ErrArgs;
return;
}
if (request.Type == 0) //频道聊天 if (request.Type == 0) //频道聊天
{ {
ChatSceneHelper.BroadcastChannel(chatUnit.Scene, request.Target, new ChatMessageInfo()
{
Content = request.Message,
});
} }
else if (request.Type == 1) //私聊 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; await FTask.CompletedTask;
} }
} }

View File

@@ -13,12 +13,10 @@ public class G2Chat_EnterRequestHandler : RouteRPC<Scene, G2Chat_EnterRequest, C
var roleId = request.Role.RoleId; var roleId = request.Role.RoleId;
Log.Debug($"收到 G2Chat_EnterRequestHandler {roleId}"); Log.Debug($"收到 G2Chat_EnterRequestHandler {roleId}");
// 在缓存中检查该账号是否存在 // 在缓存中检查该账号是否存在
var chatUnitManageComponent = scene.GetComponent<ChatUnitManageComponent>(); var chatUnitManageComponent = scene.GetComponent<ChatUnitManageComponent>();
var account = await chatUnitManageComponent.Online(scene, request.Role, request.GateRouteId); var account = await chatUnitManageComponent.Online(scene, request.Role, request.GateRouteId);
response.RoleRouteId = account.RuntimeId; response.RoleRouteId = account.RuntimeId;
await FTask.CompletedTask;
} }
} }

View File

@@ -0,0 +1,16 @@
using Fantasy;
using Fantasy.Async;
using Fantasy.Network.Interface;
namespace NB.Chat;
public class G2Chat_ExitRequestHandler : RouteRPC<Scene, G2Chat_ExitRequest, Chat2G_ExitResponse>
{
protected override async FTask Run(Scene scene, G2Chat_ExitRequest request, Chat2G_ExitResponse response,
Action reply)
{
// 在缓存中检查该账号是否存在
var chatUnitManageComponent = scene.GetComponent<ChatUnitManageComponent>();
await chatUnitManageComponent.Offline(scene, request.AccountId, request.GateRouteId);
}
}

View File

@@ -8,22 +8,107 @@ public static class ChatSceneHelper
{ {
#region #region
/// <summary>
/// 发送一条私聊
/// </summary>
/// <param name="scene"></param>
/// <param name="selfId"></param>
/// <param name="targetId"></param>
/// <param name="message"></param>
public static void PrivateMessage(Scene scene, long selfId, long targetId, ChatMessageInfo message)
{
var chatUnitManage = scene.GetComponent<ChatUnitManageComponent>();
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);
}
}
/// <summary>
/// 发送一条地图消息
/// </summary>
/// <param name="scene"></param>
/// <param name="mapId"></param>
/// <param name="message"></param>
public static void BroadcastMap(Scene scene, long mapId, ChatMessageInfo message)
{
var chatUnitManage = scene.GetComponent<ChatUnitManageComponent>();
if (chatUnitManage == null) return;
HashSet<long> targets = new HashSet<long>();
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);
}
/// <summary>
/// 发送一条频道消息
/// </summary>
/// <param name="scene"></param>
/// <param name="channelId"></param>
/// <param name="message"></param>
public static void BroadcastChannel(Scene scene, long channelId, ChatMessageInfo message)
{
var chatUnitManage = scene.GetComponent<ChatUnitManageComponent>();
if (chatUnitManage == null) return;
HashSet<long> targets = new HashSet<long>();
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);
}
/// <summary> /// <summary>
/// 广播消息给所有人 /// 广播消息给所有人
/// </summary> /// </summary>
/// <param name="scene"></param> /// <param name="scene"></param>
/// <param name="message"></param> /// <param name="message"></param>
public static void Broadcast(Scene scene, ChatMessageInfo message) /// <param name="targets"></param>
public static void BroadcastAll(Scene scene, ChatMessageInfo message, HashSet<long>? targets = null)
{ {
Log.Info("广播消息===");
//发送给所有Gate服务器让Gate转发给其他客户端 //发送给所有Gate服务器让Gate转发给其他客户端
var gateConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Gate); var gateConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Gate);
var sendMessage = new Chat2G_ChatMessage() var sendMessage = new Chat2G_ChatMessage()
{ {
Message = message Message = message,
}; };
if (targets != null && targets.Count > 0)
{
sendMessage.IdList.AddRange(targets);
}
var networkMessagingComponent = scene.NetworkMessagingComponent; var networkMessagingComponent = scene.NetworkMessagingComponent;
foreach (var config in gateConfigs) foreach (var config in gateConfigs)
{ {
@@ -37,7 +122,7 @@ public static class ChatSceneHelper
#region 线线 #region 线线
public static async FTask<long> Online(Scene scene, RoleSimpleInfo roleSimple, long gateRuntimeId) public static async FTask<(long, long)> Online(Scene scene, RoleSimpleInfo roleSimple, long gateRuntimeId)
{ {
var gameSceneConfig = GetSceneConfig(); var gameSceneConfig = GetSceneConfig();
var gameRouteId = gameSceneConfig.RouteId; var gameRouteId = gameSceneConfig.RouteId;
@@ -51,10 +136,30 @@ public static class ChatSceneHelper
if (gameResponse.ErrorCode != 0) 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() private static SceneConfig GetSceneConfig()

View File

@@ -37,7 +37,11 @@ public static class ChatChannelCenterComponentSystem
//查数据库 //查数据库
channel = await self.Scene.World.DataBase.Query<ChatChannel>(channelId, true); channel = await self.Scene.World.DataBase.Query<ChatChannel>(channelId, true);
self.Channels.Add(channel.Id, channel); if (channel != null)
{
self.Channels.Add(channel.Id, channel);
}
return channel; return channel;
} }

View File

@@ -6,6 +6,21 @@ namespace NB.Chat;
public static class ChatUnitManageComponentSystem public static class ChatUnitManageComponentSystem
{ {
#region
/// <summary>
/// 离线消息,进入待领取队列
/// </summary>
/// <param name="self"></param>
/// <param name="targetId"></param>
/// <param name="message"></param>
public static void SaveOfflineMessage(this ChatUnitManageComponent self, long targetId, ChatMessageInfo message)
{
self.NotSendMessage.Add(targetId, message);
}
#endregion
#region 线线 #region 线线
/// <summary> /// <summary>
@@ -15,7 +30,8 @@ public static class ChatUnitManageComponentSystem
/// <param name="scene"></param> /// <param name="scene"></param>
/// <param name="roleSimpleInfo"></param> /// <param name="roleSimpleInfo"></param>
/// <param name="gateRouteId"></param> /// <param name="gateRouteId"></param>
public static async FTask<ChatUnit?> Online(this ChatUnitManageComponent self, Scene scene, RoleSimpleInfo roleSimpleInfo, public static async FTask<ChatUnit?> Online(this ChatUnitManageComponent self, Scene scene,
RoleSimpleInfo roleSimpleInfo,
long gateRouteId) long gateRouteId)
{ {
var accountId = roleSimpleInfo.RoleId; var accountId = roleSimpleInfo.RoleId;
@@ -35,9 +51,17 @@ public static class ChatUnitManageComponentSystem
return account; 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; await FTask.CompletedTask;
} }

View File

@@ -34,4 +34,8 @@ public static class GameSceneHelper
return (gameResponse.RoleRouteId, gameResponse.RoleInfo); return (gameResponse.RoleRouteId, gameResponse.RoleInfo);
} }
public static async FTask Offline(Scene scene, long accountId, long gateRuntimeId)
{
}
} }

View File

@@ -15,14 +15,34 @@ public class Chat2G_ChatMessageHandler : Route<Scene, Chat2G_ChatMessage>
{ {
Message = message.Message, Message = message.Message,
}; };
var idList = message.IdList;
bool isAll = !(idList != null && idList.Count > 0);
var gateUnitManage = scene.GetComponent<GateUnitManageComponent>(); var gateUnitManage = scene.GetComponent<GateUnitManageComponent>();
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; await FTask.CompletedTask;
} }

View File

@@ -29,10 +29,8 @@ public sealed class C2G_LoginRequestHandler : MessageRPC<C2G_LoginRequest, G2C_L
// 在缓存中检查该账号是否存在 // 在缓存中检查该账号是否存在
var gateUnitManageComponent = scene.GetComponent<GateUnitManageComponent>(); var gateUnitManageComponent = scene.GetComponent<GateUnitManageComponent>();
if (!gateUnitManageComponent.TryGet(accountId, out var gateUnit))
{ var gateUnit = gateUnitManageComponent.Online(session, accountId);
gateUnit = gateUnitManageComponent.Add(session, accountId);
}
if (gateUnit == null) if (gateUnit == null)
{ {
@@ -71,6 +69,5 @@ public sealed class C2G_LoginRequestHandler : MessageRPC<C2G_LoginRequest, G2C_L
// // 给当前Session添加一个组件当Session销毁的时候会销毁这个组件。 // // 给当前Session添加一个组件当Session销毁的时候会销毁这个组件。
// var accountFlagComponent = session.AddComponent<SessionPlayerComponent>(); // var accountFlagComponent = session.AddComponent<SessionPlayerComponent>();
// accountFlagComponent.AccountID = accountId; // accountFlagComponent.AccountID = accountId;
} }
} }

View File

@@ -40,6 +40,7 @@ public static class GateLoginHelper
} }
gateUnitSessionComponent.AccountID = gateUnit.AccountID; 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) if (chatRouteId <= 0)
{ {
return ErrorCode.OnlineSceneFailed; return ErrorCode.OnlineSceneFailed;
} }
routeComponent.AddAddress(RouteType.ChatRoute, chatRouteId); routeComponent.AddAddress(RouteType.ChatRoute, chatRouteId);
gateUnit.ChatSceneRouteId = chatRouteId; gateUnit.ChatSceneRouteId = sceneRouteId;
Log.Info($"连接聊天服成功gameRouteId:{gameRouteId}"); Log.Info($"连接聊天服成功gameRouteId:{gameRouteId}");
return ErrorCode.Successful; return ErrorCode.Successful;
} }
@@ -75,12 +77,15 @@ public static class GateLoginHelper
/// <summary> /// <summary>
/// 网关通知其他服务器下线 /// 网关通知其他服务器下线
/// </summary> /// </summary>
/// <param name="self"></param>
/// <param name="gateUnit"></param> /// <param name="gateUnit"></param>
public static async FTask<uint> Offline(GateUnit gateUnit) /// <param name="sessionId"></param>
public static async FTask<uint> 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; return ErrorCode.Successful;
} }

View File

@@ -9,7 +9,7 @@ namespace NB.Gate;
public static class GateUnitManageComponentSystem 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)) if (self.Units.TryGetValue(accountId, out var unit))
{ {
@@ -34,11 +34,12 @@ public static class GateUnitManageComponentSystem
return self.Units.TryGetValue(accountId, out unit); 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; 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) if (result != 0)
{ {
Log.Error($"通知其他服务器下线失败,错误码:{result}"); Log.Error($"通知其他服务器下线失败,错误码:{result}");
@@ -53,8 +54,9 @@ public static class GateUnitManageComponentSystem
} }
} }
/// <summary> /// <summary>
/// 话迭代器 /// 话迭代器
/// </summary> /// </summary>
/// <param name="self"></param> /// <param name="self"></param>
/// <returns></returns> /// <returns></returns>

View File

@@ -9,7 +9,7 @@ public class GateUnitSessionComponentSystem : DestroySystem<GateUnitSessionCompo
var gateUnitManageComponent = self.Scene.GetComponent<GateUnitManageComponent>(); var gateUnitManageComponent = self.Scene.GetComponent<GateUnitManageComponent>();
if (gateUnitManageComponent != null) if (gateUnitManageComponent != null)
{ {
_ = gateUnitManageComponent.Remove(self.AccountID); _ = gateUnitManageComponent.Offline(self.AccountID, self.SessionId);
} }
self.AccountID = 0; self.AccountID = 0;

View File

@@ -13,6 +13,8 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABsonElementAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F3be33698cf8a4c6ea48ef124c9ddacad81800_003Ff5_003F5d71aba0_003FBsonElementAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABsonElementAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F3be33698cf8a4c6ea48ef124c9ddacad81800_003Ff5_003F5d71aba0_003FBsonElementAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABsonIgnoreAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F39988e239fb94b73b8bdb00ab8b87d1f82400_003F63_003Fca262714_003FBsonIgnoreAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABsonIgnoreAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F39988e239fb94b73b8bdb00ab8b87d1f82400_003F63_003Fca262714_003FBsonIgnoreAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControllerBase_002Ecs_002Fl_003AC_0021_003FUsers_003Fbob_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0207e94f3a3e4dca931382ccf94981471de930_003Fd2_003Fe3b49283_003FControllerBase_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AControllerBase_002Ecs_002Fl_003AC_0021_003FUsers_003Fbob_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0207e94f3a3e4dca931382ccf94981471de930_003Fd2_003Fe3b49283_003FControllerBase_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADeserializeSystem_00601_002Ecs_002Fl_003AC_0021_003FUsers_003F60527_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fff8cbe4b3c6c469b86633ea0c41accd783200_003Fba_003Fb30c4cb2_003FDeserializeSystem_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADestroySystem_00601_002Ecs_002Fl_003AC_0021_003FUsers_003F60527_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fff8cbe4b3c6c469b86633ea0c41accd783200_003F41_003F9b0e4a72_003FDestroySystem_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F326268ddb927895dce924c78646b4d4ce2b05971ed1d8c9be99051ad1d2_003FDictionary_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F326268ddb927895dce924c78646b4d4ce2b05971ed1d8c9be99051ad1d2_003FDictionary_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bc9cdb23bc146bcaaae0bb9e45e5d46d9dc00_003Fdb_003F02b9a6a5_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8bc9cdb23bc146bcaaae0bb9e45e5d46d9dc00_003Fdb_003F02b9a6a5_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F77fc0eb92b774686bbae91cb92331703d83600_003Feb_003F3472606c_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F77fc0eb92b774686bbae91cb92331703d83600_003Feb_003F3472606c_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

View File

@@ -1 +1 @@
{"Server":"127.0.0.1:20001","Heartbeat":5,"ProtocolScriptPath":"D:\\work\\Fishing2\\Assets\\Scripts\\Generate","Accounts":["test002"]} {"Server":"127.0.0.1:20001","Heartbeat":5,"ProtocolScriptPath":"D:\\myself\\Games\\Fishing2\\Assets\\Scripts\\Generate\\NetworkProtocol","Accounts":["test002","test003"]}

View File

@@ -0,0 +1 @@
{"ResponseType":null,"Username":"test002","Password":"test002","LoginType":1,"Region":3}

View File

@@ -0,0 +1 @@
{"ResponseType":null,"RouteType":1002,"Type":1,"Message":"\u4F1A\u8986\u76D644545","Target":0}

View File

@@ -0,0 +1 @@
{"ResponseType":null,"RouteType":1002,"Target":331859667959676928}

View File

@@ -0,0 +1 @@
{"ResponseType":null,"RouteType":1002,"Type":1,"Message":"11111\u5927\u6CD5\u5E08\u7684\u65B9\u6CD5343411","Target":323063059205849090}

View File

@@ -0,0 +1 @@
{"ResponseType":null,"RouteType":1002}

View File

@@ -0,0 +1 @@
{"ResponseType":null,"RouteType":1002,"Target":331859667959676928}

View File

@@ -0,0 +1 @@
{"ResponseType":null,"RouteType":1002,"Type":0,"Message":"\u554A\u6536\u5230\u53D1\u65AF\u8482\u82AC334","Target":323063059205849090}