对对对

This commit is contained in:
bob
2025-07-26 17:58:25 +08:00
parent 4d8748e866
commit 6311c7cb12
57 changed files with 458 additions and 317 deletions

View File

@@ -9,7 +9,7 @@ using Fantasy.Platform.Net;
#pragma warning disable CS8602 // Dereference of a possibly null reference.
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
namespace Fantasy.Authentication;
namespace NB.Authentication;
public sealed class AuthenticationComponentDestroySystem : DestroySystem<AuthenticationComponent>
{
@@ -19,7 +19,7 @@ public sealed class AuthenticationComponentDestroySystem : DestroySystem<Authent
{
account.Dispose();
}
self.Accounts.Clear();
}
}
@@ -39,31 +39,31 @@ internal static class AuthenticationComponentSystem
self.AuthenticationCount = authentications.Count;
Log.Info($"鉴权服务器启动成功Position:{self.Position} AuthenticationCount:{self.AuthenticationCount}");
}
internal static async FTask<(uint ErrorCode, long AccountId)> Login(this AuthenticationComponent self, string userName, string password)
internal static async FTask<(uint ErrorCode, long AccountId)> Login(this AuthenticationComponent self,
string userName, string password)
{
// 1、检查传递的参数是否完整
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
{
// 这个1代表的是参数不完整。
return (1, 0);
return (ErrorCode.ErrArgs, 0);
}
// 检查账号是否应该在当前鉴权服务器中处理
// 检查账号是否应该在当前鉴权服务器中处理
var position = HashCodeHelper.MurmurHash3(userName) % self.AuthenticationCount;
if (self.Position != position)
{
// 这个3代表的是当前账号不应该在这个鉴权服务器处理。
return (3, 0);
// return (3, 0);
return (ErrorCode.ErrServer, 0);
}
var scene = self.Scene;
var worldDateBase = scene.World.DataBase;//DateBase
var worldDateBase = scene.World.DataBase; //DateBase
var usernameHashCode = userName.GetHashCode();
using (var @lock = await scene.CoroutineLockComponent.Wait((int)LockType.AuthenticationLoginLock, usernameHashCode))
using (var @lock =
await scene.CoroutineLockComponent.Wait((int)LockType.AuthenticationLoginLock, usernameHashCode))
{
// 如果用户频繁发生登录的请求,导致服务器会频繁请求数据库或缓存。
// 针对这个问题咱们可以利用缓存来解决这个问题。
@@ -71,13 +71,13 @@ internal static class AuthenticationComponentSystem
// 2、key:userName + password, Value = ?
// 3、为了防止缓存暴涨、肯定需要一个定期清理的过程Value肯定是要一个实体了。
// 4、因为这个实体下面咱们可以挂载一个组件这个组件的作用就是定时清理这个缓存。5
// 问题
// 1、如果用户的密码改了怎么办?
// 因为缓存中有定时清除的,所以遇到改密码的情况下,最多等待这个缓存清除了,然后就可以登录了。
// 2、如果我不这样做还有什么其他办法
// 通过防火墙的策略来限制用户请求比如100ms请求一次。
// 作业:
// 在这个AccountCacheInfo下创建一个组件这个组件的功能就是定时清理这个缓存。
@@ -87,23 +87,29 @@ internal static class AuthenticationComponentSystem
if (self.LoginAccounts.TryGetValue(loginAccountsKey, out var accountCacheInfo))
{
account = accountCacheInfo.GetComponent<Account>();
if (account == null)
{
return (2, 0);
return (ErrorCode.ErrAccountOrPass, 0);
}
return (0, account.Id);
return (ErrorCode.Successful, account.Id);
}
uint result = 0;
accountCacheInfo = Entity.Create<AccountCacheInfo>(scene, true, true);
account = await worldDateBase.First<Account>(d => d.Username == userName && d.Password == password);
account = await worldDateBase.First<Account>(d => d.Username == userName);
if (account == null)
{
// 这个2代表的是该用户没有注册或者用户或密码错误
result = 2;
// 没有注册
return (ErrorCode.ErrAccountOrPass, -1); //返回-1用于判断是否需要自动注册
}
if (account.Password != password)
{
//密码错误
result = ErrorCode.ErrAccountOrPass;
}
else
{
@@ -123,7 +129,7 @@ internal static class AuthenticationComponentSystem
return (result, 0);
}
return (0, account.Id);
return (ErrorCode.Successful, account.Id);
}
}
@@ -134,46 +140,48 @@ internal static class AuthenticationComponentSystem
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="source"></param>
internal static async FTask<uint> Register(this AuthenticationComponent self, string username, string password, string source)
internal static async FTask<uint> Register(this AuthenticationComponent self, string username, string password,
string source)
{
// 1、检查传递的参数是否完整
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
// 这个1代表的是参数不完整。
return 1;
return ErrorCode.ErrArgs;
}
// 检查账号是否应该在当前鉴权服务器中处理
var position = HashCodeHelper.MurmurHash3(username) % self.AuthenticationCount;
if (self.Position != position)
{
// 这个3代表的是当前账号不应该在这个鉴权服务器处理。
return 3;
// 这个代表的是当前账号不应该在这个鉴权服务器处理。
return ErrorCode.ErrServer;
}
var usernameHashCode = username.GetHashCode();
var scene = self.Scene;
// 利用协程锁来解决异步的原子问题
using (var @lock = await scene.CoroutineLockComponent.Wait((int)LockType.AuthenticationRegisterLock, usernameHashCode))
using (var @lock =
await scene.CoroutineLockComponent.Wait((int)LockType.AuthenticationRegisterLock, usernameHashCode))
{
// 利用缓存来减少频繁请求数据库或缓存的压力。
if (self.Accounts.TryGetValue(username, out var account))
{
// 这个2代表的是该用户已经存在。
return 2;
return ErrorCode.ErrAccountHave;
}
// 2、数据库查询该账号是否存在
var worldDateBase = scene.World.DataBase;
var isExist = await worldDateBase.Exist<Account>(d => d.Username == username);
if (isExist)
{
// 这个2代表的是该用户已经存在。
return 2;
return ErrorCode.ErrAccountHave;
}
//3、执行到这里的话表示数据库或缓存没有该账号的注册信息需要咱们创建一个。
@@ -190,7 +198,7 @@ internal static class AuthenticationComponentSystem
account.AddComponent<AccountTimeOut>().TimeOut(4000);
// 这个0代表的是操作成功
Log.Info($"Register source:{source} username:{username} accountId:{accountId}");
return 0;
return ErrorCode.Successful;
}
}
@@ -213,7 +221,7 @@ internal static class AuthenticationComponentSystem
{
return;
}
Log.Debug($"Remove cache username:{username} Count:{self.Accounts.Count}");
if (isDispose)
@@ -225,9 +233,9 @@ internal static class AuthenticationComponentSystem
internal static async FTask<uint> Remove(this AuthenticationComponent self, long accountId, string source)
{
var scene = self.Scene;
// 其实呢,这里没必要加协程锁,这里加是为了给大家加深下这个协程锁的印象。
using (var @lock = await scene.CoroutineLockComponent.Wait((int)LockType.AuthenticationRemoveLock, accountId))
{
var worldDateBase = scene.World.DataBase;