177 lines
6.7 KiB
C#
177 lines
6.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using Microsoft.AspNetCore.DataProtection.KeyManagement;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Nettention.Proud;
|
|
using Newtonsoft.Json;
|
|
using OtpNet;
|
|
using Pipelines.Sockets.Unofficial.Buffers;
|
|
using StackExchange.Redis;
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
|
|
|
|
using SESSION_ID = System.Int32;
|
|
using META_ID = System.UInt32;
|
|
using ENTITY_GUID = 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;
|
|
|
|
|
|
|
|
namespace ServerCommon;
|
|
|
|
public static class ServerConnectionSwitchHelper
|
|
{
|
|
public static async Task<Result> registerUserOtpToTargetServer(UserBase entityUser, RedisConnector redisConnector
|
|
, string destServer)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
(result, var reserved_to_switch_server) = await startServerSwitch(entityUser, redisConnector, destServer);
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
NullReferenceCheckHelper.throwIfNull(reserved_to_switch_server, () => $"reserved_to_switch_server is null !!!");
|
|
|
|
var account_attribute = entityUser.getEntityAttribute<AccountAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {entityUser.toBasicString()}");
|
|
|
|
account_attribute.OtpForServerConnect = reserved_to_switch_server.OneTimeKey;
|
|
|
|
return result;
|
|
}
|
|
|
|
public static async Task<(Result, LoginCache.ReservationToSwitchServer?)> startServerSwitch(UserBase entityUser, RedisConnector redisConnector, string destServer)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
try
|
|
{
|
|
var login_cache_request = new LoginCacheRequest(entityUser, redisConnector);
|
|
result = await login_cache_request.onPrepareRequest();
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
string key = login_cache_request.getKey();
|
|
var database = login_cache_request.getDatabase();
|
|
|
|
var value = await database.StringGetAsync(key, CommandFlags.PreferReplica);
|
|
if (value.HasValue == false)
|
|
{
|
|
err_msg = $"Not found Key !!! : Key:{key} - {entityUser.toBasicString()}";
|
|
result.setFail(ServerErrorCode.RedisLoginCacheGetFailed, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
var login_cache = JsonConvert.DeserializeObject<LoginCache>(value.ToString());
|
|
if (null == login_cache)
|
|
{
|
|
err_msg = $"Failed to JsonConvert.DeserializeObject !!! : {login_cache_request.toBasicString()} - {entityUser.toBasicString()}";
|
|
result.setFail(ServerErrorCode.JsonConvertDeserializeFailed, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
var otp = KeyGeneration.GenerateRandomKey(20);
|
|
var otp_encoding_by_base32 = Base32Encoding.ToString(otp);
|
|
|
|
login_cache.ReservedToSwitchServer = new LoginCache.ReservationToSwitchServer()
|
|
{
|
|
OneTimeKey = otp_encoding_by_base32,
|
|
DestServer = destServer
|
|
};
|
|
|
|
var json_string = login_cache.toJsonString();
|
|
|
|
if (await database.StringSetAsync(key, json_string, TimeSpan.FromMilliseconds(LoginCacheRequest.SERVER_SWITCH_CACHE_EXPIRY_TIME)) == false)
|
|
{
|
|
err_msg = $"Failed to StringSetAsync !!! : Key:{key}, JsonString:{json_string} - {entityUser.toBasicString()}";
|
|
result.setFail(ServerErrorCode.RedisStringsWriteFailed, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
Log.getLogger().info($"Server Switching Start : currServer:{login_cache.CurrentServer}, destServer:{destServer} - {entityUser.toBasicString()}");
|
|
|
|
return (result, login_cache.ReservedToSwitchServer);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
err_msg = $"Failed to startServerSwitch !!! : Exception:{e} - {entityUser.toBasicString()}";
|
|
result.setFail(ServerErrorCode.TryCatchException, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, null);
|
|
}
|
|
}
|
|
|
|
public static async Task<Result> endServerSwitch(EntityBase entityUser, LoginCacheRequest loginCacheRequest
|
|
, string currConnectedServer
|
|
, DateTime switchedDateTime)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
try
|
|
{
|
|
var database = loginCacheRequest.getDatabase();
|
|
var login_cache = loginCacheRequest.getLoginCache();
|
|
|
|
NullReferenceCheckHelper.throwIfNull(login_cache, () => $"login_cache is null !!!");
|
|
NullReferenceCheckHelper.throwIfNull(login_cache.ReservedToSwitchServer, () => $"login_cache.ReservedToSwitchServer is null !!!");
|
|
|
|
string prev_connected_server = login_cache.CurrentServer;
|
|
|
|
login_cache.LoginDateTime = switchedDateTime;
|
|
|
|
login_cache.ServerSwitchCount += 1;
|
|
login_cache.CurrentServer = login_cache.ReservedToSwitchServer.DestServer;
|
|
login_cache.ReservedToSwitchServer = null;
|
|
|
|
var key = loginCacheRequest.getKey();
|
|
var json_string = login_cache.toJsonString();
|
|
|
|
if (await database.StringSetAsync(key, json_string, TimeSpan.FromMilliseconds(LoginCacheRequest.LOGIN_CACHE_EXPIRY_TIME)) == false)
|
|
{
|
|
err_msg = $"Failed to StringSetAsync !!! : Key:{key}, JsonString:{json_string} - {entityUser.toBasicString()}";
|
|
result.setFail(ServerErrorCode.RedisStringsWriteFailed, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return result;
|
|
}
|
|
|
|
Log.getLogger().info($"Server Switching End : prevServer:{prev_connected_server} => currServer:{currConnectedServer} - {entityUser.toBasicString()}");
|
|
|
|
return result;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
err_msg = $"Failed to startServerSwitch !!! : Exception:{e} - {entityUser.toBasicString()}";
|
|
result.setFail(ServerErrorCode.TryCatchException, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return result;
|
|
}
|
|
}
|
|
}
|