chat
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
syntax = "proto3";
|
||||
package Fantasy.Network.Message;
|
||||
|
||||
|
||||
|
||||
// 协议分为:
|
||||
// ProtoBuf:可以在Outer和Inner文件里使用。
|
||||
// MemoryPack:可以在Outer和Inner文件里使用。
|
||||
@@ -11,12 +14,14 @@ message C2A_LoginRequest // IRequest,A2C_LoginResponse
|
||||
{
|
||||
string Username = 1;
|
||||
string Password = 2;
|
||||
int32 LoginType = 3;
|
||||
int32 LoginType = 3; //登录方式
|
||||
int32 Region = 4; //登录地区,如果是注册,则必须传入
|
||||
}
|
||||
message A2C_LoginResponse // IResponse
|
||||
{
|
||||
string ToKen = 1;
|
||||
}
|
||||
|
||||
/// 客户端登录到Gate服务器
|
||||
message C2G_LoginRequest // IRequest,G2C_LoginResponse
|
||||
{
|
||||
@@ -71,4 +76,21 @@ message Game2C_MailState // ICustomRouteMessage,GameRoute
|
||||
{
|
||||
int32 MailState = 1;
|
||||
int64 MailId = 2;
|
||||
}
|
||||
|
||||
///发送聊天
|
||||
message C2Chat_SendMessageRequest // ICustomRouteRequest,Caht2C_SendMessageResponse,ChatRoute
|
||||
{
|
||||
string Message = 1;
|
||||
}
|
||||
///发送聊天响应
|
||||
message Caht2C_SendMessageResponse // ICustomRouteResponse
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///推送消息
|
||||
message Chat2C_Message // ICustomRouteMessage,ChatRoute
|
||||
{
|
||||
string Message = 1;
|
||||
}
|
||||
28
Config/private_key.pem
Normal file
28
Config/private_key.pem
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPgvJvOMVwyzhw
|
||||
CjMXpmuopnsiPVt5OCAlYa4u32MxLbQ/hzGWt5BEnJtrzlHRzgI20Z5pNtco6w5R
|
||||
JU26y+RixmcNp28kWIVmHKA457HiexdamnThdDVGjsTZ98BZHQNWAdmlR0AWjyaF
|
||||
Se0w/7qBDLgebn+OENxKfga10i7jVgVfwtomTDBwFl2dDwL+rYVxrt7iWFtAvJ6b
|
||||
aV9UAjmNXvy/MH9pIBUOAJ6mvDkq/wNSTTrBX1Kun/M7axoheaZ5fDbdLrHnOEew
|
||||
LAjsncRl1+XXwEbhHa7UQk4qa7DJhUQkx61CT2WS1+q45g2Z0N5Caop+CpVZPWBd
|
||||
yNkLbedNAgMBAAECggEAM7LwYxjeCfK7giBsZ8NA1cD6cwad3FbJHX8XVhq2HAnC
|
||||
u0QbrOzZTtrElwiNVmvQnec+JADzfICJbdqRIc2L/jbndF2nYUMDozPVEDBbX21i
|
||||
3WIXZhcdcdF+hj6FJ76EdwBZgOW+OBCcnH8VTsybouywD3bgpRyawZ1h3xk5MM5p
|
||||
udZBTv6pHJu4KDCWBziWyLFAFOd2u9NgaRxeHbpq09AvwHyjXK5bKTwOCWFNW9mj
|
||||
FHGo0Pk7hYeYVGa3HktIQ3oAiMiyKLdeB/4SZc35RH6wWGOhLi1jqDgAKuTzVMt+
|
||||
jDWh6ozggEVx8NCrEWtZpSsxlBhWDfxzZd1lFOwMAQKBgQD4KaybHNCPLmJhg8fS
|
||||
J5MhJZBEfyE5fenrMjftLI7c4wo805idggk8c6mBERstYjLPg+hDnjoQHZmy8i0I
|
||||
MLfebH2ts+tqyx12gmKC7zRjNfEBW3QjH8mH5Lq0bF9cPrZj7AVDpzxCAuB9xGfn
|
||||
WwvuNdcx1cWGgAl5zE5CcfvbTQKBgQDWEJ5kHRH39tXbz0Mqbj3CXKsCskZvqSGt
|
||||
4WH35Jx7lZV1iIU/IL+mmQcZLALczOTRuN0Vq3LcyoZSaS/3d3OQEsKKYzJGZNOg
|
||||
nqtS4v2sO/ywSBpduw5cQfZrmOk3x4v1CTzsx6IhCCZFR5S9kWrnqSCVzdtvasnV
|
||||
z3zq3Dw8AQKBgQCaXGnGDhVYipSdbXgUq5MkEhZ71MwY0852AsWw3H98vCi5DzEm
|
||||
ACW4mYU9CCPsheFvHPCTZs9dCNx655LFPnCQhNFkA78SrYcFGTMnmJzwfTQNERLb
|
||||
akFUKx1LbwGeAlA3NS9NFrAvq1RyRoIO8Z4pLQpPMFZuRCQgw8mGIRp1HQKBgQCc
|
||||
EW+5Y+xm0cKnyJuagtdqLi/L/ngWDsRsRmcr2bQw8iUOlOM43EJ+TxF6y7imjIfD
|
||||
U7l0hBRxXwLBcMk07hUGFHdbd+j+o6Ibd7NG8hGqke2wBFGcxrU4lCr51XkrXsPu
|
||||
eba+lunglVV5qy+Jakz76zXDolt7ButyhBz6CmmsAQKBgHVDjpIGsyojxq19OtLm
|
||||
xm3GuK2/+9VruRJ9B4yX2uwj2+x53rCxV6zWkBDMJtjyUjb7epz4xkau73KYoncR
|
||||
B9om+4Nmo+R/p3ACgGjMDoaadyUD1hVM4R+d4VqNv3Ck7YPd/Ehiz3uZRD4njo8D
|
||||
w7xwwzHNjgpL5+xeiMsaUOL9
|
||||
-----END PRIVATE KEY-----
|
||||
9
Config/public_key.pem
Normal file
9
Config/public_key.pem
Normal file
@@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz4LybzjFcMs4cAozF6Zr
|
||||
qKZ7Ij1beTggJWGuLt9jMS20P4cxlreQRJyba85R0c4CNtGeaTbXKOsOUSVNusvk
|
||||
YsZnDadvJFiFZhygOOex4nsXWpp04XQ1Ro7E2ffAWR0DVgHZpUdAFo8mhUntMP+6
|
||||
gQy4Hm5/jhDcSn4GtdIu41YFX8LaJkwwcBZdnQ8C/q2Fca7e4lhbQLyem2lfVAI5
|
||||
jV78vzB/aSAVDgCeprw5Kv8DUk06wV9Srp/zO2saIXmmeXw23S6x5zhHsCwI7J3E
|
||||
Zdfl18BG4R2u1EJOKmuwyYVEJMetQk9lktfquOYNmdDeQmqKfgqVWT1gXcjZC23n
|
||||
TQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
1
Config/密钥20250805230750/应用公钥RSA2048.txt
Normal file
1
Config/密钥20250805230750/应用公钥RSA2048.txt
Normal file
@@ -0,0 +1 @@
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6EL7hSzceNVL5NFa8HLhtqvxEUHSVh8ChDRhHmltDyZ7pdsesiOBPS2lU++LztOrwNv4Q4KyUnoJ2OPHZAObaZyxXMW89SDJo8hkfx7mgPxhCtLxazcnBBoq+FVEbV24hRlYYpXpEkc2gAu7EmnphnCLpsMLn1WP2d+URxCNbHxy8IKD6Cl9NErKTgbmm5AB0bL+fd2vtxH/u3rVPBHM7Cu3rO37NjsUdY62nE88+IBp6jLT099F7ixz2mVqFeCvubnWv8vowl0Sj9zOhx+xz+h9UjysnJA0fPK6xl0s2ArGfGmNJNHQncAPxDj8t7t4/8oJr4oBiYrw4TChMikmwIDAQAB
|
||||
1
Config/密钥20250805230750/应用私钥RSA2048-敏感数据,请妥善保管.txt
Normal file
1
Config/密钥20250805230750/应用私钥RSA2048-敏感数据,请妥善保管.txt
Normal file
@@ -0,0 +1 @@
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCPoQvuFLNx41Uvk0VrwcuG2q/ERQdJWHwKENGEeaW0PJnul2x6yI4E9LaVT74vO06vA2/hDgrJSegnY48dkA5tpnLFcxbz1IMmjyGR/HuaA/GEK0vFrNycEGir4VURtXbiFGVhilekSRzaAC7sSaemGcIumwwufVY/Z35RHEI1sfHLwgoPoKX00SspOBuabkAHRsv593a+3Ef+7etU8EczsK7es7fs2OxR1jracTzz4gGnqMtPT30XuLHPaZWoV4K+5uda/y+jCXRKP3M6HH7HP6H1SPKyckDR88rrGXSzYCsZ8aY0k0dCdwA/EOPy3u3j/ygmvigGJivDhMKEyKSbAgMBAAECggEAdMsUlGko8jdWEfXDwbg49FPoEcXAAxh85QKAHSV+ZW3SDn37rGxhcA4+WnQZxvaHKTG2TF/KzZvXuA/xVKzLzsZHFeBcjbIFY9mIBto0+Cy0vDEo0Hmcexuswffd4SSao4TKW+LPGbyKRYtYnLPYK+1ORe+2nCc3dx+FTBeaj2X9d1d4f1PsdvNrPEkNz+p+dhY/g9Gm7FyS3WLSnUt0j25m3p+fvxvUInwhLBE9fyUlP2t/wHXOkd/KR1ncw5HebYK/dgN1RSa/izXmfFpKGGfxb4o5ZeYJgzvn5nkJHfBerki+5nuYhlcXm4qJn95V8LZ8yixSq7hTNy3tJx4CYQKBgQD32JI579iw2F/fLKwjnv1o61uLQJYvGB8JsWACVdny5kJt+AJaggCHNhMUOLgj1/Gywt6V9CEUhCminxIKC5gW12HfQtV6L9/lyA3ymND5lyWZKFqvLlksHqyvqlyK31uLm6UE4nP6NQ+NWfo5ue6gS1vp/wvhiM3LOFsPxDNgzQKBgQCUWrs3wX3YvHIODu8bgYBpgSin6tpNIxm1iojHnp5XtXcP5fNgOpRb0QjJjckdpFoLvCWURybhhDbJDwDiucm69RlT1fkKeQrAeiKpEQuKySN1xUjqQyKYVd4LKJl7rJT7RSgxar5nsbF5dCb98wj8TXeKeTNbYEI6O0MKhVj7BwKBgBpjot4sXYQm5b5bgVChoxXCyZKAI/2LsfJUQoa9IWGthrEy0P1WDjxXU5y5lVGrsn54JT8OKV+H2u8HxOHw7hawhClDcnt6EXrj3ChSgR2yLDysgUtZwgDimzxxBT18HsE0p1Nn0TV45NkGFZCD7ZZ/r5+wmlE/Qbo7m+aH23iZAoGAMHTKPdXnYwl6P3lFRDiyVsOnIeGl2Bgk55UORBVdJszQzNKRAddgafUG5751+EacWsTjiWEMJBDpTBaodWW1rGkuEqILLA6JIoFCHPLCUFyORoNf45R2EkfJtN9X8ntWVhQqoql486mojEESE1R0lORArWwVCD2SpC6DIUaY37UCgYAHbSfZUUeDMHlVMF6ZF4SbDsYw1ATPkhPOWnoBhm2zk0marGnXKlUdsRBL2JwYek648dSQ9Y9G4+sFt6qROBWel1U72Y76zczs34OkeYIEUPYLlL2P859tWtDLv3gnA4m65EdxfrxkUyFJiS+4+c4MDLPt3mNhNHA19/wtRsJsjA==
|
||||
@@ -6,6 +6,7 @@ public sealed class Account : Entity
|
||||
{
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
public int Region { get; set; }
|
||||
public long CreateTime { get; set; }
|
||||
public long LoginTime { get; set; }
|
||||
}
|
||||
29
Entity/Def/RegionDef.cs
Normal file
29
Entity/Def/RegionDef.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace NB;
|
||||
|
||||
public static class RegionDef
|
||||
{
|
||||
/// <summary>
|
||||
/// 中国区
|
||||
/// </summary>
|
||||
public const int CN = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 亚太区
|
||||
/// </summary>
|
||||
public const int Asia = 2;
|
||||
|
||||
/// <summary>
|
||||
/// 欧洲区
|
||||
/// </summary>
|
||||
public const int Europe = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 美洲区
|
||||
/// </summary>
|
||||
public const int America = 4;
|
||||
|
||||
/// <summary>
|
||||
/// 独联体区
|
||||
/// </summary>
|
||||
public const int CIS = 5;
|
||||
}
|
||||
@@ -12,9 +12,4 @@ public sealed class PlayerManageComponent : Entity
|
||||
public long AutoSaveTimerId;
|
||||
|
||||
public readonly Dictionary<long, Player> Players = new();
|
||||
|
||||
/// <summary>
|
||||
/// 需要保存到数据库的玩家
|
||||
/// </summary>
|
||||
public readonly HashSet<long> NeedSavePlayer = new();
|
||||
}
|
||||
14
Entity/Gate/GateUnit.cs
Normal file
14
Entity/Gate/GateUnit.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Network;
|
||||
|
||||
namespace NB.Gate;
|
||||
|
||||
public class GateUnit : Entity
|
||||
{
|
||||
public bool Kick;
|
||||
public long AccountID;
|
||||
public int Region;
|
||||
public long GameSceneRouteId;
|
||||
public long ChatSceneRouteId;
|
||||
public EntityReference<Session> Session;
|
||||
}
|
||||
9
Entity/Gate/GateUnitManageComponent.cs
Normal file
9
Entity/Gate/GateUnitManageComponent.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Network;
|
||||
|
||||
namespace NB.Gate;
|
||||
|
||||
public class GateUnitManageComponent : Entity
|
||||
{
|
||||
public readonly Dictionary<long, GateUnit> Units = new();
|
||||
}
|
||||
8
Entity/Gate/GateUnitSessionComponent.cs
Normal file
8
Entity/Gate/GateUnitSessionComponent.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NB.Gate;
|
||||
|
||||
public sealed class GateUnitSessionComponent : Entity
|
||||
{
|
||||
public long AccountID;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NB.Gate;
|
||||
|
||||
public sealed class SessionPlayerComponent : Entity
|
||||
{
|
||||
public bool Kick { get; set; }
|
||||
|
||||
public long AccountID;
|
||||
}
|
||||
@@ -29,6 +29,7 @@ namespace Fantasy
|
||||
Username = default;
|
||||
Password = default;
|
||||
LoginType = default;
|
||||
Region = default;
|
||||
#if FANTASY_NET || FANTASY_UNITY
|
||||
GetScene().MessagePoolComponent.Return<C2A_LoginRequest>(this);
|
||||
#endif
|
||||
@@ -42,6 +43,8 @@ namespace Fantasy
|
||||
public string Password { get; set; }
|
||||
[ProtoMember(3)]
|
||||
public int LoginType { get; set; }
|
||||
[ProtoMember(4)]
|
||||
public int Region { get; set; }
|
||||
}
|
||||
[ProtoContract]
|
||||
public partial class A2C_LoginResponse : AMessage, IResponse, IProto
|
||||
@@ -284,4 +287,73 @@ namespace Fantasy
|
||||
[ProtoMember(2)]
|
||||
public long MailId { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送聊天
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class C2Chat_SendMessageRequest : AMessage, ICustomRouteRequest, IProto
|
||||
{
|
||||
public static C2Chat_SendMessageRequest Create(Scene scene)
|
||||
{
|
||||
return scene.MessagePoolComponent.Rent<C2Chat_SendMessageRequest>();
|
||||
}
|
||||
public override void Dispose()
|
||||
{
|
||||
Message = default;
|
||||
#if FANTASY_NET || FANTASY_UNITY
|
||||
GetScene().MessagePoolComponent.Return<C2Chat_SendMessageRequest>(this);
|
||||
#endif
|
||||
}
|
||||
[ProtoIgnore]
|
||||
public Caht2C_SendMessageResponse ResponseType { get; set; }
|
||||
public uint OpCode() { return OuterOpcode.C2Chat_SendMessageRequest; }
|
||||
[ProtoIgnore]
|
||||
public int RouteType => Fantasy.RouteType.ChatRoute;
|
||||
[ProtoMember(1)]
|
||||
public string Message { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送聊天响应
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Caht2C_SendMessageResponse : AMessage, ICustomRouteResponse, IProto
|
||||
{
|
||||
public static Caht2C_SendMessageResponse Create(Scene scene)
|
||||
{
|
||||
return scene.MessagePoolComponent.Rent<Caht2C_SendMessageResponse>();
|
||||
}
|
||||
public override void Dispose()
|
||||
{
|
||||
ErrorCode = default;
|
||||
#if FANTASY_NET || FANTASY_UNITY
|
||||
GetScene().MessagePoolComponent.Return<Caht2C_SendMessageResponse>(this);
|
||||
#endif
|
||||
}
|
||||
public uint OpCode() { return OuterOpcode.Caht2C_SendMessageResponse; }
|
||||
[ProtoMember(1)]
|
||||
public uint ErrorCode { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 推送消息
|
||||
/// </summary>
|
||||
[ProtoContract]
|
||||
public partial class Chat2C_Message : AMessage, ICustomRouteMessage, IProto
|
||||
{
|
||||
public static Chat2C_Message Create(Scene scene)
|
||||
{
|
||||
return scene.MessagePoolComponent.Rent<Chat2C_Message>();
|
||||
}
|
||||
public override void Dispose()
|
||||
{
|
||||
Message = default;
|
||||
#if FANTASY_NET || FANTASY_UNITY
|
||||
GetScene().MessagePoolComponent.Return<Chat2C_Message>(this);
|
||||
#endif
|
||||
}
|
||||
public uint OpCode() { return OuterOpcode.Chat2C_Message; }
|
||||
[ProtoIgnore]
|
||||
public int RouteType => Fantasy.RouteType.ChatRoute;
|
||||
[ProtoMember(1)]
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,8 @@ namespace Fantasy
|
||||
public const uint Game2C_GetMailsResponse = 2415929106;
|
||||
public const uint Game2C_HaveMail = 2147493649;
|
||||
public const uint Game2C_MailState = 2147493650;
|
||||
public const uint C2Chat_SendMessageRequest = 2281711379;
|
||||
public const uint Caht2C_SendMessageResponse = 2415929107;
|
||||
public const uint Chat2C_Message = 2147493651;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@ public class ErrorCode
|
||||
{
|
||||
public const uint Successful = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 服务器上线失败
|
||||
/// </summary>
|
||||
public const uint OnlineSceneFailed = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 参数有误
|
||||
/// </summary>
|
||||
@@ -29,4 +34,9 @@ public class ErrorCode
|
||||
/// 账号或密码有误
|
||||
/// </summary>
|
||||
public const uint ErrAccountOrPass = 11002;
|
||||
|
||||
/// <summary>
|
||||
/// 登录自动注册没有设置地区
|
||||
/// </summary>
|
||||
public const uint RegisterNotRegion = 11011;
|
||||
}
|
||||
@@ -157,6 +157,10 @@ namespace Fantasy.Entitas
|
||||
case IDestroySystem iDestroySystem:
|
||||
{
|
||||
entitiesType = iDestroySystem.EntitiesType();
|
||||
if (_destroySystems.ContainsKey(entitiesType))
|
||||
{
|
||||
|
||||
}
|
||||
_destroySystems.Add(entitiesType, iDestroySystem);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,13 @@ public class C2A_LoginRequestHandler : MessageRPC<C2A_LoginRequest, A2C_LoginRes
|
||||
|
||||
if (result.ErrorCode != ErrorCode.Successful && result.AccountId == -1)
|
||||
{
|
||||
if (request.Region == 0)
|
||||
{
|
||||
request.Region = RegionDef.CN;
|
||||
}
|
||||
//开始注册账号
|
||||
var regErrorCode =
|
||||
await AuthenticationHelper.Register(session.Scene, request.Username, request.Password, "用户注册");
|
||||
await AuthenticationHelper.Register(session.Scene, request.Username, request.Region, "用户注册");
|
||||
if (regErrorCode != ErrorCode.Successful)
|
||||
{
|
||||
result.ErrorCode = regErrorCode;
|
||||
@@ -55,7 +59,7 @@ public class C2A_LoginRequestHandler : MessageRPC<C2A_LoginRequest, A2C_LoginRes
|
||||
var machineConfig = MachineConfigData.Instance.Get(processConfig.MachineId);
|
||||
// 颁发一个ToKen令牌给客户端
|
||||
response.ToKen = AuthenticationJwtHelper.GetToken(scene, result.AccountId,
|
||||
$"{machineConfig.OuterIP}:{outerPort}", gateSceneConfig.Id);
|
||||
$"{machineConfig.OuterIP}:{outerPort}", gateSceneConfig.Id, result.region);
|
||||
}
|
||||
|
||||
response.ErrorCode = result.ErrorCode;
|
||||
|
||||
@@ -11,5 +11,6 @@ public class AccountDestroySystem : DestroySystem<Account>
|
||||
self.Password = null;
|
||||
self.CreateTime = 0;
|
||||
self.LoginTime = 0;
|
||||
self.Region = 0;
|
||||
}
|
||||
}
|
||||
@@ -40,13 +40,13 @@ internal static class AuthenticationComponentSystem
|
||||
Log.Info($"鉴权服务器启动成功!Position:{self.Position} AuthenticationCount:{self.AuthenticationCount}");
|
||||
}
|
||||
|
||||
internal static async FTask<(uint ErrorCode, long AccountId)> Login(this AuthenticationComponent self,
|
||||
internal static async FTask<(uint ErrorCode, long AccountId, int region)> Login(this AuthenticationComponent self,
|
||||
string userName, string password)
|
||||
{
|
||||
// 1、检查传递的参数是否完整
|
||||
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
|
||||
{
|
||||
return (ErrorCode.ErrArgs, 0);
|
||||
return (ErrorCode.ErrArgs, 0, 0);
|
||||
}
|
||||
|
||||
// 检查账号是否应该在当前鉴权服务器中处理
|
||||
@@ -55,7 +55,7 @@ internal static class AuthenticationComponentSystem
|
||||
{
|
||||
// 这个3代表的是当前账号不应该在这个鉴权服务器处理。
|
||||
// return (3, 0);
|
||||
return (ErrorCode.ErrServer, 0);
|
||||
return (ErrorCode.ErrServer, 0, 0);
|
||||
}
|
||||
|
||||
var scene = self.Scene;
|
||||
@@ -90,10 +90,10 @@ internal static class AuthenticationComponentSystem
|
||||
|
||||
if (account == null)
|
||||
{
|
||||
return (ErrorCode.ErrAccountOrPass, 0);
|
||||
return (ErrorCode.ErrAccountOrPass, 0, 0);
|
||||
}
|
||||
|
||||
return (ErrorCode.Successful, account.Id);
|
||||
return (ErrorCode.Successful, account.Id, account.Region);
|
||||
}
|
||||
|
||||
uint result = 0;
|
||||
@@ -103,7 +103,7 @@ internal static class AuthenticationComponentSystem
|
||||
if (account == null)
|
||||
{
|
||||
// 没有注册
|
||||
return (ErrorCode.ErrAccountOrPass, -1); //返回-1,用于判断是否需要自动注册
|
||||
return (ErrorCode.ErrAccountOrPass, -1, 0); //返回-1,用于判断是否需要自动注册
|
||||
}
|
||||
|
||||
if (account.Password != password)
|
||||
@@ -126,10 +126,10 @@ internal static class AuthenticationComponentSystem
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
return (result, 0);
|
||||
return (result, 0, 0);
|
||||
}
|
||||
|
||||
return (ErrorCode.Successful, account.Id);
|
||||
return (ErrorCode.Successful, account.Id, account.Region);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,14 +138,14 @@ internal static class AuthenticationComponentSystem
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="username"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <param name="region"></param>
|
||||
/// <param name="source"></param>
|
||||
internal static async FTask<uint> Register(this AuthenticationComponent self, string username, string password,
|
||||
internal static async FTask<uint> Register(this AuthenticationComponent self, string username, int region,
|
||||
string source)
|
||||
{
|
||||
// 1、检查传递的参数是否完整
|
||||
|
||||
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
|
||||
if (string.IsNullOrEmpty(username))
|
||||
{
|
||||
// 这个1代表的是参数不完整。
|
||||
return ErrorCode.ErrArgs;
|
||||
@@ -187,7 +187,8 @@ internal static class AuthenticationComponentSystem
|
||||
//3、执行到这里的话,表示数据库或缓存没有该账号的注册信息,需要咱们创建一个。
|
||||
account = Entity.Create<Account>(scene, true, true);
|
||||
account.Username = username;
|
||||
account.Password = password;
|
||||
account.Password = username;
|
||||
account.Region = region;
|
||||
account.CreateTime = TimeHelper.Now;
|
||||
// 写入这个实体到数据中
|
||||
await worldDateBase.Save(account);
|
||||
|
||||
@@ -12,7 +12,8 @@ public static class AuthenticationHelper
|
||||
/// <param name="userName">用户名</param>
|
||||
/// <param name="password">用户密码</param>
|
||||
/// <returns></returns>
|
||||
public static async FTask<(uint ErrorCode, long AccountId)> Login(Scene scene, string userName, string password)
|
||||
public static async FTask<(uint ErrorCode, long AccountId, int region)> Login(Scene scene, string userName,
|
||||
string password)
|
||||
{
|
||||
return await scene.GetComponent<AuthenticationComponent>().Login(userName, password);
|
||||
}
|
||||
@@ -22,12 +23,12 @@ public static class AuthenticationHelper
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="username">用户名</param>
|
||||
/// <param name="password">用户密码</param>
|
||||
/// <param name="region">注册地区</param>
|
||||
/// <param name="source">注册的来源/原因</param>
|
||||
/// <returns></returns>
|
||||
public static async FTask<uint> Register(Scene scene, string username, string password, string source)
|
||||
public static async FTask<uint> Register(Scene scene, string username, int region, string source)
|
||||
{
|
||||
return await scene.GetComponent<AuthenticationComponent>().Register(username, password, source);
|
||||
return await scene.GetComponent<AuthenticationComponent>().Register(username, region, source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -29,24 +29,25 @@ public static class AuthenticationJwtComponentSystem
|
||||
ValidateIssuer = true, // 验证发行者
|
||||
ValidateAudience = true, // 验证受众
|
||||
ValidateIssuerSigningKey = true, // 验证签名密钥
|
||||
ValidIssuer = "Fantasy", // 有效的发行者
|
||||
ValidAudience = "Fantasy", // 有效的受众
|
||||
ValidIssuer = "NoBug", // 有效的发行者
|
||||
ValidAudience = "NoBug", // 有效的受众
|
||||
IssuerSigningKey = new RsaSecurityKey(rsa) // RSA公钥作为签名密钥
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetToken(this AuthenticationJwtComponent self, long aId, string address, uint sceneId)
|
||||
public static string GetToken(this AuthenticationJwtComponent self, long aId, string address, uint sceneId, int region)
|
||||
{
|
||||
var jwtPayload = new JwtPayload()
|
||||
{
|
||||
{ "aId", aId },
|
||||
{ "Address", address },
|
||||
{ "SceneId", sceneId }
|
||||
{ "SceneId", sceneId },
|
||||
{ "Region", region },
|
||||
};
|
||||
|
||||
var jwtSecurityToken = new JwtSecurityToken(
|
||||
issuer: "Fantasy",
|
||||
audience: "Fantasy",
|
||||
issuer: "NoBug",
|
||||
audience: "NoBug",
|
||||
claims: jwtPayload.Claims,
|
||||
expires: DateTime.UtcNow.AddMilliseconds(3000),
|
||||
signingCredentials: self.SigningCredentials);
|
||||
|
||||
@@ -11,9 +11,10 @@ public static class AuthenticationJwtHelper
|
||||
/// <param name="aId">AccountId</param>
|
||||
/// <param name="address">目标服务器的地址</param>
|
||||
/// <param name="sceneId">分配的Scene的Id</param>
|
||||
/// <param name="region">账号所属地区</param>
|
||||
/// <returns></returns>
|
||||
public static string GetToken(Scene scene, long aId, string address, uint sceneId)
|
||||
public static string GetToken(Scene scene, long aId, string address, uint sceneId, int region)
|
||||
{
|
||||
return scene.GetComponent<AuthenticationJwtComponent>().GetToken(aId, address, sceneId);
|
||||
return scene.GetComponent<AuthenticationJwtComponent>().GetToken(aId, address, sceneId, region);
|
||||
}
|
||||
}
|
||||
15
Hotfix/Chat/Handler/C2Chat_SendMessageRequestHandler.cs
Normal file
15
Hotfix/Chat/Handler/C2Chat_SendMessageRequestHandler.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public sealed class
|
||||
C2Chat_SendMessageRequestHandler : RouteRPC<ChatUnit, C2Chat_SendMessageRequest, Caht2C_SendMessageResponse>
|
||||
{
|
||||
protected override async FTask Run(ChatUnit chatUnit, C2Chat_SendMessageRequest request,
|
||||
Caht2C_SendMessageResponse response, Action reply)
|
||||
{
|
||||
ChatSceneHelper.Broadcast(chatUnit.Scene, request.Message);
|
||||
}
|
||||
}
|
||||
29
Hotfix/Chat/Helper/ChatSceneHelper.cs
Normal file
29
Hotfix/Chat/Helper/ChatSceneHelper.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Platform.Net;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public static class ChatSceneHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 广播消息
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void Broadcast(Scene scene, string message)
|
||||
{
|
||||
//发送给所有Gate服务器,让Gate转发给其他客户端
|
||||
var gateConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Gate);
|
||||
|
||||
var sendMessage = new Chat2C_Message()
|
||||
{
|
||||
Message = message
|
||||
};
|
||||
var networkMessagingComponent = scene.NetworkMessagingComponent;
|
||||
foreach (var config in gateConfigs)
|
||||
{
|
||||
//发送给Gate服务器转发消息
|
||||
networkMessagingComponent.SendInnerRoute(config.RouteId, sendMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Hotfix/Game/Helper/GameSceneHelper.cs
Normal file
16
Hotfix/Game/Helper/GameSceneHelper.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Net;
|
||||
using Fantasy;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Platform.Net;
|
||||
|
||||
namespace NB.Game;
|
||||
|
||||
public static class GameSceneHelper
|
||||
{
|
||||
public static SceneConfig GetSceneConfig(Session session)
|
||||
{
|
||||
var gameSceneConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Game);
|
||||
|
||||
return gameSceneConfigs.First();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
// }
|
||||
// }
|
||||
@@ -25,6 +25,8 @@ public class OnSceneCreate_Init : AsyncEventSystem<OnCreateScene>
|
||||
}
|
||||
case SceneType.Gate:
|
||||
{
|
||||
// 用于管理网关所有连接的组件
|
||||
scene.AddComponent<GateUnitManageComponent>();
|
||||
// 用于验证JWT是否合法的组件
|
||||
scene.AddComponent<GateJWTComponent>();
|
||||
break;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInt32_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_003F3f_003F80da7f34_003FInt32_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AINumber_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_003Fbaa8e7d4791cced365c9d7a682f0113b93d06e1c5c78bc63c611d852c11d83cd_003FINumber_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJsonIgnoreAttribute_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_003F7e62198beab24380bbac29171862d1d8adf10_003F0e_003F062c5ada_003FJsonIgnoreAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJwtSecurityToken_002Ecs_002Fl_003AC_0021_003FUsers_003F60527_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7f2ab4cba14312a0d93e2c5adc801b16648_003Fe4_003F74042d58_003FJwtSecurityToken_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_00601_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_003Fac_003F37a729a2_003FList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_00601_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_003F73_003F35ac318d_003FList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMemoryMarshal_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_003F74_003F8c8beed7_003FMemoryMarshal_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
|
||||
Reference in New Issue
Block a user