초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,399 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Google.Protobuf.WellKnownTypes;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using StackExchange.Redis;
using NLog.Layouts;
using Amazon.CloudWatchLogs.Model;
using Microsoft.AspNetCore.Identity;
using ServerCore;
using ServerBase;
using SESSION_ID = System.Int32;
using WORLD_ID = System.UInt32;
using META_ID = System.UInt32;
using ENTITY_GUID = System.String;
using ACCOUNT_ID_STRING = System.String;
using ACCOUNT_ID = System.String;
using OWNER_GUID = System.String;
using USER_GUID = System.String;
using CHARACTER_GUID = System.String;
using ITEM_GUID = System.String;
using PARTY_GUID = System.String;
namespace ServerCommon;
public class LoginCache : CacheBase
{
public USER_GUID UserGuid = string.Empty;
public ACCOUNT_ID_STRING AccountIdString = string.Empty;
public ACCOUNT_ID AccountId = string.Empty;
public LanguageType LanguageType = LanguageType.None;
public DateTime LoginDateTime;
public PlayerStateType State = PlayerStateType.None; //클라이언트 주도로 저장되고 있다, 어떤 상태가 관리되는지 확인해 본다. - kangms
// 접속중인 서버 정보
public string CurrentServer = String.Empty;
// 가입된 파티 식별키
public string PartyGuid = string.Empty;
// 접속중인 인스턴트 룸 식별키
public string InstanceRoomId = string.Empty;
public Int32 ServerSwitchCount = 0;
public class ReservationToSwitchServer
{
public string OneTimeKey = string.Empty;
public string DestServer = string.Empty;
}
public ReservationToSwitchServer? ReservedToSwitchServer { get; set; } = null;
public LoginCache()
: base()
{
}
private void copyCacheFromAccountAttribute(AccountAttribute accountAttribute)
{
NullReferenceCheckHelper.throwIfNull(accountAttribute, () => $"accountAttribute is null !!!");
AccountIdString = accountAttribute.AccountIdString;
AccountId = accountAttribute.AccountId;
UserGuid = accountAttribute.UserGuid;
LanguageType = accountAttribute.LanguageType;
LoginDateTime = accountAttribute.LoginDateTime;
}
public void copyCacheFromAccountAttributeWithServerName(AccountAttribute accountAttribute, string currServer)
{
copyCacheFromAccountAttribute(accountAttribute);
CurrentServer = currServer;
}
public string toBasicString()
{
return $"LoginCacheInfo: AccountIdString:{AccountIdString}, AccountId:{AccountId}, UserGuid:{UserGuid}, LanguageType:{LanguageType}, LoginDateTime:{LoginDateTime}";
}
}
public partial class LoginCacheRequest : RedisRequestPrivateBase
{
public static readonly double LOGIN_CACHE_EXPIRY_TIME = ConstValue.default_1_hour_to_sec * ConstValue.default_1_sec_to_milisec;
public static readonly double SERVER_SWITCH_CACHE_EXPIRY_TIME = 5 * (ConstValue.default_1_min_to_sec * ConstValue.default_1_sec_to_milisec);
// Requester User
private USER_GUID m_user_guid = string.Empty;
private ACCOUNT_ID_STRING m_account_id_string = string.Empty;
private ACCOUNT_ID m_account_id = string.Empty;
// Request Target UserGuid
private USER_GUID m_target_user_guid = string.Empty;
// Out
private LoginCache? m_login_cache_nullable;
public LoginCacheRequest(UserBase owner, RedisConnector redisConnector)
: base(owner, redisConnector)
{
var account_attribute = owner.getOriginEntityAttribute<AccountAttribute>();
NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {owner.toBasicString()}");
m_account_id_string = account_attribute.AccountIdString;
m_account_id = account_attribute.AccountId;
m_user_guid = account_attribute.UserGuid;
m_target_user_guid = m_user_guid;
}
public LoginCacheRequest(IServerLogic owner, RedisConnector redisConnector)
: base(owner, redisConnector)
{
}
private static string getPrefixOfKey() { return $"login:"; }
protected override string onMakeKey()
{
return $"{getPrefixOfKey()}{m_target_user_guid}";
}
protected string onMakeKeyWith(string combinationKey)
{
return $"login:{combinationKey}";
}
public async Task<Result> fetchLogin()
{
var result = new Result();
var err_msg = string.Empty;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
var database = getDatabase();
var redis_value = await database.StringGetAsync(getKey(), CommandFlags.PreferReplica);
if (true == redis_value.HasValue)
{
var curr_login_cache = JsonConvert.DeserializeObject<LoginCache>(redis_value.ToString());
if (null == curr_login_cache)
{
err_msg = $"Failed to convert DeserializeObject of Json !!! : {toBasicString()} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.JsonConvertDeserializeFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
m_login_cache_nullable = curr_login_cache;
return result;
}
else
{
err_msg = $"Failed to get LoginCache in Redis !!! : Key:{getKey()} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.RedisLoginCacheGetFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
catch(Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get LoginCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {getOwner().toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> isLoginableToUserAuth()
{
var owner = getOwner();
var result = new Result();
var err_msg = string.Empty;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
var database = getDatabase();
var redis_value = await database.StringGetAsync(getKey(), CommandFlags.PreferReplica);
if (true == redis_value.HasValue)
{
var curr_login_cache = JsonConvert.DeserializeObject<LoginCache>(redis_value.ToString());
if (null == curr_login_cache)
{
err_msg = $"Failed to convert DeserializeObject of Json !!! : {redis_value.ToString()} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.JsonConvertDeserializeFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
m_login_cache_nullable = curr_login_cache;
if(curr_login_cache.ReservedToSwitchServer != null)
{
err_msg = $"User is switching Server !!! : {curr_login_cache.toBasicString()} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.UserIsSwitchingServer, err_msg);
return result;
}
err_msg = $"User Login Duplicated !!! : {curr_login_cache.toBasicString()} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.UserDuplicatedLogin, err_msg);
return result;
}
return result;
}
catch (Exception e)
{
err_msg = $"Failed to get LoginCache from Redis !!! : Exception:{e} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
public async Task<Result> isLoginableToGame(string currConnectedServer, string toCheckOtp)
{
var owner = getOwner();
var result = new Result();
var err_msg = string.Empty;
try
{
result = await fetchLogin();
if (result.isFail())
{
return result;
}
var curr_login_cache = getLoginCache();
NullReferenceCheckHelper.throwIfNull(curr_login_cache, () => "Login Cache is null !!");
if (curr_login_cache.ReservedToSwitchServer == null)
{
err_msg = $"User is not switching Server !!! : {curr_login_cache.toBasicString()} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.UserIsNotSwitchingServer, err_msg);
return result;
}
var dest_server = curr_login_cache.ReservedToSwitchServer.DestServer;
if (currConnectedServer != dest_server)
{
err_msg = $"Not matched Dest Server !!! : currServer:{currConnectedServer} == destServer:{dest_server} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.ConnectedServerIsNotDestServer, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
var reserved_otp = curr_login_cache.ReservedToSwitchServer.OneTimeKey;
if (reserved_otp != toCheckOtp)
{
err_msg = $"Server switching Otp not match !!! : reservedOtp:{reserved_otp} == toCheckOtp:{toCheckOtp} - {curr_login_cache.toBasicString()}, {owner.toBasicString()}";
result.setFail(ServerErrorCode.ServerSwitchingOtpNotMatch, err_msg);
return result;
}
return result;
}
catch (Exception e)
{
err_msg = $"Failed to get LoginCache from Redis !!! : Exception:{e} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
public async Task<Result> upsertLogin()
{
var result = new Result();
var err_msg = string.Empty;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
if (getTargetUserGuid() != m_user_guid)
{
err_msg = $"Failed to set LoginCacheInfo !!!, OwnerUserGuid and TargetUserGuid not match !!! : OwnerUserGuid:{m_user_guid} != TargetUserGuid:{getTargetUserGuid()} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.RedisLoginCacheOwnerUserGuidNotMatch, err_msg);
Log.getLogger().error(err_msg);
return result;
}
var login_cache = getLoginCache();
NullReferenceCheckHelper.throwIfNull(login_cache, () => "login_cache is null !!!");
var login_cache_json_string = login_cache.toJsonString();
var database = getDatabase();
if (false == await database.StringSetAsync(getKey(), login_cache_json_string, TimeSpan.FromMilliseconds(LOGIN_CACHE_EXPIRY_TIME)))
{
err_msg = $"Failed to set LoginCacheInfo to Redis !!! : Key:{getKey()} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.RedisLoginCacheSetFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
catch (Exception e)
{
err_msg = $"Failed to set LoginCache in Redis !!! : : Exception:{e} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
public async Task logout(USER_GUID userGuid)
{
var key = onMakeKeyWith(userGuid);
var database = getDatabase();
await database.KeyDeleteAsync(key);
var err_msg = $"Logout in LoginCache - userGuid:{userGuid}";
Log.getLogger().debug(err_msg);
}
public LoginCache? getLoginCache() => m_login_cache_nullable;
public LoginCache newLoginCache() => m_login_cache_nullable = new LoginCache();
public USER_GUID getTargetUserGuid() => m_target_user_guid;
protected void setTargetUserGuid(USER_GUID targetUserGuid) => m_target_user_guid = targetUserGuid;
public override string toBasicString()
{
return $"LoginCache: In:UserGuid:{m_user_guid}, AccountId:{m_account_id}, Out:{m_login_cache_nullable?.toBasicString()}";
}
}
public partial class LoginCacheOtherUserRequest : LoginCacheRequest
{
public LoginCacheOtherUserRequest(UserBase requester, RedisConnector redisConnector, USER_GUID otherUserGuid)
: base(requester, redisConnector)
{
setTargetUserGuid(otherUserGuid);
}
public LoginCacheOtherUserRequest(IServerLogic logic, RedisConnector redisConnector, USER_GUID otherUserGuid)
: base(logic, redisConnector)
{
setTargetUserGuid(otherUserGuid);
}
}