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 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 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 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 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 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 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 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 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?> getCaliumForUserPerDailyCountAsync(int day) { var result = new Result(); var list = new Dictionary(); 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 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 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; } }