diff --git a/Config/NetworkProtocol/Outer/OuterMessage.proto b/Config/NetworkProtocol/Outer/OuterMessage.proto
index c347b24..224e1dc 100644
--- a/Config/NetworkProtocol/Outer/OuterMessage.proto
+++ b/Config/NetworkProtocol/Outer/OuterMessage.proto
@@ -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;
}
\ No newline at end of file
diff --git a/Config/private_key.pem b/Config/private_key.pem
new file mode 100644
index 0000000..8e1c59b
--- /dev/null
+++ b/Config/private_key.pem
@@ -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-----
diff --git a/Config/public_key.pem b/Config/public_key.pem
new file mode 100644
index 0000000..8c2fea3
--- /dev/null
+++ b/Config/public_key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz4LybzjFcMs4cAozF6Zr
+qKZ7Ij1beTggJWGuLt9jMS20P4cxlreQRJyba85R0c4CNtGeaTbXKOsOUSVNusvk
+YsZnDadvJFiFZhygOOex4nsXWpp04XQ1Ro7E2ffAWR0DVgHZpUdAFo8mhUntMP+6
+gQy4Hm5/jhDcSn4GtdIu41YFX8LaJkwwcBZdnQ8C/q2Fca7e4lhbQLyem2lfVAI5
+jV78vzB/aSAVDgCeprw5Kv8DUk06wV9Srp/zO2saIXmmeXw23S6x5zhHsCwI7J3E
+Zdfl18BG4R2u1EJOKmuwyYVEJMetQk9lktfquOYNmdDeQmqKfgqVWT1gXcjZC23n
+TQIDAQAB
+-----END PUBLIC KEY-----
diff --git a/Config/密钥20250805230750/应用公钥RSA2048.txt b/Config/密钥20250805230750/应用公钥RSA2048.txt
new file mode 100644
index 0000000..687589b
--- /dev/null
+++ b/Config/密钥20250805230750/应用公钥RSA2048.txt
@@ -0,0 +1 @@
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6EL7hSzceNVL5NFa8HLhtqvxEUHSVh8ChDRhHmltDyZ7pdsesiOBPS2lU++LztOrwNv4Q4KyUnoJ2OPHZAObaZyxXMW89SDJo8hkfx7mgPxhCtLxazcnBBoq+FVEbV24hRlYYpXpEkc2gAu7EmnphnCLpsMLn1WP2d+URxCNbHxy8IKD6Cl9NErKTgbmm5AB0bL+fd2vtxH/u3rVPBHM7Cu3rO37NjsUdY62nE88+IBp6jLT099F7ixz2mVqFeCvubnWv8vowl0Sj9zOhx+xz+h9UjysnJA0fPK6xl0s2ArGfGmNJNHQncAPxDj8t7t4/8oJr4oBiYrw4TChMikmwIDAQAB
\ No newline at end of file
diff --git a/Config/密钥20250805230750/应用私钥RSA2048-敏感数据,请妥善保管.txt b/Config/密钥20250805230750/应用私钥RSA2048-敏感数据,请妥善保管.txt
new file mode 100644
index 0000000..98577a5
--- /dev/null
+++ b/Config/密钥20250805230750/应用私钥RSA2048-敏感数据,请妥善保管.txt
@@ -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==
\ No newline at end of file
diff --git a/Entity/Authentication/Entity/Account.cs b/Entity/Authentication/Entity/Account.cs
index 8982809..125e8b3 100644
--- a/Entity/Authentication/Entity/Account.cs
+++ b/Entity/Authentication/Entity/Account.cs
@@ -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; }
}
\ No newline at end of file
diff --git a/Entity/Def/RegionDef.cs b/Entity/Def/RegionDef.cs
new file mode 100644
index 0000000..d0e41fe
--- /dev/null
+++ b/Entity/Def/RegionDef.cs
@@ -0,0 +1,29 @@
+namespace NB;
+
+public static class RegionDef
+{
+ ///
+ /// 中国区
+ ///
+ public const int CN = 1;
+
+ ///
+ /// 亚太区
+ ///
+ public const int Asia = 2;
+
+ ///
+ /// 欧洲区
+ ///
+ public const int Europe = 3;
+
+ ///
+ /// 美洲区
+ ///
+ public const int America = 4;
+
+ ///
+ /// 独联体区
+ ///
+ public const int CIS = 5;
+}
\ No newline at end of file
diff --git a/Entity/Game/Player/PlayerManageComponent.cs b/Entity/Game/Player/PlayerManageComponent.cs
index 99bbac4..f153818 100644
--- a/Entity/Game/Player/PlayerManageComponent.cs
+++ b/Entity/Game/Player/PlayerManageComponent.cs
@@ -12,9 +12,4 @@ public sealed class PlayerManageComponent : Entity
public long AutoSaveTimerId;
public readonly Dictionary Players = new();
-
- ///
- /// 需要保存到数据库的玩家
- ///
- public readonly HashSet NeedSavePlayer = new();
}
\ No newline at end of file
diff --git a/Entity/Gate/GateUnit.cs b/Entity/Gate/GateUnit.cs
new file mode 100644
index 0000000..03529de
--- /dev/null
+++ b/Entity/Gate/GateUnit.cs
@@ -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;
+}
\ No newline at end of file
diff --git a/Entity/Gate/GateUnitManageComponent.cs b/Entity/Gate/GateUnitManageComponent.cs
new file mode 100644
index 0000000..e5187cd
--- /dev/null
+++ b/Entity/Gate/GateUnitManageComponent.cs
@@ -0,0 +1,9 @@
+using Fantasy.Entitas;
+using Fantasy.Network;
+
+namespace NB.Gate;
+
+public class GateUnitManageComponent : Entity
+{
+ public readonly Dictionary Units = new();
+}
\ No newline at end of file
diff --git a/Entity/Gate/GateUnitSessionComponent.cs b/Entity/Gate/GateUnitSessionComponent.cs
new file mode 100644
index 0000000..88dcba7
--- /dev/null
+++ b/Entity/Gate/GateUnitSessionComponent.cs
@@ -0,0 +1,8 @@
+using Fantasy.Entitas;
+
+namespace NB.Gate;
+
+public sealed class GateUnitSessionComponent : Entity
+{
+ public long AccountID;
+}
\ No newline at end of file
diff --git a/Entity/Gate/SessionPlayerComponent.cs b/Entity/Gate/SessionPlayerComponent.cs
deleted file mode 100644
index 8090aff..0000000
--- a/Entity/Gate/SessionPlayerComponent.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using Fantasy.Entitas;
-
-namespace NB.Gate;
-
-public sealed class SessionPlayerComponent : Entity
-{
- public bool Kick { get; set; }
-
- public long AccountID;
-}
\ No newline at end of file
diff --git a/Entity/Generate/NetworkProtocol/OuterMessage.cs b/Entity/Generate/NetworkProtocol/OuterMessage.cs
index de5e21b..ef2aaf4 100644
--- a/Entity/Generate/NetworkProtocol/OuterMessage.cs
+++ b/Entity/Generate/NetworkProtocol/OuterMessage.cs
@@ -29,6 +29,7 @@ namespace Fantasy
Username = default;
Password = default;
LoginType = default;
+ Region = default;
#if FANTASY_NET || FANTASY_UNITY
GetScene().MessagePoolComponent.Return(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; }
}
+ ///
+ /// 发送聊天
+ ///
+ [ProtoContract]
+ public partial class C2Chat_SendMessageRequest : AMessage, ICustomRouteRequest, IProto
+ {
+ public static C2Chat_SendMessageRequest Create(Scene scene)
+ {
+ return scene.MessagePoolComponent.Rent();
+ }
+ public override void Dispose()
+ {
+ Message = default;
+#if FANTASY_NET || FANTASY_UNITY
+ GetScene().MessagePoolComponent.Return(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; }
+ }
+ ///
+ /// 发送聊天响应
+ ///
+ [ProtoContract]
+ public partial class Caht2C_SendMessageResponse : AMessage, ICustomRouteResponse, IProto
+ {
+ public static Caht2C_SendMessageResponse Create(Scene scene)
+ {
+ return scene.MessagePoolComponent.Rent();
+ }
+ public override void Dispose()
+ {
+ ErrorCode = default;
+#if FANTASY_NET || FANTASY_UNITY
+ GetScene().MessagePoolComponent.Return(this);
+#endif
+ }
+ public uint OpCode() { return OuterOpcode.Caht2C_SendMessageResponse; }
+ [ProtoMember(1)]
+ public uint ErrorCode { get; set; }
+ }
+ ///
+ /// 推送消息
+ ///
+ [ProtoContract]
+ public partial class Chat2C_Message : AMessage, ICustomRouteMessage, IProto
+ {
+ public static Chat2C_Message Create(Scene scene)
+ {
+ return scene.MessagePoolComponent.Rent();
+ }
+ public override void Dispose()
+ {
+ Message = default;
+#if FANTASY_NET || FANTASY_UNITY
+ GetScene().MessagePoolComponent.Return(this);
+#endif
+ }
+ public uint OpCode() { return OuterOpcode.Chat2C_Message; }
+ [ProtoIgnore]
+ public int RouteType => Fantasy.RouteType.ChatRoute;
+ [ProtoMember(1)]
+ public string Message { get; set; }
+ }
}
diff --git a/Entity/Generate/NetworkProtocol/OuterOpcode.cs b/Entity/Generate/NetworkProtocol/OuterOpcode.cs
index 231afc0..c686785 100644
--- a/Entity/Generate/NetworkProtocol/OuterOpcode.cs
+++ b/Entity/Generate/NetworkProtocol/OuterOpcode.cs
@@ -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;
}
}
diff --git a/Entity/Model/Def/ErrorCode.cs b/Entity/Model/Def/ErrorCode.cs
index 277e856..ac96af0 100644
--- a/Entity/Model/Def/ErrorCode.cs
+++ b/Entity/Model/Def/ErrorCode.cs
@@ -4,6 +4,11 @@ public class ErrorCode
{
public const uint Successful = 0;
+ ///
+ /// 服务器上线失败
+ ///
+ public const uint OnlineSceneFailed = 1;
+
///
/// 参数有误
///
@@ -29,4 +34,9 @@ public class ErrorCode
/// 账号或密码有误
///
public const uint ErrAccountOrPass = 11002;
+
+ ///
+ /// 登录自动注册没有设置地区
+ ///
+ public const uint RegisterNotRegion = 11011;
}
\ No newline at end of file
diff --git a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EntityComponent.cs b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EntityComponent.cs
index 5baa63e..b367448 100644
--- a/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EntityComponent.cs
+++ b/Fantasy/Fantasy.Net/Fantasy.Net/Runtime/Core/Entitas/Component/EntityComponent.cs
@@ -157,6 +157,10 @@ namespace Fantasy.Entitas
case IDestroySystem iDestroySystem:
{
entitiesType = iDestroySystem.EntitiesType();
+ if (_destroySystems.ContainsKey(entitiesType))
+ {
+
+ }
_destroySystems.Add(entitiesType, iDestroySystem);
break;
}
diff --git a/Hotfix/Authentication/Handler/C2A_LoginRequestHandler.cs b/Hotfix/Authentication/Handler/C2A_LoginRequestHandler.cs
index 9c8b37d..c0ce6a7 100644
--- a/Hotfix/Authentication/Handler/C2A_LoginRequestHandler.cs
+++ b/Hotfix/Authentication/Handler/C2A_LoginRequestHandler.cs
@@ -26,9 +26,13 @@ public class C2A_LoginRequestHandler : MessageRPC
self.Password = null;
self.CreateTime = 0;
self.LoginTime = 0;
+ self.Region = 0;
}
}
\ No newline at end of file
diff --git a/Hotfix/Authentication/System/AuthenticationComponentSystem.cs b/Hotfix/Authentication/System/AuthenticationComponentSystem.cs
index 83b6124..436a6cd 100644
--- a/Hotfix/Authentication/System/AuthenticationComponentSystem.cs
+++ b/Hotfix/Authentication/System/AuthenticationComponentSystem.cs
@@ -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
///
///
///
- ///
+ ///
///
- internal static async FTask Register(this AuthenticationComponent self, string username, string password,
+ internal static async FTask 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(scene, true, true);
account.Username = username;
- account.Password = password;
+ account.Password = username;
+ account.Region = region;
account.CreateTime = TimeHelper.Now;
// 写入这个实体到数据中
await worldDateBase.Save(account);
diff --git a/Hotfix/Authentication/System/AuthenticationHelper.cs b/Hotfix/Authentication/System/AuthenticationHelper.cs
index b319b86..39ccf59 100644
--- a/Hotfix/Authentication/System/AuthenticationHelper.cs
+++ b/Hotfix/Authentication/System/AuthenticationHelper.cs
@@ -12,7 +12,8 @@ public static class AuthenticationHelper
/// 用户名
/// 用户密码
///
- 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().Login(userName, password);
}
@@ -22,12 +23,12 @@ public static class AuthenticationHelper
///
///
/// 用户名
- /// 用户密码
+ /// 注册地区
/// 注册的来源/原因
///
- public static async FTask Register(Scene scene, string username, string password, string source)
+ public static async FTask Register(Scene scene, string username, int region, string source)
{
- return await scene.GetComponent().Register(username, password, source);
+ return await scene.GetComponent().Register(username, region, source);
}
///
diff --git a/Hotfix/Authentication/System/Jwt/AuthenticationJwtComponentSystem.cs b/Hotfix/Authentication/System/Jwt/AuthenticationJwtComponentSystem.cs
index cd3bf77..739dbcd 100644
--- a/Hotfix/Authentication/System/Jwt/AuthenticationJwtComponentSystem.cs
+++ b/Hotfix/Authentication/System/Jwt/AuthenticationJwtComponentSystem.cs
@@ -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);
diff --git a/Hotfix/Authentication/System/Jwt/AuthenticationJwtHelper.cs b/Hotfix/Authentication/System/Jwt/AuthenticationJwtHelper.cs
index 1ed5bf5..80c16c5 100644
--- a/Hotfix/Authentication/System/Jwt/AuthenticationJwtHelper.cs
+++ b/Hotfix/Authentication/System/Jwt/AuthenticationJwtHelper.cs
@@ -11,9 +11,10 @@ public static class AuthenticationJwtHelper
/// AccountId
/// 目标服务器的地址
/// 分配的Scene的Id
+ /// 账号所属地区
///
- 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().GetToken(aId, address, sceneId);
+ return scene.GetComponent().GetToken(aId, address, sceneId, region);
}
}
\ No newline at end of file
diff --git a/Hotfix/Chat/Handler/C2Chat_SendMessageRequestHandler.cs b/Hotfix/Chat/Handler/C2Chat_SendMessageRequestHandler.cs
new file mode 100644
index 0000000..2907994
--- /dev/null
+++ b/Hotfix/Chat/Handler/C2Chat_SendMessageRequestHandler.cs
@@ -0,0 +1,15 @@
+using Fantasy;
+using Fantasy.Async;
+using Fantasy.Network.Interface;
+
+namespace NB.Chat;
+
+public sealed class
+ C2Chat_SendMessageRequestHandler : RouteRPC
+{
+ protected override async FTask Run(ChatUnit chatUnit, C2Chat_SendMessageRequest request,
+ Caht2C_SendMessageResponse response, Action reply)
+ {
+ ChatSceneHelper.Broadcast(chatUnit.Scene, request.Message);
+ }
+}
\ No newline at end of file
diff --git a/Hotfix/Chat/Helper/ChatSceneHelper.cs b/Hotfix/Chat/Helper/ChatSceneHelper.cs
new file mode 100644
index 0000000..9417fd2
--- /dev/null
+++ b/Hotfix/Chat/Helper/ChatSceneHelper.cs
@@ -0,0 +1,29 @@
+using Fantasy;
+using Fantasy.Platform.Net;
+
+namespace NB.Chat;
+
+public static class ChatSceneHelper
+{
+ ///
+ /// 广播消息
+ ///
+ ///
+ ///
+ 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Hotfix/Game/Helper/GameSceneHelper.cs b/Hotfix/Game/Helper/GameSceneHelper.cs
new file mode 100644
index 0000000..993db41
--- /dev/null
+++ b/Hotfix/Game/Helper/GameSceneHelper.cs
@@ -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();
+ }
+}
\ No newline at end of file
diff --git a/Hotfix/Gate/Handler/C2G_GetAccountInfoRequestHandler.cs b/Hotfix/Gate/Handler/C2G_GetAccountInfoRequestHandler.cs
deleted file mode 100644
index a286832..0000000
--- a/Hotfix/Gate/Handler/C2G_GetAccountInfoRequestHandler.cs
+++ /dev/null
@@ -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
-// {
-// protected override async FTask Run(Session session, C2G_GetAccountInfoRequest request, G2C_GetAccountInfoResponse response, Action reply)
-// {
-// var gameAccountFlagComponent = session.GetComponent();
-//
-// if (gameAccountFlagComponent == null)
-// {
-// // 表示不应该访问这个接口,要先访问登录的接口。
-// // response.ErrorCode = 1;
-// session.Dispose();
-// return;
-// }
-//
-// Player account = gameAccountFlagComponent.Player;
-//
-// if (account == null)
-// {
-// // 表示这个Account已经被销毁过了。不是咱们想要的了
-// }
-//
-// response.GameAccountInfo = account.GetGameAccountInfo();
-// await FTask.CompletedTask;
-// }
-// }
\ No newline at end of file
diff --git a/Hotfix/Gate/Handler/C2G_LoginRequestHandler.cs b/Hotfix/Gate/Handler/C2G_LoginRequestHandler.cs
index 326541d..607a931 100644
--- a/Hotfix/Gate/Handler/C2G_LoginRequestHandler.cs
+++ b/Hotfix/Gate/Handler/C2G_LoginRequestHandler.cs
@@ -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();
+
+ 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();
- // 需要再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();
- 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.AddAddress(RouteType.GameRoute, gameResponse.RoleRouteId);
+ //
+ // // 给当前Session添加一个组件,当Session销毁的时候会销毁这个组件。
+ // var accountFlagComponent = session.AddComponent();
+ // accountFlagComponent.AccountID = accountId;
+
}
}
\ No newline at end of file
diff --git a/Hotfix/Gate/Helper/GateLoginHelper.cs b/Hotfix/Gate/Helper/GateLoginHelper.cs
new file mode 100644
index 0000000..bb8b844
--- /dev/null
+++ b/Hotfix/Gate/Helper/GateLoginHelper.cs
@@ -0,0 +1,75 @@
+using Fantasy;
+using Fantasy.Async;
+using Fantasy.Network;
+using NB.Game;
+
+namespace NB.Gate;
+
+public static class GateLoginHelper
+{
+ ///
+ /// 网关通知其他服务器上线
+ ///
+ ///
+ ///
+ public static async FTask Online(GateUnit gateUnit)
+ {
+ if (gateUnit == null)
+ {
+ return ErrorCode.ErrArgs;
+ }
+
+ Session session = gateUnit.Session;
+ if (session == null)
+ {
+ return ErrorCode.ErrArgs;
+ }
+
+ var gateUnitSessionComponent = session.GetComponent();
+ if (gateUnitSessionComponent == null)
+ {
+ gateUnitSessionComponent = session.AddComponent();
+ }
+
+ var routeComponent = session.GetComponent();
+ if (routeComponent == null)
+ {
+ routeComponent = session.AddComponent();
+ }
+
+ 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;
+ }
+
+ ///
+ /// 网关通知其他服务器下线
+ ///
+ ///
+ ///
+ public static async FTask Offline(GateUnit gateUnit)
+ {
+ //通知服务器下线
+ return ErrorCode.Successful;
+ }
+}
\ No newline at end of file
diff --git a/Hotfix/Gate/System/GateUnitManageComponentSystem.cs b/Hotfix/Gate/System/GateUnitManageComponentSystem.cs
new file mode 100644
index 0000000..cd3c4cd
--- /dev/null
+++ b/Hotfix/Gate/System/GateUnitManageComponentSystem.cs
@@ -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(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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Hotfix/Gate/System/GateUnitSessionComponentSystem.cs b/Hotfix/Gate/System/GateUnitSessionComponentSystem.cs
new file mode 100644
index 0000000..98c1fe1
--- /dev/null
+++ b/Hotfix/Gate/System/GateUnitSessionComponentSystem.cs
@@ -0,0 +1,17 @@
+using Fantasy.Entitas.Interface;
+
+namespace NB.Gate;
+
+public class GateUnitSessionComponentSystem : DestroySystem
+{
+ protected override void Destroy(GateUnitSessionComponent self)
+ {
+ var gateUnitManageComponent = self.Scene.GetComponent();
+ if (gateUnitManageComponent != null)
+ {
+ _ = gateUnitManageComponent.Remove(self.AccountID);
+ }
+
+ self.AccountID = 0;
+ }
+}
\ No newline at end of file
diff --git a/Hotfix/Gate/System/GateUnitSystem.cs b/Hotfix/Gate/System/GateUnitSystem.cs
new file mode 100644
index 0000000..5ad76f9
--- /dev/null
+++ b/Hotfix/Gate/System/GateUnitSystem.cs
@@ -0,0 +1,16 @@
+using Fantasy.Entitas.Interface;
+
+namespace NB.Gate;
+
+public class GateUnitDestroySystem : DestroySystem
+{
+ protected override void Destroy(GateUnit self)
+ {
+ self.AccountID = 0;
+ self.Kick = false;
+ }
+}
+
+public class GateUnitSystem
+{
+}
\ No newline at end of file
diff --git a/Hotfix/Gate/System/PlayerFlagComponentSystem.cs b/Hotfix/Gate/System/PlayerFlagComponentSystem.cs
index 77f0d53..825c6f5 100644
--- a/Hotfix/Gate/System/PlayerFlagComponentSystem.cs
+++ b/Hotfix/Gate/System/PlayerFlagComponentSystem.cs
@@ -1,19 +1,19 @@
-using Fantasy.Entitas.Interface;
-
-namespace NB.Gate;
-
-public sealed class SessionPlayerComponentDestroySystem : DestroySystem
-{
- 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;
- }
-}
\ No newline at end of file
+// using Fantasy.Entitas.Interface;
+//
+// namespace NB.Gate;
+//
+// public sealed class SessionPlayerComponentDestroySystem : DestroySystem
+// {
+// 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;
+// }
+// }
\ No newline at end of file
diff --git a/Hotfix/OnSceneCreate_Init.cs b/Hotfix/OnSceneCreate_Init.cs
index ef991b5..0a5cc6a 100644
--- a/Hotfix/OnSceneCreate_Init.cs
+++ b/Hotfix/OnSceneCreate_Init.cs
@@ -25,6 +25,8 @@ public class OnSceneCreate_Init : AsyncEventSystem
}
case SceneType.Gate:
{
+ // 用于管理网关所有连接的组件
+ scene.AddComponent();
// 用于验证JWT是否合法的组件
scene.AddComponent();
break;
diff --git a/Server.sln.DotSettings.user b/Server.sln.DotSettings.user
index 3bbff5d..08fab59 100644
--- a/Server.sln.DotSettings.user
+++ b/Server.sln.DotSettings.user
@@ -31,6 +31,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded