Eintoo/GameServer/Server/Hotfix/Outter/Authentication/AuthenticationComponentSystem.cs
2025-03-19 18:16:39 +08:00

187 lines
6.7 KiB
C#

using Fantasy;
using Fantasy.Async;
using Fantasy.Entitas;
using Fantasy.Entitas.Interface;
using Fantasy.Helper;
using Fantasy.Platform.Net;
namespace Hotfix;
public static class AuthenticationComponentSystem
{
#region
/// <summary>
/// 注册
/// </summary>
/// <param name="self"></param>
/// <param name="username"></param>
/// <param name="password"></param>
/// <param name="source"></param>
/// <returns></returns>
public static async FTask<uint> Register(this AuthenticationComponent self,string username, string password,string source)
{
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
return GameErrorCode.UsernameOrPasswordCannotBeEmpty;
}
var position = HashCodeHelper.MurmurHash3(username) % self.AuthenticationCount;
if (position != self.Position)
{
return GameErrorCode.UnauthorizedServer;
}
var scene = self.Scene;
var database = scene.World.DataBase;
var userCode = (long)username.GetHashCode();
using (await scene.CoroutineLockComponent.Wait((int)ELockType.AuthenticationRegister,userCode))
{
if (self.RegisterAccounts.ContainsKey(userCode))
{
Log.Debug($"RegisterAccount Fail(注册失败),username:{username} 已存在缓存中");
return GameErrorCode.UserAlreadyExists;
}
var isExist = await database.Exist<Account>(x=>x.Username == username);
if (isExist)
{
Log.Debug($"RegisterAccount Fail(注册失败),username:{username} 已存在数据库中");
return GameErrorCode.UserAlreadyExists;
}
var account = Entity.Create<Account>(scene,true,false);
account.Username = username;
account.Password = password;
account.CreateTime = DateTime.Now.Ticks;
var timerOutCom = account.AddComponent<AccountTimeOuterComponent>();
timerOutCom.TimeOut(5000);
self.RegisterAccounts.Add(userCode,account);
database.Save(account);
Log.Debug($"RegisterAccount Success(注册成功),username:{username},password:{password},source:{source},Position:{self.Scene.SceneConfigId}");
return GameErrorCode.Success;
}
}
/// <summary>
/// 移除注册缓存
/// </summary>
/// <param name="self"></param>
/// <param name="userCode"></param>
/// <param name="isDispose"></param>
public static void RemoveRegisterCacheAccount(this AuthenticationComponent self,long userCode,bool isDispose)
{
if (!self.RegisterAccounts.Remove(userCode,out var account))
{
return;
}
if (isDispose)
{
Log.Debug($"账号{ account.Username}超时,移除缓存");
account.Dispose();
}
}
public static async FTask<(uint error,long accountId)> Login(this AuthenticationComponent self,string username, string password,string source)
{
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
return (GameErrorCode.UsernameOrPasswordCannotBeEmpty,0);
}
var position = HashCodeHelper.MurmurHash3(username) % self.AuthenticationCount;
if (position != self.Position)
{
return (GameErrorCode.UnauthorizedServer,0);
}
var scene = self.Scene;
var database = scene.World.DataBase;
var userCode = (long)username.GetHashCode();
using (await scene.CoroutineLockComponent.Wait((int)ELockType.AuthenticationLogin,userCode))
{
(uint,long) result = (0,0);
if (self.LoginAccounts.TryGetValue(username,out var accountInfoCache))
{
Log.Debug($"Login 失败(账号不存在或者密码不正确),username:{username},password:{password},source:{source} 缓存中查看,Position:{self.Scene.SceneConfigId}");
return accountInfoCache.GetComponent<Account>() != null ? (GameErrorCode.UserAlreadyLogin,0):(GameErrorCode.UserNotFoundOrPasswordIsNotCorrect,0);
}
var account = await database.First<Account>(x=>x.Username == username && x.Password == password);
if (account == null)
{
result = (GameErrorCode.UserNotFoundOrPasswordIsNotCorrect, 0);
Log.Debug($"Login 失败(账号不存在或者密码不正确),username:{username},password:{password},source:{source} 数据库中查看,Position:{self.Scene.SceneConfigId}");
}
var accountInfo = Entity.Create<AccountCacheInfo>(scene,true,false);
if (account !=null)
{
account.Deserialize(scene);
accountInfo.AddComponent(account);
result = (GameErrorCode.Success,account.RuntimeId);
Log.Debug($"Login Success(登录成功),username:{username},password:{password},source:{source},Position:{self.Scene.SceneConfigId}");
}
var timerOutCom = accountInfo.AddComponent<AccountInfoTimeOuterComponent>();
timerOutCom.Key = username;
timerOutCom.TimeOut(6000);
self.LoginAccounts.Add(username,accountInfo);
return result;
}
}
public static void RemoveCacheAccountInfo(this AuthenticationComponent self,string key, bool isDispose)
{
if (!self.LoginAccounts.Remove(key,out var accountCacheInfo))
{
return;
}
if (isDispose)
{
Log.Debug($"Login:username:{key} 用户移除成功 从缓存中");
accountCacheInfo.Dispose();
}
}
public static void UpdatePosition(this AuthenticationComponent self)
{
var authenticationScenes = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Authentication);
var sceneConfig = SceneConfigData.Instance.Get(self.Scene.SceneConfigId);
self.Position = authenticationScenes.IndexOf(sceneConfig);
self.AuthenticationCount = authenticationScenes.Count;
}
#endregion
}
public class AuthenticationComponentAwakeSystem : AwakeSystem<AuthenticationComponent>
{
protected override void Awake(AuthenticationComponent self)
{
self.UpdatePosition();
}
}
public class AuthenticationComponentDestroySystem : DestroySystem<AuthenticationComponent>
{
protected override void Destroy(AuthenticationComponent self)
{
foreach (var account in self.RegisterAccounts.Values.ToArray())
{
account.Dispose();
}
self.RegisterAccounts.Clear();
}
}