chat
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
// using Fantasy;
|
||||
// using Fantasy.Async;
|
||||
// using Fantasy.Network;
|
||||
// using Fantasy.Network.Interface;
|
||||
//
|
||||
// namespace NB.Gate;
|
||||
//
|
||||
// public sealed class C2G_GetAccountInfoRequestHandler : MessageRPC<C2G_GetAccountInfoRequest, G2C_GetAccountInfoResponse>
|
||||
// {
|
||||
// protected override async FTask Run(Session session, C2G_GetAccountInfoRequest request, G2C_GetAccountInfoResponse response, Action reply)
|
||||
// {
|
||||
// var gameAccountFlagComponent = session.GetComponent<PlayerFlagComponent>();
|
||||
//
|
||||
// if (gameAccountFlagComponent == null)
|
||||
// {
|
||||
// // 表示不应该访问这个接口,要先访问登录的接口。
|
||||
// // response.ErrorCode = 1;
|
||||
// session.Dispose();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// Player account = gameAccountFlagComponent.Player;
|
||||
//
|
||||
// if (account == null)
|
||||
// {
|
||||
// // 表示这个Account已经被销毁过了。不是咱们想要的了
|
||||
// }
|
||||
//
|
||||
// response.GameAccountInfo = account.GetGameAccountInfo();
|
||||
// await FTask.CompletedTask;
|
||||
// }
|
||||
// }
|
||||
@@ -3,6 +3,7 @@ using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Platform.Net;
|
||||
using NB.Game;
|
||||
|
||||
namespace NB.Gate.Handler;
|
||||
|
||||
@@ -13,14 +14,11 @@ public sealed class C2G_LoginRequestHandler : MessageRPC<C2G_LoginRequest, G2C_L
|
||||
{
|
||||
if (string.IsNullOrEmpty(request.ToKen))
|
||||
{
|
||||
// 1、客户端漏传了 response.ErrorCode = 1;
|
||||
// 2、恶意攻击导致的 session.Dispose();
|
||||
session.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
var scene = session.Scene;
|
||||
// Log.Info($"网关服场景 {scene.Id} {scene.RouteId} {scene.SceneConfigId} {scene.RouteId} {session.RouteId}");
|
||||
if (!GateJWTHelper.ValidateToken(scene, request.ToKen, out var accountId))
|
||||
{
|
||||
// 如果失败,表示肯定是恶意攻击、所以毫不犹疑,直接断开当前会话。
|
||||
@@ -28,51 +26,51 @@ public sealed class C2G_LoginRequestHandler : MessageRPC<C2G_LoginRequest, G2C_L
|
||||
return;
|
||||
}
|
||||
|
||||
// 首先需要找到一个需要建立Route的Scene的SceneConfig。
|
||||
// 例子演示的连接的ChatScene,所以这里我通过SceneConfigData拿到这个SceneConfig。
|
||||
// 如果是其他Scene,用法跟这个没有任何区别。
|
||||
var gameSceneConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Game)[0];
|
||||
// 通过chatSceneConfig拿到这个Scene的RouteId
|
||||
var gameRouteId = gameSceneConfig.RouteId;
|
||||
//连接到游戏中心服
|
||||
var gameResponse = (Game2G_EnterResponse)await session.Scene.NetworkMessagingComponent.CallInnerRoute(
|
||||
gameRouteId, new G2Game_EnterRequest()
|
||||
{
|
||||
AccountId = accountId,
|
||||
GateRouteId = session.RuntimeId
|
||||
});
|
||||
|
||||
if (gameResponse.ErrorCode != 0)
|
||||
// 在缓存中检查该账号是否存在
|
||||
var gateUnitManageComponent = scene.GetComponent<GateUnitManageComponent>();
|
||||
|
||||
if (!gateUnitManageComponent.TryGet(accountId, out var gateUnit))
|
||||
{
|
||||
// 如果ErrorCode不是0表示请求的协议发生错误,应该提示给客户端。
|
||||
// 这里就不做这个了。
|
||||
response.ErrorCode = gameResponse.ErrorCode;
|
||||
return;
|
||||
gateUnit = gateUnitManageComponent.Add(session, accountId);
|
||||
}
|
||||
|
||||
// 要实现Route协议的转发,需要给Session添加一个RouteComponent,这个非常重要。
|
||||
var routeComponent = session.AddComponent<RouteComponent>();
|
||||
// 需要再Examples/Config/NetworkProtocol/RouteType.Config里添加一个ChatRoute
|
||||
// 然后点击导表工具,会自动生成一个RouteType.cs文件。
|
||||
// 使用你定义的ChatRoute当routeType的参数传递进去。
|
||||
// routeResponse会返回一个ChatRouteId,这个就是Chat的RouteId。
|
||||
routeComponent.AddAddress(RouteType.GameRoute, gameResponse.RoleRouteId);
|
||||
// 这些操作完成后,就完成了Route消息的建立。
|
||||
// 后面可以直接发送Route消息通过Gate自动中转给Chat了。
|
||||
if (gateUnit == null)
|
||||
{
|
||||
Log.Error("创建GateUnit失败");
|
||||
session.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 给当前Session添加一个组件,当Session销毁的时候会销毁这个组件。
|
||||
var accountFlagComponent = session.AddComponent<SessionPlayerComponent>();
|
||||
accountFlagComponent.AccountID = accountId;
|
||||
|
||||
// account.SessionRunTimeId = session.RuntimeId;
|
||||
// response.GameAccountInfo = account.GetGameAccountInfo();
|
||||
|
||||
response.ErrorCode = await GateLoginHelper.Online(gateUnit);
|
||||
Log.Debug($"当前的Gate服务器:{session.Scene.SceneConfigId} accountId:{accountId}");
|
||||
|
||||
|
||||
|
||||
Log.Debug($"网关内网连接到游戏服成功 routerId={gameResponse.RoleRouteId}");
|
||||
// var gameSceneConfig = GameSceneHelper.GetSceneConfig(session);
|
||||
//
|
||||
// // 通过chatSceneConfig拿到这个Scene的RouteId
|
||||
// var gameRouteId = gameSceneConfig.RouteId;
|
||||
// //连接到游戏中心服
|
||||
// var gameResponse = (Game2G_EnterResponse)await session.Scene.NetworkMessagingComponent.CallInnerRoute(
|
||||
// gameRouteId, new G2Game_EnterRequest()
|
||||
// {
|
||||
// AccountId = accountId,
|
||||
// GateRouteId = session.RuntimeId
|
||||
// });
|
||||
//
|
||||
// if (gameResponse.ErrorCode != 0)
|
||||
// {
|
||||
// // 如果ErrorCode不是0表示请求的协议发生错误,应该提示给客户端。
|
||||
// response.ErrorCode = gameResponse.ErrorCode;
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 要实现Route协议的转发,需要给Session添加一个RouteComponent,这个非常重要。
|
||||
// var routeComponent = session.AddComponent<RouteComponent>();
|
||||
// routeComponent.AddAddress(RouteType.GameRoute, gameResponse.RoleRouteId);
|
||||
//
|
||||
// // 给当前Session添加一个组件,当Session销毁的时候会销毁这个组件。
|
||||
// var accountFlagComponent = session.AddComponent<SessionPlayerComponent>();
|
||||
// accountFlagComponent.AccountID = accountId;
|
||||
|
||||
}
|
||||
}
|
||||
75
Hotfix/Gate/Helper/GateLoginHelper.cs
Normal file
75
Hotfix/Gate/Helper/GateLoginHelper.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using NB.Game;
|
||||
|
||||
namespace NB.Gate;
|
||||
|
||||
public static class GateLoginHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 网关通知其他服务器上线
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="gateUnit"></param>
|
||||
public static async FTask<uint> Online(GateUnit gateUnit)
|
||||
{
|
||||
if (gateUnit == null)
|
||||
{
|
||||
return ErrorCode.ErrArgs;
|
||||
}
|
||||
|
||||
Session session = gateUnit.Session;
|
||||
if (session == null)
|
||||
{
|
||||
return ErrorCode.ErrArgs;
|
||||
}
|
||||
|
||||
var gateUnitSessionComponent = session.GetComponent<GateUnitSessionComponent>();
|
||||
if (gateUnitSessionComponent == null)
|
||||
{
|
||||
gateUnitSessionComponent = session.AddComponent<GateUnitSessionComponent>();
|
||||
}
|
||||
|
||||
var routeComponent = session.GetComponent<RouteComponent>();
|
||||
if (routeComponent == null)
|
||||
{
|
||||
routeComponent = session.AddComponent<RouteComponent>();
|
||||
}
|
||||
|
||||
gateUnitSessionComponent.AccountID = gateUnit.AccountID;
|
||||
|
||||
//安排服务器,并通知进入
|
||||
var gameSceneConfig = GameSceneHelper.GetSceneConfig(session);
|
||||
var gameRouteId = gameSceneConfig.RouteId;
|
||||
//连接到游戏中心服
|
||||
var gameResponse = (Game2G_EnterResponse)await session.Scene.NetworkMessagingComponent.CallInnerRoute(
|
||||
gameRouteId, new G2Game_EnterRequest()
|
||||
{
|
||||
AccountId = gateUnit.AccountID,
|
||||
GateRouteId = session.RuntimeId
|
||||
});
|
||||
|
||||
if (gameResponse.ErrorCode != 0)
|
||||
{
|
||||
return ErrorCode.OnlineSceneFailed;
|
||||
}
|
||||
|
||||
routeComponent.AddAddress(RouteType.GameRoute, gameResponse.RoleRouteId);
|
||||
gateUnit.GameSceneRouteId = gameRouteId;
|
||||
|
||||
|
||||
return ErrorCode.Successful;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网关通知其他服务器下线
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="gateUnit"></param>
|
||||
public static async FTask<uint> Offline(GateUnit gateUnit)
|
||||
{
|
||||
//通知服务器下线
|
||||
return ErrorCode.Successful;
|
||||
}
|
||||
}
|
||||
55
Hotfix/Gate/System/GateUnitManageComponentSystem.cs
Normal file
55
Hotfix/Gate/System/GateUnitManageComponentSystem.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Platform.Net;
|
||||
using NB.Game;
|
||||
|
||||
namespace NB.Gate;
|
||||
|
||||
public static class GateUnitManageComponentSystem
|
||||
{
|
||||
public static GateUnit Add(this GateUnitManageComponent self, Session session, long accountId)
|
||||
{
|
||||
if (self.Units.TryGetValue(accountId, out var unit))
|
||||
{
|
||||
unit.Session = session;
|
||||
return unit;
|
||||
}
|
||||
|
||||
unit = Entity.Create<GateUnit>(self.Scene, accountId, true, true);
|
||||
unit.AccountID = accountId;
|
||||
unit.Session = session;
|
||||
self.Units.Add(accountId, unit);
|
||||
return unit;
|
||||
}
|
||||
|
||||
public static GateUnit? Get(this GateUnitManageComponent self, long accountId)
|
||||
{
|
||||
return self.Units.GetValueOrDefault(accountId);
|
||||
}
|
||||
|
||||
public static bool TryGet(this GateUnitManageComponent self, long accountId, out GateUnit? unit)
|
||||
{
|
||||
return self.Units.TryGetValue(accountId, out unit);
|
||||
}
|
||||
|
||||
public static async FTask Remove(this GateUnitManageComponent self, long accountId, bool isDispose = true)
|
||||
{
|
||||
if (!self.Units.TryGetValue(accountId, out var unit)) return;
|
||||
//通知其他服务器下线
|
||||
var result = await GateLoginHelper.Offline(unit);
|
||||
if (result != 0)
|
||||
{
|
||||
Log.Error($"通知其他服务器下线失败,错误码:{result}");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Info($"accountId:{accountId} 下线成功");
|
||||
self.Units.Remove(accountId);
|
||||
if (isDispose)
|
||||
{
|
||||
unit.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Hotfix/Gate/System/GateUnitSessionComponentSystem.cs
Normal file
17
Hotfix/Gate/System/GateUnitSessionComponentSystem.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Fantasy.Entitas.Interface;
|
||||
|
||||
namespace NB.Gate;
|
||||
|
||||
public class GateUnitSessionComponentSystem : DestroySystem<GateUnitSessionComponent>
|
||||
{
|
||||
protected override void Destroy(GateUnitSessionComponent self)
|
||||
{
|
||||
var gateUnitManageComponent = self.Scene.GetComponent<GateUnitManageComponent>();
|
||||
if (gateUnitManageComponent != null)
|
||||
{
|
||||
_ = gateUnitManageComponent.Remove(self.AccountID);
|
||||
}
|
||||
|
||||
self.AccountID = 0;
|
||||
}
|
||||
}
|
||||
16
Hotfix/Gate/System/GateUnitSystem.cs
Normal file
16
Hotfix/Gate/System/GateUnitSystem.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Fantasy.Entitas.Interface;
|
||||
|
||||
namespace NB.Gate;
|
||||
|
||||
public class GateUnitDestroySystem : DestroySystem<GateUnit>
|
||||
{
|
||||
protected override void Destroy(GateUnit self)
|
||||
{
|
||||
self.AccountID = 0;
|
||||
self.Kick = false;
|
||||
}
|
||||
}
|
||||
|
||||
public class GateUnitSystem
|
||||
{
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
using Fantasy.Entitas.Interface;
|
||||
|
||||
namespace NB.Gate;
|
||||
|
||||
public sealed class SessionPlayerComponentDestroySystem : DestroySystem<SessionPlayerComponent>
|
||||
{
|
||||
protected override void Destroy(SessionPlayerComponent self)
|
||||
{
|
||||
if (self.AccountID != 0)
|
||||
{
|
||||
// 执行下线过程、并且要求在5分钟后完成缓存清理。也就是5分钟后会保存数据到数据库。
|
||||
// 由于5分钟太长了、咱们测试的时候,不方便测试,也可以把这个时间改短一些,比如10秒。
|
||||
// PlayerHelper.Disconnect(self.Scene, self.AccountID, 1000 * 60 * 5).Coroutine();
|
||||
// self.AccountID = 0;
|
||||
}
|
||||
|
||||
// self.Player = null;
|
||||
}
|
||||
}
|
||||
// using Fantasy.Entitas.Interface;
|
||||
//
|
||||
// namespace NB.Gate;
|
||||
//
|
||||
// public sealed class SessionPlayerComponentDestroySystem : DestroySystem<GateUnitSessionComponent>
|
||||
// {
|
||||
// protected override void Destroy(GateUnitSessionComponent self)
|
||||
// {
|
||||
// if (self.AccountID != 0)
|
||||
// {
|
||||
// // 执行下线过程、并且要求在5分钟后完成缓存清理。也就是5分钟后会保存数据到数据库。
|
||||
// // 由于5分钟太长了、咱们测试的时候,不方便测试,也可以把这个时间改短一些,比如10秒。
|
||||
// // PlayerHelper.Disconnect(self.Scene, self.AccountID, 1000 * 60 * 5).Coroutine();
|
||||
// // self.AccountID = 0;
|
||||
// }
|
||||
//
|
||||
// // self.Player = null;
|
||||
// }
|
||||
// }
|
||||
Reference in New Issue
Block a user