초기커밋

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,197 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
using META_ID = System.UInt32;
namespace ServerCommon;
public class BuffCacheInfo
{
public META_ID BuffMetaID = 0;
public DateTime BuffStartTime = new();
}
public class BuffCache : CacheBase, ICopyCacheFromEntityAttribute
{
public ConcurrentDictionary<MetaAssets.EBuffCategory, ConcurrentDictionary<int, BuffCacheInfo>> buff_cache_Infos = new();
public bool copyCacheFromEntityAttribute(EntityAttributeBase entityAttributeBase)
{
var err_msg = string.Empty;
buff_cache_Infos.Clear();
var to_cast_string = typeof(BuffAttribute).Name;
var buff_attribute = entityAttributeBase as BuffAttribute;
if (null == buff_attribute)
{
err_msg = $"Failed to copyCacheFromEntityAttribute() !!!, buff_attribute is null :{to_cast_string}";
Log.getLogger().error(err_msg);
return false;
}
//=====================================================================================
// Attribute => Cache
//=====================================================================================
foreach (var channel_buff in buff_attribute.BuffInfos)
{
foreach(var buff_info in channel_buff.Value)
{
if(buff_cache_Infos.TryGetValue(channel_buff.Key, out var cache_channel_buffs) == false)
{
cache_channel_buffs = new ConcurrentDictionary<int, BuffCacheInfo>();
buff_cache_Infos.TryAdd(channel_buff.Key, cache_channel_buffs);
}
var cache_buff = new BuffCacheInfo();
cache_buff.BuffMetaID = buff_info.Value.BuffMetaID;
cache_buff.BuffStartTime = buff_info.Value.BuffStartTime;
if(cache_channel_buffs.TryAdd(buff_info.Key, cache_buff) == false)
{
err_msg = $"Duplicated buff in channel !!! : buffMetaId:{buff_info.Value.BuffMetaID}";
Log.getLogger().warn(err_msg);
continue;
}
}
}
return true;
}
public string toBasicString()
{
return "";
}
}
public partial class BuffCacheRequest : RedisRequestPrivateBase
{
public static readonly double BUFFER_CACHE_EXPIRY_TIME = ConstValue.default_1_min_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);
// In
private string m_user_guid;
// Out
private BuffCache? m_buff_cache_nullable;
public BuffCacheRequest(UserBase owner, RedisConnector redisConnector)
: base(owner, redisConnector)
{
var accountAttribute = owner.getOriginEntityAttribute<AccountAttribute>();
NullReferenceCheckHelper.throwIfNull(accountAttribute, () => $"accountAttribute is null !!!");
m_user_guid = accountAttribute.UserGuid;
}
public async Task<Result> UpsertBuff()
{
var result = new Result();
var err_msg = string.Empty;
try
{
var buff_cache_json_string = getBuffCache()?.toJsonString();
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!! ");
if (false == await database.StringSetAsync(getKey(), buff_cache_json_string, TimeSpan.FromMilliseconds(BUFFER_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<Result> fetchBuff()
{
var result = new Result();
var err_msg = string.Empty;
var owner = getOwner();
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var redis_value = await database.StringGetAsync(getKey(), CommandFlags.PreferReplica);
if (true == redis_value.HasValue)
{
var curr_buff_cache = JsonConvert.DeserializeObject<BuffCache>(redis_value.ToString());
if (null == curr_buff_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_buff_cache_nullable = curr_buff_cache;
}
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;
}
}
protected override string onMakeKey()
{
return $"buff:{m_user_guid}";
}
protected string onMakeKeyWith(string combinationKey)
{
return $"buff:{combinationKey}";
}
public BuffCache? getBuffCache() => m_buff_cache_nullable;
public BuffCache newBuffCache() => m_buff_cache_nullable = new BuffCache();
public override string toBasicString()
{
return $"BuffCache: In:UserGuid:{m_user_guid}, Out:{m_buff_cache_nullable?.toBasicString()}";
}
}

View File

@@ -0,0 +1,385 @@
using System.ComponentModel;
using ServerCore; using ServerBase;
using StackExchange.Redis;
using USER_GUID = System.String;
namespace ServerCommon.Cache;
public class CaliumConverterManageCacheRequest : RedisRequestSharedBase
{
private const int DefaultManageExpireMinute = 1;
private const string LastDateKey = "lastdate";
private const string CaliumKey = "calium";
// in
// out
public CaliumConverterManageCacheRequest(RedisConnector redisConnector) : base("CaliumConverterManage", redisConnector)
{
}
protected override string onMakeKey() => "caliumConverter:manage";
private string getStartRunningKey() => $"{onMakeKey()}:start";
private string getDailyCaliumForUserKey(int day)
{
var base_key = $"{onMakeKey()}:daily";
base_key = $"{base_key}:{day}";
return base_key;
}
public override string toBasicString() => "CaliumConverterManageCacheRequest";
public async Task<bool> startCaliumConverterManage()
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var redis_value = await database.StringSetAsync(getStartRunningKey(), DateTimeHelper.Current.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(DefaultManageExpireMinute), When.NotExists);
if (false == redis_value) return false;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return false;
}
return true;
}
public async Task<DateTime?> getLastFillUpDailyCaliumDate()
{
var result = new Result();
var last_fill_up_date = DateTimeHelper.MinTime;
try
{
result = await onPrepareRequest();
if (result.isFail()) return null;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var redis_value = await database.HashGetAsync(onMakeKey(), LastDateKey);
if (redis_value.IsNullOrEmpty) return null;
DateTime.TryParse(redis_value, out last_fill_up_date);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return null;
}
return last_fill_up_date;
}
public async Task<Result> setLastFillUpDailyCaliumDate(string lastRunningDate)
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
_ = await database.HashSetAsync(onMakeKey(), LastDateKey, lastRunningDate);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<double> fillUpDailyCalium(double fillUpCalium)
{
var result = new Result();
var is_first = false;
// 1. Last fill up daily date 체크
var last_date = await getLastFillUpDailyCaliumDate();
if (null == last_date) is_first = true;
if (fillUpCalium == 0 && !is_first) return 0;
if(is_first) fillUpCalium += (double)MetaHelper.GameConfigMeta.CaliumConverterInitialValue;
// 2. fill up calium
result = await changeTotalCaliumAsync(fillUpCalium);
if (result.isFail()) return -1;
return fillUpCalium;
}
public async Task<Result> changeTotalCaliumAsync(double calium)
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var redis_value = await database.HashIncrementAsync(onMakeKey(), CaliumKey, calium);
if (redis_value < 0)
{
var err_msg = $"fail to change daily cailum : change calium - {calium}";
result.setFail(ServerErrorCode.RedisHashesWriteFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<bool> isExist(bool isTotal, int day)
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var key = (isTotal) ? onMakeKey() : getDailyCaliumForUserKey(day);
var redis_value = await database.KeyExistsAsync(key);
return redis_value;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get exist key !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return false;
}
}
public async Task<decimal> getTotalCaliumAsync()
{
var result = new Result();
decimal calium;
try
{
result = await onPrepareRequest();
if (result.isFail()) return -1;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var redis_value = await database.HashGetAsync(onMakeKey(), CaliumKey);
if (redis_value.IsNullOrEmpty) return -1;
redis_value.ToString().toDecimal(out calium);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return -1;
}
return calium;
}
public async Task<Result> changeCaliumForUserPerDailyAsync(USER_GUID userGuid, double calium, int day)
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail())
{
result.setFail(ServerErrorCode.RedisHashesWriteFailed, $"failed to prepare request for redis: {nameof(changeCaliumForUserPerDailyAsync)}");
return result;
};
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var key = getDailyCaliumForUserKey(day);
var redis_value = await database.HashIncrementAsync(key, userGuid, calium);
await setTtlCaliumForUserPerDailyAsync(key);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<Dictionary<USER_GUID, double>?> getCaliumForUserPerDailyCountAsync(int day)
{
var result = new Result();
var list = new Dictionary<USER_GUID, double>();
try
{
result = await onPrepareRequest();
if (result.isFail()) return null;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var key = getDailyCaliumForUserKey(day);
var redis_values = await database.HashGetAllAsync(key);
foreach (var value in redis_values)
{
value.Value.ToString().toDecimal(out var calium);
var user_guid = value.Name.ToString();
list.Add(user_guid, (double)calium);
}
return list;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg =
$"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return null;
}
}
public async Task<double> getCaliumForUserPerDailyAsync(USER_GUID userGuid, int day)
{
var result = new Result();
double daily_calium;
try
{
result = await onPrepareRequest();
if (result.isFail()) return 0;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var key = getDailyCaliumForUserKey(day);
var redis_value = await database.HashGetAsync(key, userGuid);
if (redis_value.IsNullOrEmpty)
{
daily_calium = (double)MetaHelper.GameConfigMeta.CaliumConverterLimitPerPerson;
_ = await database.HashSetAsync(key, userGuid, daily_calium);
await setTtlCaliumForUserPerDailyAsync(key);
}
else
{
redis_value.TryParse(out daily_calium);
}
if (daily_calium < 0) daily_calium = 0;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg =
$"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return -1;
}
return daily_calium;
}
private async Task<Result> setTtlCaliumForUserPerDailyAsync(string key)
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
// 1. 현재 ttl 설정 확인
var redis_value = await database.KeyTimeToLiveAsync(key);
if (null != redis_value)
{
return result;
}
// 2. ttl 시간 생성
var current = DateTimeHelper.Current;
var base_time = new DateTime(current.Year, current.Month, current.Day,
MetaHelper.GameConfigMeta.CaliumConverterPivotTime, 0, 0);
TimeSpan check;
if (current < base_time) check = base_time - current;
else check = base_time.AddDays(1) - current;
// 3. ttl 설정
_ = await database.KeyExpireAsync(key, check);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg =
$"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
}

View File

@@ -0,0 +1,141 @@
using ServerCore; using ServerBase;
using StackExchange.Redis;
using USER_GUID = System.String;
namespace ServerCommon;
public class CaliumStorageCacheRequest : RedisRequestSharedBase
{
private const int DefaultManageExpireMs = 1 * 60 * 1000;
// in
// out
public CaliumStorageCacheRequest(RedisConnector redisConnector) : base("CaliumStorageCache", redisConnector)
{
}
protected override string onMakeKey() => "caliumstorage:start";
private string getSyncKey() => "caliumstorage:sync:start";
private string getRetryKey() => "caliumstorage:retry";
public override string toBasicString() => "CaliumStorageCacheRequest";
public async Task<bool> startCaliumConverterManage(bool isSync = false)
{
var result = new Result();
var redis_key = isSync ? getSyncKey() : onMakeKey();
try
{
result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var redis_value = await database.StringSetAsync(redis_key, DateTimeHelper.Current.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMilliseconds(DefaultManageExpireMs), When.NotExists);
if (false == redis_value) return false;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return false;
}
return true;
}
public async Task<bool> checkRetryKey()
{
var result = new Result();
var redis_key = getRetryKey();
try
{
result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var redis_value = await database.KeyExistsAsync(redis_key);
return redis_value;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return false;
}
}
public async Task<bool> setRetryKey()
{
var result = new Result();
var redis_key = getRetryKey();
try
{
result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var check_date = DateTimeHelper.Current.AddDays(1);
var next_date = new DateTime(check_date.Year, check_date.Month, check_date.Day, 0, 0, 0);
next_date = next_date.AddMinutes(-1);
var expire_time = next_date - DateTimeHelper.Current;
var redis_value = await database.StringSetAsync(redis_key, DateTimeHelper.Current.ToString("yyyy-MM-dd HH:mm:ss"), expire_time, When.NotExists);
if (false == redis_value) return false;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return false;
}
return true;
}
public async Task deleteRetryKey()
{
var result = new Result();
var redis_key = getRetryKey();
try
{
result = await onPrepareRequest();
if (result.isFail()) return;
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
await database.KeyDeleteAsync(redis_key, CommandFlags.FireAndForget);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get CaliumConverterManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
}
}

View File

@@ -0,0 +1,88 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
using META_ID = System.UInt32;
namespace ServerCommon;
public partial class CraftHelpCacheRequest : RedisRequestPrivateBase
{
public static readonly double CRAFT_CACHE_EXPIRY_TIME = ConstValue.default_1_day_to_sec * ConstValue.default_1_sec_to_milisec;
private string m_target_guid;
public CraftHelpCacheRequest(UserBase owner, RedisConnector redisConnector, string target_guid)
: base(owner, redisConnector)
{
m_target_guid = target_guid;
}
public async Task<Result> UpsertCraftHelp(string push_Guid)
{
var result = new Result();
var err_msg = string.Empty;
var limitCount = MetaHelper.GameConfigMeta.CraftingHelpLimitCountReceive;
try
{
var database = getDatabase();
string craftHelpListKey = onMakeKey();
var pushAfterLength = await database.ListRightPushAsync(craftHelpListKey, push_Guid);
if (pushAfterLength > limitCount)
{
await database.ListTrimAsync(craftHelpListKey, 0, limitCount - 1);
var trimAfterPosition = await database.ListPositionAsync(craftHelpListKey, push_Guid);
if (trimAfterPosition == -1)
{
err_msg = $"Crafting help receieved Count Over !!! : push_Guid :{push_Guid}- {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.CraftingHelpReceivedCountOver, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
if(pushAfterLength == 1)
{
await database.KeyExpireAsync(craftHelpListKey, TimeSpan.FromMilliseconds(CRAFT_CACHE_EXPIRY_TIME));
}
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;
}
}
protected override string onMakeKey()
{
return $"craftHelp:{m_target_guid}:{DateTime.UtcNow.Date}";
}
public override string toBasicString()
{
return $"craftHelp: In:UserGuid:{m_target_guid}";
}
}

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Amazon.OpenSearchService.Model.Internal.MarshallTransformations;
using Microsoft.IdentityModel.Tokens;
using ServerControlCenter;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
namespace ServerCommon;
public class FriendInterlockCacheRequest : RedisRequestPrivateBase
{
string m_guid = string.Empty;
string m_friend_guid = string.Empty;
public FriendInterlockCacheRequest(UserBase owner, RedisConnector redisConnector, string userGuid, string friendGuid)
: base(owner, redisConnector)
{
m_guid = userGuid;
m_friend_guid = friendGuid;
}
protected override string onMakeKey()
{
return $"friendrequestaction:{getSuffix()}";
}
public async Task<Result> getLock()
{
var key = onMakeKey();
var database = getDatabase();
var result = new Result();
string err_msg;
try
{
if (false == await database.SortedSetAddAsync(key, m_guid, DateTimeOffset.Now.ToUnixTimeMilliseconds()))
{
err_msg = $"Failed to add FriendCache from Redis !!! : key : {key}, guid : {m_guid}";
//result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().warn(err_msg);
//return result;
}
else
{
Log.getLogger().debug($"Success to add FriendCache from Redis !!! : key : {key}, guid : {m_guid}");
}
if (false == await database.KeyExpireAsync(key, TimeSpan.FromMilliseconds(10000)))
{
err_msg = $"Failed to set expire FriendCache from Redis !!! : key : {key}, guid : {m_guid}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(err_msg);
return result;
}
Int32 retry_cnt = 3;
Int32 millisecondTimeout = 100;
for (Int32 i = 0; i < retry_cnt; i++)
{
var values = await database.SortedSetRangeByRankAsync(key, 0, 0, Order.Ascending, CommandFlags.PreferMaster);
if (false == values[0].HasValue)
{
Log.getLogger().warn($"Not Exist Value m_guid : {m_guid}, m_friend_guid : {m_friend_guid}");
System.Threading.Thread.Sleep(millisecondTimeout);
continue;
}
if (true == values[0].Equals(m_guid))
{
return result;
}
else
{
Log.getLogger().warn($"Not Exist Value m_guid : {m_guid}, m_friend_guid : {m_friend_guid}, values[0] : {values[0]}");
System.Threading.Thread.Sleep(millisecondTimeout);
continue;
}
}
}
catch (Exception e)
{
err_msg = $"Failed to get FriendCache from Redis !!! : : errMsg:{e.Message} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(err_msg);
return result;
}
err_msg = $"Failed to get First Data from Redis !!! : - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.FriendInfoNotExist, err_msg);
return result;
}
public async Task<Result> removeFirstCache()
{
string key = onMakeKey();
var database = getDatabase();
var result = new Result();
string err_msg = string.Empty;
try
{
bool ret = await database.SortedSetRemoveAsync(key, m_guid);
if (!ret)
{
err_msg = $"Failed to remove First Data from Redis !!! : - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.ServerLogicError, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
catch (Exception e)
{
err_msg = $"Failed to get FriendCache from Redis !!! : : errMsg:{e.Message} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
public override string toBasicString()
{
return string.Empty;
}
private string getSuffix()
{
string[] strings = new string[2];
strings[0] = m_guid;
strings[1] = m_friend_guid;
Array.Sort(strings);
string suffix = strings[0] + strings[1];
return suffix;
}
}

View File

@@ -0,0 +1,260 @@
using Newtonsoft.Json;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace ServerCommon;
public class FriendRequestCache : CacheBase
{
[JsonProperty("sender_guid")]
public string m_sender_guid { get; set; } = string.Empty;
[JsonProperty("receiver_guid")]
public string m_receiver_guid { get; set; } = string.Empty;
[JsonProperty("is_new")]
public Int32 m_is_new { get; set; } = 0;
[JsonProperty("request_time")]
public DateTime m_request_time { get; set; } = new();
public FriendRequestCache(string sender, string receiver, bool isNew, DateTime requestTime)
{
m_sender_guid = sender;
m_receiver_guid = receiver;
m_is_new = isNew ? 1: 0;
m_request_time = requestTime;
}
}
public class FriendReqCacheRequest : RedisRequestPrivateBase
{
private string m_guid = string.Empty;
private string m_friend_guid = string.Empty;
public FriendReqCacheRequest(UserBase owner, string myGuid, string friendGuid, RedisConnector redisConnector)
: base(owner, redisConnector)
{
m_guid = myGuid;
m_friend_guid = friendGuid;
}
public FriendReqCacheRequest(UserBase owner, string myGuid, RedisConnector redisConnector)
: base(owner, redisConnector)
{
m_guid = myGuid;
m_friend_guid = string.Empty;
}
public override string toBasicString()
{
return $"SendedFriendRequestCache: In:m_guid:{m_guid}";
}
protected override string onMakeKey()
{
return $"friendrequest:{m_guid}";
}
private string makeSendKey(string guid)
{
return $"sendedfriendrequest:{guid}";
}
private string makeRecvKey(string guid)
{
return $"receivedfriendrequest:{guid}";
}
public async Task<List<FriendRequestCache>> getSendedFriendRequests()
{
var database = getDatabase();
string key = makeSendKey(m_guid);
List<FriendRequestCache> sendedFriendRequests = new();
try
{
var hashes = await database.HashGetAllAsync(key, CommandFlags.PreferReplica);
//여기서 가져와서 RequestList로 만들어줘야 한다.
foreach (var entry in hashes)
{
// RedisValue를 문자열로 변환하여 JSON 디시리얼라이즈
var value_string = entry.Value.ToString();
var obj = JsonConvert.DeserializeObject<FriendRequestCache>(value_string);
if(obj == null)
{
string err_msg = $"Failed to get FriendCache from Redis !!! : : value_string:{entry.Value} - {getOwner().toBasicString()}";
Log.getLogger().error(err_msg);
continue;
}
var is_active = await deleteOldRequest(obj.m_request_time, obj.m_sender_guid, obj.m_receiver_guid);
if (is_active)
{
sendedFriendRequests.Add(obj);
}
}
}
catch (Exception e)
{
string err_msg = $"Failed to get FriendCache from Redis !!! : : errMsg:{e.Message} - {getOwner().toBasicString()}";
Log.getLogger().error(err_msg);
return new();
}
return sendedFriendRequests;
}
public async Task<List<FriendRequestCache>> getReceivedFriendRequests()
{
var database = getDatabase();
string key = makeRecvKey(m_guid);
List<FriendRequestCache> recvedFriendRequests = new();
try
{
var hashes = await database.HashGetAllAsync(key, CommandFlags.PreferReplica);
//여기서 가져와서 RequestList로 만들어줘야 한다.
foreach (var entry in hashes)
{
var value_string = entry.Value.ToString();
var obj = JsonConvert.DeserializeObject<FriendRequestCache>(value_string);
if (obj == null)
{
string err_msg = $"Failed to get FriendCache from Redis !!! : : value_string:{value_string} - {getOwner().toBasicString()}";
Log.getLogger().error(err_msg);
continue;
}
var is_active = await deleteOldRequest(obj.m_request_time, obj.m_sender_guid, obj.m_receiver_guid);
if (is_active)
{
recvedFriendRequests.Add(obj);
}
}
}
catch (Exception e)
{
string err_msg = $"Exception !!!, Failed to get FriendCache from Redis !!! : exception:{e} - {getOwner().toBasicString()}";
Log.getLogger().error(err_msg);
return new();
}
return recvedFriendRequests;
}
private async Task<bool> deleteOldRequest(DateTime requestTime, string sender, string receiver)
{
var now = DateTimeHelper.Current;
var expire_time = requestTime.AddSeconds(MetaHelper.GameConfigMeta.SentFriendRequestValidTime);
if (now > expire_time)
{
await deleteCache(sender, receiver);
return false;
}
return true;
}
public async Task<Result> addFriendRequest(string senderGuid, string receiverGuid, DateTime now)
{
var result = new Result();
var database = getDatabase();
var tran = database.CreateTransaction();
{
FriendRequestCache send_req_cache = new FriendRequestCache(senderGuid, receiverGuid, true, now);
FriendRequestCache receuve_req_cache = new FriendRequestCache(senderGuid, receiverGuid, true, now);
await database.HashSetAsync(makeSendKey(senderGuid), receiverGuid, JsonConvert.SerializeObject(send_req_cache));
await database.HashSetAsync(makeRecvKey(receiverGuid), senderGuid, JsonConvert.SerializeObject(receuve_req_cache));
}
bool ret = tran.Execute();
if (false == ret)
{
string err_msg = $"Failed to RedisHashSets Set Failed to Redis !!! : : senderGuid:{senderGuid}, receiverGuid:{receiverGuid}";
result.setFail(ServerErrorCode.RedisHashesWriteFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
return result;
}
public async Task<Result> confirmReceivedFriendRequest()
{
var result = new Result();
var database = getDatabase();
var redis_value = await database.HashGetAsync(makeRecvKey(m_guid), m_friend_guid, CommandFlags.PreferReplica);
var value_string = redis_value.ToString();
var cache = JsonConvert.DeserializeObject<FriendRequestCache>(value_string);
if (cache == null)
{
string err_msg = $"Failed to get FriendCache from Redis !!! : : redis_value:{redis_value} - {getOwner().toBasicString()}";
Log.getLogger().error(err_msg);
result.setFail(ServerErrorCode.RedisHashesReadFailed, err_msg);
return result;
}
cache.m_is_new = 0;
await database.HashSetAsync(makeRecvKey(m_guid), m_friend_guid, JsonConvert.SerializeObject(cache));
return result;
}
public async Task<Result> deleteFriendByReply()
{
var result = await deleteCache(m_friend_guid, m_guid);//수락은은 요청 받은 사람이 하는 것이므로 sender가 friendGuid
return result;
}
public async Task<Result> cancelFriendRequest()
{
var result = await deleteCache(m_guid, m_friend_guid);
return result;
}
public async Task<Result> refuseFriendRequest()
{
var result = await deleteCache(m_friend_guid, m_guid);//거절은 요청 받은 사람이 하는 것이므로 sender가 friendGuid
return result;
}
public async Task<Result> deleteCache(string senderGuid, string receiverGuid)
{
var result = new Result();
var database = getDatabase();
var tran = database.CreateTransaction();
{
await database.HashDeleteAsync(makeSendKey(senderGuid), receiverGuid);
await database.HashDeleteAsync(makeRecvKey(receiverGuid), senderGuid);
}
bool ret = tran.Execute();
if (false == ret)
{
string err_msg = $"Failed to RedisHashSets delete Failed to Redis !!! : : senderGuid:{senderGuid}, receiverGuid:{receiverGuid}";
result.setFail(ServerErrorCode.RedisHashesWriteFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
}

View File

@@ -0,0 +1,118 @@
using StackExchange.Redis;
using ServerCore;
using ServerBase;
using META_ID = System.UInt32;
using USER_GUID = System.String;
namespace ServerCommon;
public class LandAuctionTopBidderCache : CacheBase
{
public META_ID LandMetaId { get; set; } = 0;
public USER_GUID HighestBidUserGuid { get; set; } = string.Empty;
public double HighestBidPrice { get; set; } = 0;
public LandAuctionTopBidderCache()
{ }
}
public class LandAuctionBidPriceOrderCacheRequest : RedisRequestSharedBase
{
private readonly META_ID m_land_meta_id;
public LandAuctionBidPriceOrderCacheRequest(META_ID landMetaId, RedisConnector redisConnector)
: base(landMetaId.ToString(), redisConnector)
{
m_land_meta_id = landMetaId;
}
public async Task<Result> deleteBidPriceOrder()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
var database = getDatabase();
var is_success = await database.KeyDeleteAsync(getKey());
if (false == is_success)
{
err_msg = $"Failed to KeyDeleteAsync() !!! : redisKey:{getKey()} - {toBasicString()}";
Log.getLogger().debug(err_msg);
return result;
}
err_msg = $"LandAuctionTopBidderCache deleted from Cache - redisKey:{getKey()}, {toBasicString()}";
Log.getLogger().debug(err_msg);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to process in deleteBidPriceOrder() !!! : errorCode{error_code}, execption:{e} - redisKey:{getKey()}, {toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<bool> isExistKey()
{
try
{
var result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
var redis_value = await database.KeyExistsAsync(onMakeKey());
return redis_value;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Exception !!!, Failed to perform in LandAuctionBidPriceOrderCacheRequest.isExistKey() !!! : errorCode:{error_code}, exception:{e} - {nameof(isExistKey)}";
Log.getLogger().error(err_msg);
}
return false;
}
public string toKey()
{
return onMakeKey();
}
protected override string onMakeKey()
{
return $"{{{m_land_meta_id}}}:land_auction_bid_order";
}
public string toBlockKey()
{
return $"{{{m_land_meta_id}}}:land_auction_bid_order_block";
}
public string toKeyAll()
{
return $"Key:{toKey()}, BlockKey:{toBlockKey()}";
}
public override string toBasicString()
{
return $"LandAuctionBid - LandMetaId:{m_land_meta_id}";
}
}

View File

@@ -0,0 +1,220 @@
using Newtonsoft.Json;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
using META_ID = System.UInt32;
using USER_GUID = System.String;
using LAND_AUCTION_NUMBER = System.Int32;
namespace ServerCommon;
public class LandAuctionCache : CacheBase
{
public META_ID LandMetaId { get; set; } = 0;
public LAND_AUCTION_NUMBER AuctionNumber { get; set; } = 0;
public LandAuctionState LandAuctionState { get; set; } = LandAuctionState.None;
public LandAuctionResult LandAuctionResult { get; set; } = LandAuctionResult.None;
public DateTime ProcessVersionTime { get; set; } = DateTimeHelper.MinTime;
public LandAuctionCache()
{ }
}
public class LandAuctionCacheRequest : RedisRequestSharedBase
{
private readonly META_ID m_land_meta_id;
private LandAuctionCache? m_land_auction_cache;
public LandAuctionCacheRequest(META_ID landMetaId, RedisConnector redisConnector)
: base(landMetaId.ToString(), redisConnector)
{
m_land_meta_id = landMetaId;
}
public LandAuctionCacheRequest(LandAuctionCache landAuctionCache, RedisConnector redisConnector)
: base(landAuctionCache.LandMetaId.ToString(), redisConnector)
{
m_land_meta_id = landAuctionCache.LandMetaId;
m_land_auction_cache = landAuctionCache;
}
public async Task<Result> upsertLandAuction(double cacheExpiryMinutes)
{
var result = new Result();
var err_msg = string.Empty;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
var location_cache_json_string = getLandAuctionCache()?.toJsonString();
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!! - {toBasicString()}");
var expiry = TimeSpan.FromMinutes(cacheExpiryMinutes);
if (expiry.TotalMilliseconds <= 0) expiry = TimeSpan.FromMilliseconds(1);
if (false == await database.StringSetAsync(getKey(), location_cache_json_string, expiry))
{
err_msg = $"Failed to set LandAuctionCache to Redis !!! : redisKey:{getKey()} - {toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionRedisCacheSetFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
err_msg = $"LandAuctionCache save to Cache !!! : redisKey:{getKey()}, ttlMinutes:{cacheExpiryMinutes} - {toBasicString()}";
Log.getLogger().info(err_msg);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to process in upsertLandAuction() !!! : errorCode{error_code}, exception:{e} - redisKey:{getKey()}, {toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<Result> fetchLandAuction()
{
var result = new Result();
var err_msg = string.Empty;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var redis_value = await database.StringGetAsync(getKey(), CommandFlags.PreferReplica);
if (true == redis_value.HasValue)
{
var curr_buff_cache = JsonConvert.DeserializeObject<LandAuctionCache>(redis_value.ToString());
if (null == curr_buff_cache)
{
err_msg = $"Failed to convert DeserializeObject of Json !!! : {redis_value.ToString()} - {toBasicString()}";
result.setFail(ServerErrorCode.JsonConvertDeserializeFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
m_land_auction_cache = curr_buff_cache;
err_msg = $"LandAuctionCache fetch from Cache !!! : redisKey:{getKey()} - {toBasicString()}";
Log.getLogger().info(err_msg);
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to process in fetchLandAuction() !!! : errorCode{error_code}, exception:{e} - redisKey:{getKey()}, {toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<Result> deleteLandAuction()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
m_land_auction_cache = null;
var database = getDatabase();
var is_success = await database.KeyDeleteAsync(getKey());
if (false == is_success)
{
err_msg = $"Failed to KeyDeleteAsync() !!! : redisKey:{getKey()} - {toBasicString()}";
Log.getLogger().debug(err_msg);
return result;
}
err_msg = $"LandAuctionCache deleted from Cache - redisKey:{getKey()}, {toBasicString()}";
Log.getLogger().debug(err_msg);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to process in deleteLandAuction() !!! : errorCode{error_code}, execption:{e} - redisKey:{getKey()}, {toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
protected override string onMakeKey()
{
return $"{{{m_land_meta_id}}}:land_auction";
}
public async Task<bool> isExistKey()
{
try
{
var result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
return await database.KeyExistsAsync(onMakeKey());
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to process in isExistKey() !!! : errorCode{error_code}, execption:{e} - redisKey:{getKey()}, {toBasicString()}";
Log.getLogger().error(err_msg);
}
return false;
}
public string toKey()
{
return onMakeKey();
}
public LandAuctionCache? getLandAuctionCache() => m_land_auction_cache;
public void setLandAuctionCache(LandAuctionCache cache) => m_land_auction_cache = cache;
public override string toBasicString()
{
return $"{this.getTypeName()} - LandMetaId:{m_land_meta_id}";
}
}

View File

@@ -0,0 +1,226 @@

using Newtonsoft.Json;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
using META_ID = System.UInt32;
using USER_GUID = System.String;
using LAND_AUCTION_NUMBER = System.Int32;
namespace ServerCommon;
public class NormalBidHighestUserCache : CacheBase
{
public META_ID LandMetaId { get; set; } = 0;
public LAND_AUCTION_NUMBER AuctionNumber { get; set; } = 0;
//=============================================================================================
// 일반 입찰 최고 입찰자 정보
//=============================================================================================
public double NormalHighestBidPrice { get; set; } = 0; // 일반 입찰 최고가
public string NormalHighestBidUserGuid { get; set; } = string.Empty; // 일반 입찰 최고가 유저 식별키
public string NormalHighestBidUserNickname { get; set; } = string.Empty; // 일반 입찰 최고가 유저 닉네임
public DateTime HighestRankVersionTime { get; set; } = DateTimeHelper.MinTime; // 최고 입찰자 순위 버전 정보
public NormalBidHighestUserCache()
{ }
}
public class LandAuctionNormalBidHighestUserCacheRequest: RedisRequestSharedBase
{
private readonly META_ID m_land_meta_id;
private NormalBidHighestUserCache? m_normal_bid_highest_user_cache;
public LandAuctionNormalBidHighestUserCacheRequest(META_ID landMetaId, RedisConnector redisConnector)
: base(landMetaId.ToString(), redisConnector)
{
m_land_meta_id = landMetaId;
}
public LandAuctionNormalBidHighestUserCacheRequest(NormalBidHighestUserCache cache, RedisConnector redisConnector)
: base(cache.LandMetaId.ToString(), redisConnector)
{
m_land_meta_id = cache.LandMetaId;
m_normal_bid_highest_user_cache = cache;
}
public async Task<Result> upsertNormalBidHighestUser(double cacheExpiryMinutes)
{
var result = new Result();
var err_msg = string.Empty;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
var cache_json_string = getNormalBidHighestUserCache()?.toJsonString();
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!! - {toBasicString()}");
var expiry = TimeSpan.FromMinutes(cacheExpiryMinutes);
if (expiry.TotalMilliseconds <= 0) expiry = TimeSpan.FromMilliseconds(1);
if (false == await database.StringSetAsync(getKey(), cache_json_string, expiry))
{
err_msg = $"Failed to set NormalBidHighestUserCache to Redis !!! : redisKey:{getKey()} - {toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionRedisCacheSetFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
err_msg = $"NormalBidHighestUserCache save to Cache !!! : redisKey:{getKey()} - {toBasicString()}";
Log.getLogger().info(err_msg);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to process in upsertLandAuction() !!! : errorCode{error_code}, exception:{e} - redisKey:{getKey()}, {toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<Result> fetchNormalBidHighestUser()
{
var result = new Result();
var err_msg = string.Empty;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!!");
var redis_value = await database.StringGetAsync(getKey(), CommandFlags.PreferReplica);
if (true == redis_value.HasValue)
{
var curr_cache = JsonConvert.DeserializeObject<NormalBidHighestUserCache>(redis_value.ToString());
if (null == curr_cache)
{
err_msg = $"Failed to convert DeserializeObject of Json !!! : {redis_value.ToString()} - {toBasicString()}";
result.setFail(ServerErrorCode.JsonConvertDeserializeFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
m_normal_bid_highest_user_cache = curr_cache;
err_msg = $"NormalBidHighestUserCache fetch from Cache !!! : redisKey:{getKey()} - {toBasicString()}";
Log.getLogger().info(err_msg);
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to process in fetchNormalBidHighestUserCache() !!! : errorCode{error_code}, exception:{e} - redisKey:{getKey()}, {toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<Result> deleteNormalBidHighestUser()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
m_normal_bid_highest_user_cache = null;
var database = getDatabase();
var is_success = await database.KeyDeleteAsync(getKey());
if (false == is_success)
{
err_msg = $"Failed to KeyDeleteAsync() !!! : redisKey:{getKey()} - {toBasicString()}";
Log.getLogger().debug(err_msg);
return result;
}
err_msg = $"NormalBidHighestUserCache deleted from Cache - redisKey:{getKey()}, {toBasicString()}";
Log.getLogger().debug(err_msg);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to process in deleteNormalBidHighestUser() !!! : errorCode{error_code}, execption:{e} - redisKey:{getKey()}, {toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
protected override string onMakeKey()
{
return $"{{{m_land_meta_id}}}:land_auction_normal_bid_highest_user";
}
public async Task<bool> isExistKey()
{
try
{
var result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
return await database.KeyExistsAsync(onMakeKey());
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to process in isExistKey() !!! : errorCode{error_code}, execption:{e} - redisKey:{getKey()}, {toBasicString()}";
Log.getLogger().error(err_msg);
}
return false;
}
public string toKey()
{
return onMakeKey();
}
public NormalBidHighestUserCache? getNormalBidHighestUserCache() => m_normal_bid_highest_user_cache;
public void setNormalBidHighestUserCache(NormalBidHighestUserCache cache) => m_normal_bid_highest_user_cache = cache;
public override string toBasicString()
{
return $"{this.getTypeName()} - LandMetaId:{m_land_meta_id}";
}
}

View File

@@ -0,0 +1,170 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using StackExchange.Redis;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
namespace ServerCommon
{
public class LocationCache : CacheBase, ICopyCacheFromEntityAttribute
{
public ChannelServerLocation LastestChannelServerLocation = new();
public List<IndunLocation> ReturnIndunLocations = new();
public IndunLocation EnterIndunLocation = new();
public Timestamp MoveChannelTime = DateTimeHelper.MinTime.ToTimestamp();
public LocationCache()
: base()
{
}
public bool copyCacheFromEntityAttribute(EntityAttributeBase entityAttributeBase)
{
var err_msg = string.Empty;
var to_cast_string = typeof(LocationAttribute).Name;
var location_attribute = entityAttributeBase as LocationAttribute;
if (null == location_attribute)
{
err_msg = $"Failed to copyCacheFromEntityAttribute() !!!, location_attribute is null :{to_cast_string}";
Log.getLogger().error(err_msg);
return false;
}
//=====================================================================================
// Attribute => Cache
//=====================================================================================
LastestChannelServerLocation = location_attribute.LastestChannelServerLocation.clone();
ReturnIndunLocations = location_attribute.ReturnIndunLocations.Select(x => x.clone()).ToList();
EnterIndunLocation = location_attribute.EnterIndunLocation.clone();
MoveChannelTime = location_attribute.MoveChannelTime;
return true;
}
public string toBasicString()
{
return $"Location: ";
}
}
public class LocationCacheRequest : RedisRequestPrivateBase
{
public static readonly double LOCATION_CACHE_EXPIRY_TIME = ConstValue.default_1_min_to_sec * ConstValue.default_1_sec_to_milisec;
// In
private string m_user_guid;
// Out
private LocationCache? m_location_cache_nullable;
public LocationCacheRequest(UserBase owner, RedisConnector redisConnector)
: base(owner, redisConnector)
{
var user_attribute = owner.getEntityAttribute<UserAttribute>();
NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!! - {owner.toBasicString()}");
m_user_guid = user_attribute.UserGuid;
}
public override string toBasicString()
{
return $"Location: In:UserGuid:{m_user_guid}, Out:{m_location_cache_nullable?.toBasicString()}";
}
protected override string onMakeKey()
{
return $"location:{m_user_guid}";
}
public LocationCache? getLocationCache() => m_location_cache_nullable;
public async Task<Result> fetchLocation()
{
var result = new Result();
var err_msg = string.Empty;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
return result;
}
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!! - {getOwner().toBasicString()}");
var redis_value = await database.StringGetAsync(getKey(), CommandFlags.PreferReplica);
if (true == redis_value.HasValue)
{
var location_cache = JsonConvert.DeserializeObject<LocationCache>(redis_value.ToString());
if (null == location_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_location_cache_nullable = location_cache;
}
else
{
m_location_cache_nullable = new();
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get LocationCache 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> upsertLocation()
{
var result = new Result();
var err_msg = string.Empty;
try
{
var location_cache_json_string = getLocationCache()?.toJsonString();
var database = getDatabase();
NullReferenceCheckHelper.throwIfNull(database, () => $"database is null !!! - {getOwner().toBasicString()}");
if (false == await database.StringSetAsync(getKey(), location_cache_json_string, TimeSpan.FromMilliseconds(LOCATION_CACHE_EXPIRY_TIME)))
{
err_msg = $"Failed to set LoactionCacheInfo to Redis !!! : redisKey:{getKey()} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.RedisLocationCacheSetFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
catch (Exception e)
{
err_msg = $"Failed to set LocationCache in Redis !!! : message{e} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
}
}
}

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);
}
}

View File

@@ -0,0 +1,239 @@
using Newtonsoft.Json;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace ServerCommon;
public class PartyCache : CacheBase
{
public string PartyGuid { get; set; } = string.Empty;
public string PartyName { get; set; } = string.Empty;
public string PartyLeaderCharGuid { get; set; } = string.Empty;
public string PartyLeaderNickname { get; set; } = string.Empty;
public DateTime CreatePartyTime { get; set; } = DateTimeHelper.Current;
public Timestamp? LastVoteTime { get; set; }
public string toBasicString()
{
return $"PartyCache: PartyGuid:{PartyGuid}, PartyName:{PartyName}, PartyLeaderCharGuid:{PartyLeaderCharGuid}, LastVoteTime:{LastVoteTime?.toBasicString() ?? string.Empty}";
}
}
public class PartyCacheRequest : RedisRequestSharedBase
{
// in
private readonly string m_party_guid;
// out
private PartyCache? m_party_cache_nullable { get; set; }
public PartyCacheRequest(string party_guid, RedisConnector redisConnector) : base(party_guid, redisConnector)
{
m_party_guid = party_guid;
}
protected override string onMakeKey() => $"party:{m_party_guid}:info";
public override string toBasicString() => $"LoginCache: In:PartyGuid:{m_party_guid}, Out:{m_party_cache_nullable?.toBasicString()}";
public PartyCache? getPartyCache() => m_party_cache_nullable;
public async Task<Result> keepPartyCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.KeyExpireAsync(getKey(), TimeSpan.FromMilliseconds(Constant.KEEP_PARTY_TIME));
if (false == redis_value)
{
err_msg = $"Failed to set expire PartyCache in Redis !!! : Key:{getKey()} - {nameof(keepPartyCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyCacheWriteFailed, err_msg);
Log.getLogger().error(err_msg);
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to keep PartyCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(keepPartyCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> fetchPartyCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.StringGetAsync(getKey(), CommandFlags.PreferReplica);
if (false == redis_value.HasValue)
{
err_msg = $"Failed to get PartyCache in Redis !!! : Key:{getKey()} - {nameof(fetchPartyCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyCacheGetFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
var curr_party_cache = JsonConvert.DeserializeObject<PartyCache>(redis_value.ToString());
if (null == curr_party_cache)
{
err_msg = $"Failed to convert DeserializeObject of Json !!! : {toBasicString()} - {nameof(fetchPartyCache)}";
result.setFail(ServerErrorCode.JsonConvertDeserializeFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
m_party_cache_nullable = curr_party_cache;
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(fetchPartyCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> createPartyCache(string leader_guid, string leader_nickname)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
m_party_cache_nullable ??= new PartyCache();
m_party_cache_nullable.PartyGuid = m_party_guid;
m_party_cache_nullable.PartyName = string.Empty;
m_party_cache_nullable.PartyLeaderCharGuid = leader_guid;
m_party_cache_nullable.PartyLeaderNickname = leader_nickname;
var cache = JsonConvert.SerializeObject(m_party_cache_nullable);
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.StringSetAsync(getKey(), cache, TimeSpan.FromMilliseconds(Constant.KEEP_PARTY_TIME));
if (false == redis_value)
{
err_msg = $"Failed to get PartyCache in Redis !!! : Key:{getKey()} - {nameof(createPartyCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyCacheWriteFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(createPartyCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deletePartyCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
m_party_cache_nullable = null;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
_ = await database.KeyDeleteAsync(getKey() , CommandFlags.FireAndForget);
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to delete PartyCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(deletePartyCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> upsertPartyCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var cache = JsonConvert.SerializeObject(m_party_cache_nullable);
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.StringSetAsync(getKey(), cache, TimeSpan.FromMilliseconds(Constant.KEEP_PARTY_TIME));
if (false == redis_value)
{
err_msg = $"Failed to set PartyCache in Redis !!! : Key:{getKey()} - {nameof(upsertPartyCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyCacheWriteFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(upsertPartyCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
}

View File

@@ -0,0 +1,241 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using StackExchange.Redis;
using Newtonsoft.Json;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace ServerCommon;
public class PartyInstanceCache : CacheBase
{
public int InstanceId { get; set; } = 0;
public string RoomId { get; set; } = string.Empty;
public Timestamp StartTime { get; set; } = new();
public Timestamp EndTime { get; set; } = new();
public int JoinMemberCount { get; set; } = 0;
public string toBasicString()
{
return $"PartyInstanceCache: InstanceId:{InstanceId}, RoomId:{RoomId}, StartTime:{StartTime}, EndTime:{EndTime}, JoinMemberCount:{JoinMemberCount}";
}
}
public class PartyInstanceCacheRequest : RedisRequestSharedBase
{
// in
private readonly string m_party_guid;
// out
private PartyInstanceCache? m_party_instance_cache_nullable { get; set; }
public PartyInstanceCacheRequest(string party_guid, RedisConnector redisConnector) : base(party_guid,
redisConnector)
{
m_party_guid = party_guid;
}
protected override string onMakeKey() => $"party:{m_party_guid}:instance";
public override string toBasicString() => $"PartyInstanceCache: In:PartyGuid:{m_party_guid}, Out:{m_party_instance_cache_nullable?.toBasicString()}";
public PartyInstanceCache? getPartyInstanceCache() => m_party_instance_cache_nullable;
public async Task<Result> keepPartyInstanceCache()
{
var result = new Result();
string err_msg;
if (null == m_party_instance_cache_nullable) return result;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.KeyExpireAsync(getKey(), TimeSpan.FromMilliseconds(Constant.KEEP_PARTY_TIME));
if (false == redis_value)
{
err_msg = $"Failed to set expire PartyInstanceCache in Redis !!! : Key:{getKey()} - {nameof(keepPartyInstanceCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyCacheWriteFailed, err_msg);
Log.getLogger().error(err_msg);
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to keep PartyInstanceCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(keepPartyInstanceCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> fetchPartyInstanceCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.StringGetAsync(getKey(), CommandFlags.PreferReplica);
if (false == redis_value.HasValue)
{
err_msg = $"Failed to get PartyInstanceCache in Redis !!! : Key:{getKey()} - {nameof(fetchPartyInstanceCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyCacheGetFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
var curr_party_instance_cache = JsonConvert.DeserializeObject<PartyInstanceCache>(redis_value.ToString());
if (null == curr_party_instance_cache)
{
err_msg = $"Failed to convert DeserializeObject of Json !!! : {toBasicString()} - {nameof(fetchPartyInstanceCache)}";
result.setFail(ServerErrorCode.JsonConvertDeserializeFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
m_party_instance_cache_nullable = curr_party_instance_cache;
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyInstanceCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(fetchPartyInstanceCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> createPartyInstanceCache(int instanceId, string roomId, Timestamp startTime, Timestamp endTime, int joinCount)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
m_party_instance_cache_nullable ??= new PartyInstanceCache();
m_party_instance_cache_nullable.InstanceId = instanceId;
m_party_instance_cache_nullable.RoomId = roomId;
m_party_instance_cache_nullable.StartTime = startTime;
m_party_instance_cache_nullable.EndTime = endTime;
m_party_instance_cache_nullable.JoinMemberCount = joinCount;
var cache = JsonConvert.SerializeObject(m_party_instance_cache_nullable);
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.StringSetAsync(getKey(), cache, TimeSpan.FromMilliseconds(Constant.KEEP_PARTY_TIME));
if (false == redis_value)
{
err_msg = $"Failed to get PartyInstanceCache in Redis !!! : Key:{getKey()} - {nameof(createPartyInstanceCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyCacheWriteFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyInstanceCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(createPartyInstanceCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deletePartyInstanceCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
m_party_instance_cache_nullable = null;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
_ = await database.KeyDeleteAsync(getKey() , CommandFlags.FireAndForget);
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to delete PartyInstanceCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(deletePartyInstanceCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> upsertPartyInstanceCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var cache = JsonConvert.SerializeObject(m_party_instance_cache_nullable);
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.StringSetAsync(getKey(), cache, TimeSpan.FromMilliseconds(Constant.KEEP_PARTY_TIME));
if (false == redis_value)
{
err_msg = $"Failed to set PartyInstanceCache in Redis !!! : Key:{getKey()} - {nameof(upsertPartyInstanceCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyCacheWriteFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyInstanceCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(upsertPartyInstanceCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
}

View File

@@ -0,0 +1,178 @@
using System.Globalization;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
using USER_GUID = System.String;
namespace ServerCommon;
public class PartyInvitePartyRecvCache : CacheBase
{
public Dictionary<string, DateTime> PartyInvitePartyRecvs { get; set; } = new();
public string toBasicString()
{
return $"PartyCache: PartyInvitePartyRecvs:{PartyInvitePartyRecvs}";
}
}
public class PartyInvitePartyRecvCacheRequest : RedisRequestPrivateBase
{
private readonly USER_GUID m_user_guid;
// out
private PartyInvitePartyRecvCache? m_party_invite_party_recv_cache_nullable { get; set; }
public PartyInvitePartyRecvCacheRequest(UserBase owner, RedisConnector redisConnector) : base(owner, redisConnector)
{
var account_attribute = owner.getEntityAttribute<AccountAttribute>();
ArgumentNullException.ThrowIfNull(account_attribute);
m_user_guid = account_attribute.UserGuid;
}
protected override string onMakeKey() => $"inviteparty:recvlist:{m_user_guid}";
public override string toBasicString() => $"PartyInvitePartyRecvCache: Out:{m_party_invite_party_recv_cache_nullable?.toBasicString()}";
public PartyInvitePartyRecvCache? getPartyInvitePartyRecvCache() => m_party_invite_party_recv_cache_nullable;
public async Task<Result> fetchInvitePartyRecvCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var delete_time = DateTime.UtcNow.AddMilliseconds(-1 * Constant.KEEP_INVITEPARTY_TIME);
var curr_party_invite_party_recvs = new Dictionary<string, DateTime>();
var delete_list = new List<string>();
var redis_value = await database.HashGetAllAsync(getKey(), CommandFlags.PreferReplica);
foreach (var send_value in redis_value)
{
var recv_time = send_value.Value.ToString().toUtcTime();
if (recv_time < delete_time)
{
delete_list.Add(send_value.Name.ToString());
continue;
}
curr_party_invite_party_recvs.Add(send_value.Name.ToString(), recv_time);
}
m_party_invite_party_recv_cache_nullable ??= new PartyInvitePartyRecvCache();
m_party_invite_party_recv_cache_nullable.PartyInvitePartyRecvs.Clear();
foreach (var send in curr_party_invite_party_recvs)
{
m_party_invite_party_recv_cache_nullable.PartyInvitePartyRecvs.Add(send.Key, send.Value);
}
result = await deleteInvitePartyRecvCache(delete_list);
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyInvitePartyRecvCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(fetchInvitePartyRecvCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> addInvitePartyRecvCache(string party_guid, DateTime recv_time)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
await database.HashSetAsync(getKey(), party_guid, recv_time.ToString(CultureInfo.InvariantCulture));
m_party_invite_party_recv_cache_nullable ??= new PartyInvitePartyRecvCache();
m_party_invite_party_recv_cache_nullable.PartyInvitePartyRecvs.Add(party_guid, recv_time);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to add party invite party recv from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(addInvitePartyRecvCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deleteInvitePartyRecvCache(IReadOnlyList<string> delete_user_guids)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var delete_values = new List<RedisValue>(delete_user_guids.Select(x => new RedisValue(x)));
_ = await database.HashDeleteAsync(getKey(), delete_values.ToArray(), CommandFlags.PreferReplica);
foreach (var delete in delete_user_guids)
{
m_party_invite_party_recv_cache_nullable?.PartyInvitePartyRecvs.Remove(delete);
}
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to delete party invite party recv from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(deleteInvitePartyRecvCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<List<string>?> organizeInvitePartyRecvCache()
{
if (null == m_party_invite_party_recv_cache_nullable) return null;
var delete_time = DateTime.UtcNow.AddMilliseconds(-1 * Constant.KEEP_INVITEPARTY_TIME);
var delete_sends = (from recv in m_party_invite_party_recv_cache_nullable.PartyInvitePartyRecvs where recv.Value < delete_time select recv.Key).ToList();
_ = await deleteInvitePartyRecvCache(delete_sends);
return delete_sends;
}
}

View File

@@ -0,0 +1,236 @@
using System.Globalization;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
using USER_GUID = System.String;
namespace ServerCommon;
public class PartyInvitePartySendCache : CacheBase
{
public Dictionary<string, DateTime> PartyInvitePartySends { get; set; } = new();
public string toBasicString()
{
return $"PartyCache: PartyInvitePartySends:{PartyInvitePartySends}";
}
}
public class PartyInvitePartySendCacheRequest : RedisRequestSharedBase
{
// in
private readonly string m_party_guid;
// out
private PartyInvitePartySendCache? m_party_invite_party_send_cache_nullable { get; set; }
public PartyInvitePartySendCacheRequest(string party_guid, RedisConnector redisConnector) : base(party_guid,
redisConnector)
{
m_party_guid = party_guid;
}
protected override string onMakeKey() => $"inviteparty:sendlist:{m_party_guid}";
public override string toBasicString() => $"PartyInvitePartySendCache: In:PartyGuid:{m_party_guid}, Out:{m_party_invite_party_send_cache_nullable?.toBasicString()}";
public async Task<Result> keepInvitePartySendCache()
{
var result = new Result();
string err_msg;
if (m_party_invite_party_send_cache_nullable == null || m_party_invite_party_send_cache_nullable.PartyInvitePartySends.Count <= 0) return result;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.KeyExpireAsync(getKey(), TimeSpan.FromMilliseconds(Constant.KEEP_PARTY_TIME));
if (false == redis_value)
{
err_msg = $"Failed to set expire PartyInvitePartySendCache in Redis !!! : Key:{getKey()} - {nameof(keepInvitePartySendCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyInvitePartySendCacheWriteFailed, err_msg);
Log.getLogger().error(err_msg);
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to set expire PartyInvitePartySendCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(keepInvitePartySendCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public PartyInvitePartySendCache? getPartyInvitePartySendCache() => m_party_invite_party_send_cache_nullable;
public async Task<Result> fetchInvitePartySendCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var delete_time = DateTime.UtcNow.AddMilliseconds(-1 * Constant.KEEP_INVITEPARTY_TIME);
var curr_party_invite_party_sends = new Dictionary<string, DateTime>();
var delete_list = new List<string>();
var redis_value = await database.HashGetAllAsync(getKey(), CommandFlags.PreferReplica);
foreach (var send_value in redis_value)
{
var send_time = send_value.Value.ToString().toUtcTime();
if (send_time < delete_time)
{
delete_list.Add(send_value.Name.ToString());
continue;
}
curr_party_invite_party_sends.Add(send_value.Name.ToString(), send_time);
}
m_party_invite_party_send_cache_nullable ??= new PartyInvitePartySendCache();
m_party_invite_party_send_cache_nullable.PartyInvitePartySends.Clear();
foreach (var send in curr_party_invite_party_sends)
{
m_party_invite_party_send_cache_nullable.PartyInvitePartySends.Add(send.Key, send.Value);
}
result = await deleteInvitePartySendCache(delete_list);
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyInvitePartySendCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(fetchInvitePartySendCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<List<string>?> organizeInvitePartySendCache()
{
if (null == m_party_invite_party_send_cache_nullable) return null;
var delete_time = DateTime.UtcNow.AddMilliseconds(-1 * Constant.KEEP_INVITEPARTY_TIME);
var delete_sends = (from send in m_party_invite_party_send_cache_nullable.PartyInvitePartySends where send.Value < delete_time select send.Key).ToList();
_ = await deleteInvitePartySendCache(delete_sends);
return delete_sends;
}
public async Task<Result> addInvitePartySendCache(IReadOnlyList<USER_GUID> add_user_guids)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
foreach (var add_user in add_user_guids)
{
var invite_time = DateTime.UtcNow.ToString(CultureInfo.InvariantCulture);
_ = await database.HashSetAsync(getKey(), add_user, invite_time);
}
result = await keepInvitePartySendCache();
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to add party invite party send from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(addInvitePartySendCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deleteAllInvitePartySendCache()
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
m_party_invite_party_send_cache_nullable = null;
_ = await database.KeyDeleteAsync(getKey(), CommandFlags.FireAndForget);
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to delete party invite party send from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(deleteAllInvitePartySendCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deleteInvitePartySendCache(IReadOnlyList<string> delete_user_guids)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var delete_values = new List<RedisValue>(delete_user_guids.Select(x => new RedisValue(x)));
_ = await database.HashDeleteAsync(getKey(), delete_values.ToArray(), CommandFlags.PreferReplica);
foreach (var delete in delete_user_guids)
{
m_party_invite_party_send_cache_nullable?.PartyInvitePartySends.Remove(delete);
}
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Exception !!!, Failed to delete party invite party send from Redis !!! : : errorCode:{error_code}, exception:{e} - {nameof(deleteInvitePartySendCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
}

View File

@@ -0,0 +1,302 @@
using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
namespace ServerCommon;
public class SummonInfo
{
// 소환 여부 판단 ( true - 소환 중 )
public bool IsAlreadySummon { get; set; }
// 소환 Server
public string? SummonServer { get; set; }
// 소환 Pos
public Pos? SummonPos { get; set; }
public SummonInfo clone()
{
var clone = new SummonInfo
{
IsAlreadySummon = IsAlreadySummon,
SummonServer = SummonServer,
SummonPos = SummonPos
};
return clone;
}
public void clear()
{
IsAlreadySummon = false;
SummonServer = null;
SummonPos = null;
}
}
public class PartyMemberInfo
{
// 유저 Guid
public string UserGuid { get; set; } = string.Empty;
// 유저 nickname ( 파티 도중 닉네임 변경시 처리 불가
public string Nickname { get; set; } = string.Empty;
// 마커 Id - 유저 표시용
public int MarkId { get; set; } = 0;
// Party Join Time
public Timestamp JoinTime { get; set; } = new();
// 소환 정보
public SummonInfo Summon { get; set; } = new();
// 유저 위치 정보
public UserLocationInfo LocationInfo { get; set; } = new();
public PartyMemberInfo clone()
{
var clone = new PartyMemberInfo
{
UserGuid = UserGuid,
Nickname = Nickname,
MarkId = MarkId,
JoinTime = JoinTime,
Summon = Summon.clone(),
LocationInfo = LocationInfo
};
return clone;
}
}
public class PartyMemberCache : CacheBase
{
public Dictionary<string, PartyMemberInfo> PartyMembers { get; set; } = new();
public void upsertPartyMember(PartyMemberInfo user)
{
PartyMembers[user.UserGuid] = user;
}
public void deleteJoinMember(string user_guid) => PartyMembers.Remove(user_guid);
public string toBasicString()
{
return $"PartyCache: PartyMembers:{PartyMembers}";
}
}
public class PartyMemberCacheRequest : RedisRequestSharedBase
{
// in
private readonly string m_party_guid;
// out
private PartyMemberCache? m_party_member_cache_nullable { get; set; }
public PartyMemberCacheRequest(string party_guid, RedisConnector redisConnector) : base(party_guid, redisConnector)
{
m_party_guid = party_guid;
}
protected override string onMakeKey() => $"party:{m_party_guid}:members";
public override string toBasicString() => $"PartyMemberCache: In:PartyGuid:{m_party_guid}, Out:{m_party_member_cache_nullable?.toBasicString()}";
public PartyMemberCache? getPartyMemberCache() => m_party_member_cache_nullable;
public async Task<Result> keepPartyMemberCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.KeyExpireAsync(getKey(), TimeSpan.FromMilliseconds(Constant.KEEP_PARTY_TIME));
if (false == redis_value)
{
err_msg = $"Failed to set expire PartyMemberCache in Redis !!! : Key:{getKey()} - {nameof(keepPartyMemberCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyMemberCacheWriteFailed, err_msg);
Log.getLogger().error(err_msg);
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to set expire PartyMemberCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(keepPartyMemberCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> fetchPartyMemberCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var curr_party_members = new List<PartyMemberInfo>();
var redis_value = await database.HashValuesAsync(getKey(), CommandFlags.PreferReplica);
foreach (var member_value in redis_value)
{
var member = JsonConvert.DeserializeObject<PartyMemberInfo>(member_value.ToString());
if (null == member)
{
Log.getLogger().error($"JsonConvert.DeserializeObject<PartyMemberInfo> Error {member_value.ToString()}");
continue;
}
curr_party_members.Add(member);
}
m_party_member_cache_nullable ??= new PartyMemberCache();
m_party_member_cache_nullable.PartyMembers.Clear();
foreach (var member in curr_party_members)
{
m_party_member_cache_nullable.PartyMembers.Add(member.UserGuid, member);
}
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyMemberCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(fetchPartyMemberCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> changeJoinMember(PartyMemberInfo user)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var input_user_json = JsonConvert.SerializeObject(user);
await database.HashSetAsync(getKey(), user.UserGuid, input_user_json);
m_party_member_cache_nullable ??= new PartyMemberCache();
m_party_member_cache_nullable.upsertPartyMember(user);
result = await keepPartyMemberCache();
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyMemberCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(fetchPartyMemberCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deletePartyMemberCache()
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
m_party_member_cache_nullable = null;
_ = await database.KeyDeleteAsync(getKey(), CommandFlags.FireAndForget);
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to delete PartyMemberCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(deletePartyMemberCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deleteJoinMember(string delete_user)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
if (false == await database.HashDeleteAsync(getKey(), delete_user))
{
err_msg = $"Fail to delete join member !!! : {nameof(changeJoinMember)} - user_guid[{delete_user}]";
result.setFail(ServerErrorCode.RedisSetsWriteFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
if (null == m_party_member_cache_nullable)
{
return result;
}
m_party_member_cache_nullable.deleteJoinMember(delete_user);
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to delete PartyMemberCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(deleteJoinMember)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
}

View File

@@ -0,0 +1,233 @@
using StackExchange.Redis;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace ServerCommon;
public class PartyServerCache : CacheBase
{
public List<string> PartyServers { get; set; } = new();
public string toBasicString()
{
return $"PartyCache: PartyServers:{PartyServers}";
}
}
public class PartyServerCacheRequest : RedisRequestSharedBase
{
// in
private readonly string m_party_guid;
// out
private PartyServerCache? m_party_server_cache_nullable { get; set; }
public PartyServerCacheRequest(string party_guid, RedisConnector redisConnector) : base(party_guid, redisConnector)
{
m_party_guid = party_guid;
}
protected override string onMakeKey() => $"party:{m_party_guid}:servers";
public override string toBasicString() => $"LoginCache: In:PartyGuid:{m_party_guid}, Out:{m_party_server_cache_nullable?.toBasicString()}";
public PartyServerCache? getPartyServerCache() => m_party_server_cache_nullable;
public async Task<Result> keepPartyServerCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.KeyExpireAsync(getKey(), TimeSpan.FromMilliseconds(Constant.KEEP_PARTY_TIME));
if (false == redis_value)
{
err_msg = $"Failed to set expire PartyServerCache in Redis !!! : Key:{getKey()} - {nameof(keepPartyServerCache)}";
result.setFail(ServerErrorCode.RedisGlobalPartyServerCacheWriteFailed, err_msg);
Log.getLogger().error(err_msg);
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to set expire PartyServerCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(keepPartyServerCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> fetchPartyServerCache()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.ListRangeAsync(getKey());
m_party_server_cache_nullable ??= new PartyServerCache();
m_party_server_cache_nullable.PartyServers.Clear();
m_party_server_cache_nullable.PartyServers.AddRange(redis_value.Select(x => x.ToString()));
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get PartyServerCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(fetchPartyServerCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deletePartyServerCache(string delete_server)
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
m_party_server_cache_nullable = null;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
_ = await database.ListRemoveAsync(getKey(), delete_server, 1, CommandFlags.FireAndForget);
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to delete party server from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(deleteAllPartyServerCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> deleteAllPartyServerCache()
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
m_party_server_cache_nullable = null;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
_ = await database.KeyDeleteAsync(getKey(), CommandFlags.FireAndForget);
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to delete party server from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(deleteAllPartyServerCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> addPartyServerCache(string server_name)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
if (!await checkPartyServerCache(server_name))
{
var redis_value = await database.ListRightPushAsync(getKey(), new RedisValue(server_name));
}
m_party_server_cache_nullable ??= new PartyServerCache();
if (!m_party_server_cache_nullable.PartyServers.Contains(server_name))
{
m_party_server_cache_nullable.PartyServers.Add(server_name);
}
result = await keepPartyServerCache();
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to add party server from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(addPartyServerCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
private async Task<bool> checkPartyServerCache(string server_name)
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.ListPositionAsync(getKey(), new RedisValue(server_name));
if (redis_value >= 0) return true;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to add party server from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(addPartyServerCache)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return false;
}
}

View File

@@ -0,0 +1,122 @@
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Newtonsoft.Json;
using ServerCore; using ServerBase;
using StackExchange.Redis;
using System.Numerics;
namespace ServerCommon.Cache;
public class QuestNotifyCache : CacheBase
{
[JsonProperty("quest_id")]
public UInt32 m_quest_id { get; set; } = 0;
[JsonProperty("quest_revision")]
public UInt32 m_quest_revision { get; set; } = 0;
public QuestNotifyCache(UInt32 questId, UInt32 questRevision)
{
m_quest_id = questId;
m_quest_revision = questRevision;
}
}
public class QuestNotifyCacheRequest : RedisRequestPrivateBase
{
public string m_user_guid { get; set; } = string.Empty;
public UInt32 m_quest_id { get; set; } = 0;
public UInt32 m_quest_revision { get; set; } = 0;
public QuestNotifyCacheRequest(UserBase owner, string userGuid, UInt32 quest_id, UInt32 quest_revision, RedisConnector redisConnector) : base(owner, redisConnector)
{
m_user_guid = userGuid;
m_quest_id = quest_id;
m_quest_revision = quest_revision;
}
public QuestNotifyCacheRequest(UserBase owner, string userGuid, RedisConnector redisConnector) : base(owner, redisConnector)
{
m_user_guid = userGuid;
}
protected override string onMakeKey()
{
return $"questnotify:{m_user_guid}";
}
public override string toBasicString()
{
return $"QuestNotifyCache: In:m_user_guid:{m_user_guid}";
}
private string makeFieldKey()
{
return $"{m_quest_id}:{m_quest_revision}";
}
private string makeFieldKey(UInt32 questId, UInt32 questRevision)
{
return $"{questId}:{questRevision}";
}
public async Task<Result> addQuestNotify()
{
var result = new Result();
var database = getDatabase();
QuestNotifyCache cache = new QuestNotifyCache(m_quest_id, m_quest_revision);
//일단 예외처리는 하지 않는다.
await database.HashSetAsync(onMakeKey(), makeFieldKey(), JsonConvert.SerializeObject(cache));
await database.KeyExpireAsync(onMakeKey(), TimeSpan.FromMilliseconds(Constant.QUEST_NOTIFY_CHECK_TIME));
return result;
}
public async Task<List<QuestNotifyCache>> getQuestNotifyAll()
{
var database = getDatabase();
List<QuestNotifyCache> notify_caches = new();
var hashes = await database.HashGetAllAsync(onMakeKey(), CommandFlags.PreferReplica);
foreach (var entry in hashes)
{
try
{
var value_string = entry.Value.ToString();
var notify_cache = JsonConvert.DeserializeObject<QuestNotifyCache>(value_string);
if (notify_cache == null)
{
string err_msg = $"Failed to get FriendCache from Redis !!! : : value_string:{value_string} - {getOwner().toBasicString()}";
Log.getLogger().error(err_msg);
continue;
}
notify_caches.Add(notify_cache);
}
catch (Exception e)
{
Log.getLogger().error($"var value_string = entry.Value.ToString(); Failed. Exception message : {e.Message}");
continue;
}
}
return notify_caches;
}
public async Task<Result> deleteQuestNotify(UInt32 questId, UInt32 questRevision)
{
var result = new Result();
var database = getDatabase();
await database.HashDeleteAsync(onMakeKey(), makeFieldKey(questId, questRevision));
return result;
}
}

View File

@@ -0,0 +1,123 @@
using StackExchange.Redis;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace ServerCommon;
public class RentalOccupyCacheRequest : RedisRequestSharedBase
{
// In
private string m_shared_key;
// Out
private string m_occupied_user_guid = string.Empty;
public RentalOccupyCacheRequest(string sharedKey, RedisConnector redisConnector)
: base(sharedKey, redisConnector)
{
m_shared_key = sharedKey;
}
public override string toBasicString()
{
return $"RentalOccupy: In:{m_shared_key}, Out:{m_occupied_user_guid}";
}
protected override string onMakeKey()
{
return $"RentalOccupy:{m_shared_key}";
}
public static string makeShareKey(int landId, int buildingId, int floor)
{
var shared_key = string.Empty;
if (landId > 0)
shared_key = $"{landId}";
else
return shared_key;
if (buildingId > 0)
shared_key = $"{shared_key}:{buildingId}";
else
return shared_key;
if (floor > 0)
shared_key = $"{shared_key}:{floor}";
return shared_key;
}
public string getOccupiedUserGuid() => m_occupied_user_guid;
public async Task<Result> tryOccupyRental(string userGuid)
{
var result = new Result();
var err_msg = string.Empty;
try
{
result = await onPrepareRequest();
if (result.isFail())
{
err_msg = $"Failed to onPrepareRequest() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
var database = getDatabase();
if (!await database.StringSetAsync(getKey(), userGuid, TimeSpan.FromMinutes(1), When.NotExists))
{
err_msg = $"Failed to StringSetAsync to Redis !!! : redisKey:{getKey()}";
result.setFail(ServerErrorCode.RedisLocationCacheSetFailed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
catch (Exception e)
{
err_msg = $"Failed to tryOccupyRental in Redis !!! : message{e}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
}
public async Task<Result> deleteRentalOccupy()
{
var result = new Result();
var err_msg = string.Empty;
try
{
var database = getDatabase();
_ = await database.KeyDeleteAsync(getKey());
return result;
}
catch (Exception e)
{
err_msg = $"Failed to delete key in Redis !!! : message{e}";
result.setFail(ServerErrorCode.TryCatchException, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
}
}

View File

@@ -0,0 +1,83 @@
using StackExchange.Redis;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace ServerCommon;
public class UgcNpcRankManageCacheRequest : RedisRequestSharedBase
{
private const int DefaultManageExpireMinute = 1;
// in
// out
public UgcNpcRankManageCacheRequest(RedisConnector redisConnector) : base("UgcNpcRankManage", redisConnector)
{
}
protected override string onMakeKey() => "rank:manage";
private string getLastRunningKey() => $"{onMakeKey()}:last";
public override string toBasicString() => "UgcNpcRankManageCacheRequest";
public async Task<bool> isExistKey(string key)
{
try
{
var result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
var redis_value = await database.KeyExistsAsync(key);
return redis_value;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get isExistKey from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(isExistKey)}";
Log.getLogger().error(err_msg);
}
return false;
}
public async Task<bool> setStartUgcNpcRankManage()
{
var result = new Result();
try
{
result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
var redis_value = await database.StringSetAsync(getKey(), DateTimeHelper.Current.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(DefaultManageExpireMinute), When.NotExists);
if (false == redis_value) return false;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get UgcNpcRankManageCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
return false;
}
return true;
}
}

View File

@@ -0,0 +1,261 @@
using Renci.SshNet.Security;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
namespace ServerCommon;
public class UgcNpcTotalRankCache : CacheBase
{
public long TotalRankCount { get; set; }
public List<(string guid, long score)> Ranks { get; set; } = new();
public string toBasicString()
{
return $"UgcNpcTotalRankCache - total:{TotalRankCount} / list: {Ranks}";
}
}
public class UgcNpcTotalRankCacheRequest : RedisRequestSharedBase
{
// in
private readonly string m_rank_type;
private DateTime m_date_time { get; set; }
// out
private UgcNpcTotalRankCache? m_total_rank_cache_nullable { get; set; }
public UgcNpcTotalRankCacheRequest(UgcNpcRankType type, RedisConnector redisConnector) : base(type.ToString(), redisConnector)
{
m_rank_type = type.ToString();
m_date_time = DateTimeHelper.MinTime;
}
public UgcNpcTotalRankCacheRequest(UgcNpcRankType type, DateTime time, RedisConnector redisConnector) : base(
type.ToString(), redisConnector)
{
m_rank_type = type.ToString();
m_date_time = time;
}
protected override string onMakeKey()
{
if (m_date_time == DateTimeHelper.MinTime) return $"rank:{m_rank_type}:total";
var date = m_date_time.ToString("yyyy-MM-dd");
return $"rank:{m_rank_type}:total:{date}";
}
public override string toBasicString() =>
$"UgcNpcTotalRankCache: in[{m_rank_type}], out[{m_total_rank_cache_nullable?.toBasicString()}]";
public UgcNpcTotalRankCache? getTotalCache() => m_total_rank_cache_nullable;
public async Task<bool> isExistKey()
{
try
{
var result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
var redis_value = await database.KeyExistsAsync(onMakeKey());
return redis_value;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get isExistKey from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(isExistKey)}";
Log.getLogger().error(err_msg);
}
return false;
}
public async Task<Result> getRanks(int pageNum, int size)
{
var result = new Result();
string err_msg;
var start = (long)pageNum * size;
var end = start + size;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
m_total_rank_cache_nullable = new();
var rank_key = onMakeKey();
if (string.IsNullOrEmpty(rank_key))
{
m_total_rank_cache_nullable.TotalRankCount = 0;
return result;
}
var total_count = await database.SortedSetLengthAsync(rank_key);
if (total_count < start)
{
err_msg = $"Failed to get UgcNpcTotalRankCache from Redis !!! : out of range rank [{total_count}] - {pageNum} / {size}";
result.setFail(ServerErrorCode.UgcNpcRankOutOfRange, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (total_count < end) end = total_count;
var redis_value = await database.SortedSetRangeByRankWithScoresAsync(getKey(), start, end, Order.Descending);
m_total_rank_cache_nullable.TotalRankCount = total_count;
foreach (var value in redis_value)
{
m_total_rank_cache_nullable.Ranks.Add((value.Element.ToString(), (long)value.Score));
}
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get UgcNpcTotalRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(getRanks)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<Result> initRankScore(Dictionary<string, long> ranks)
{
var result = new Result();
string err_msg;
var redis_values = new SortedSetEntry[ranks.Count];
var idx = 0;
foreach (var rank in ranks)
{
var value = new SortedSetEntry(rank.Key, rank.Value);
redis_values[idx] = value;
idx++;
}
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
var transaction = database.CreateTransaction();
transaction.AddCondition(Condition.KeyNotExists(getKey()));
_ = transaction.SortedSetAddAsync(getKey(), redis_values, When.Always);
var is_success = await transaction.ExecuteAsync();
if (false == is_success)
{
err_msg = $"failed to sorted set!! : initRankScore - count[{ranks.Count}]";
result.setFail(ServerErrorCode.RedisSortedSetsWriteFailed, err_msg);
Log.getLogger().error(result.toBasicString());
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get UgcNpcTotalRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(setRankScore)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> initRankScore(string rankKey, long deltaCount)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
var redis_value = await database.SortedSetAddAsync(getKey(), rankKey, deltaCount, When.Always);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get UgcNpcTotalRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(setRankScore)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> setTtl()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
var expire_time = new TimeSpan(MetaHelper.GameConfigMeta.NpcRankingRetentionPeriod, 0,0);
var redis_value = await database.KeyExpireAsync(getKey(), expire_time);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get UgcNpcTotalRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(setRankScore)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> setRankScore(string rankKey, long deltaCount)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
var redis_value = await database.SortedSetAddAsync(getKey(), rankKey, deltaCount, When.NotExists);
if (false == redis_value)
{
_ = await database.SortedSetIncrementAsync(getKey(), rankKey, deltaCount);
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get UgcNpcTotalRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(setRankScore)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
}

View File

@@ -0,0 +1,294 @@
using Google.Protobuf.WellKnownTypes;
using StackExchange.Redis;
using ServerCore;
using ServerBase;
namespace ServerCommon;
public class UgcNpcTrendRankCache : CacheBase
{
public long TrendRankCount { get; set; }
public List<(string guid, long score)> Ranks { get; set; } = new();
public string toBasicString()
{
return $"UgcNpcTrendRankCache - trend:{TrendRankCount} / list: {Ranks}";
}
}
public class UgcNpcTrendRankCacheRequest : RedisRequestSharedBase
{
// in
private readonly string m_rank_type;
private DateTime m_date_time { get; set; }
// out
private UgcNpcTrendRankCache? m_trend_rank_cache_nullable { get; set; }
public UgcNpcTrendRankCacheRequest(UgcNpcRankType type, RedisConnector redisConnector) : base(type.ToString(),
redisConnector)
{
m_rank_type = type.ToString();
m_date_time = DateTimeHelper.MinTime;
}
public UgcNpcTrendRankCacheRequest(UgcNpcRankType type, DateTime time, RedisConnector redisConnector) : base(
type.ToString(),
redisConnector)
{
m_rank_type = type.ToString();
m_date_time = time;
}
protected override string onMakeKey()
{
if (m_date_time == DateTimeHelper.MinTime) return $"rank:{m_rank_type}:trend";
var date = m_date_time.ToString("yyyy-MM-dd");
return $"rank:{m_rank_type}:trend:{date}";
}
public override string toBasicString() =>
$"UgcNpcTrendRankCache: in[{m_rank_type}], out[{m_trend_rank_cache_nullable?.toBasicString()}]";
public UgcNpcTrendRankCache? getTrendRankCache() => m_trend_rank_cache_nullable;
public async Task<bool> isExistKey()
{
try
{
var result = await onPrepareRequest();
if (result.isFail()) return false;
var database = getDatabase();
ArgumentNullException.ThrowIfNull(database);
var redis_value = await database.KeyExistsAsync(onMakeKey());
return redis_value;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
var err_msg = $"Failed to get isExistKey from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(isExistKey)}";
Log.getLogger().error(err_msg);
}
return false;
}
public async Task<Result> getRanks(int pageNum, int size)
{
var result = new Result();
string err_msg;
var start = (long)pageNum * size;
var end = start + size;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
m_trend_rank_cache_nullable = new();
var rank_trend_key = onMakeKey();
if (string.IsNullOrEmpty(rank_trend_key))
{
m_trend_rank_cache_nullable.TrendRankCount = 0;
return result;
}
var total_count = await database.SortedSetLengthAsync(rank_trend_key);
if (total_count < start)
{
err_msg =
$"Failed to get UgcNpcTrendRankCache from Redis !!! : out of range rank [{total_count}] - {pageNum} / {size}";
result.setFail(ServerErrorCode.UgcNpcRankOutOfRange, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (total_count < end) end = total_count;
var redis_value =
await database.SortedSetRangeByRankWithScoresAsync(getKey(), start, end, Order.Descending);
m_trend_rank_cache_nullable.TrendRankCount = total_count;
foreach (var value in redis_value)
{
m_trend_rank_cache_nullable.Ranks.Add((value.Element.ToString(), (long)value.Score));
}
return result;
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg =
$"Failed to get UgcNpcTrendRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(getRanks)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(result.toBasicString());
}
return result;
}
public async Task<Result> initRankScore(Dictionary<string, long> ranks)
{
var result = new Result();
string err_msg;
var redis_values = new SortedSetEntry[ranks.Count];
var idx = 0;
foreach (var rank in ranks)
{
var value = new SortedSetEntry(rank.Key, rank.Value);
redis_values[idx] = value;
idx++;
}
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
var transaction = database.CreateTransaction();
transaction.AddCondition(Condition.KeyNotExists(getKey()));
_ = transaction.SortedSetAddAsync(getKey(), redis_values, When.Always);
var is_success = await transaction.ExecuteAsync();
if (false == is_success)
{
err_msg = $"failed to sorted set!! : initRankScore - count[{ranks.Count}]";
result.setFail(ServerErrorCode.RedisSortedSetsWriteFailed, err_msg);
Log.getLogger().error(result.toBasicString());
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get UgcNpcTotalRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(setRankScore)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> initRankScore(string rankKey, long deltaCount)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
var redis_value = await database.SortedSetAddAsync(getKey(), rankKey, deltaCount, When.Always);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get UgcNpcTrendRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(setRankScore)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> setTtl()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
var expire_time = new TimeSpan(MetaHelper.GameConfigMeta.NpcRankingRetentionPeriod, 0,0);
var redis_value = await database.KeyExpireAsync(getKey(), expire_time);
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg = $"Failed to get UgcNpcTotalRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(setRankScore)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> setRankScore(string rankKey, long deltaCount)
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
var redis_value = await database.SortedSetAddAsync(getKey(), rankKey, deltaCount, When.NotExists);
if (false == redis_value)
{
_ = await database.SortedSetIncrementAsync(getKey(), rankKey, deltaCount);
}
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg =
$"Failed to get UgcNpcTrendRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(setRankScore)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> resetRanks()
{
var result = new Result();
string err_msg;
try
{
result = await onPrepareRequest();
if (result.isFail()) return result;
var database = getDatabase();
_ = await database.KeyDeleteAsync(getKey());
}
catch (Exception e)
{
var error_code = ServerErrorCode.TryCatchException;
err_msg =
$"Failed to get UgcNpcTrendRankCache from Redis !!! : : errorCode{error_code}, errMsg:{e.Message} - {nameof(setRankScore)}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
}
return result;
}
}