602 lines
27 KiB
C#
602 lines
27 KiB
C#
using Google.Protobuf;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
using ServerCommon.BusinessLogDomain;
|
|
using MetaAssets;
|
|
|
|
|
|
namespace GameServer;
|
|
|
|
public class CaliumStorageAction : EntityActionBase
|
|
{
|
|
private readonly CaliumStorageCacheRequest m_cache_request;
|
|
private int m_repeat_count { get; set; }
|
|
|
|
public CaliumStorageAction(CaliumStorageEntity owner) : base(owner)
|
|
{
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
var redis = server_logic.getRedisConnector();
|
|
|
|
m_cache_request = new CaliumStorageCacheRequest(redis);
|
|
}
|
|
|
|
public override async Task<Result> onInit()
|
|
{
|
|
// 1. fill up 시간 체크
|
|
var pivot_date = CaliumStorageHelper.CurrentPivotTimeDate();
|
|
var task_date = pivot_date;
|
|
|
|
// 2. repeat count
|
|
m_repeat_count = 24 / MetaHelper.GameConfigMeta.CaliumConverterCycleTime;
|
|
|
|
// 3. DailyTimeEventManager 등록
|
|
string task_name;
|
|
|
|
for (var repeat = 0; repeat < m_repeat_count; repeat++)
|
|
{
|
|
var is_first_run = repeat != 0;
|
|
|
|
task_name = "CaliumConverterManage";
|
|
task_name = $"{task_name}_{repeat}";
|
|
DailyTimeEventManager.Instance.tryAddTask(task_name, task_date, onFillUpDailyCalium, is_first_run);
|
|
|
|
task_date = task_date.AddHours(MetaHelper.GameConfigMeta.CaliumConverterCycleTime);
|
|
}
|
|
|
|
// 4. 컨버터 동기화 체크 Manager 등록
|
|
task_name = "CaliumConverterSyncManage";
|
|
DailyTimeEventManager.Instance.tryAddTask(task_name, task_date.AddHours(1), onSyncConverterCalium);
|
|
|
|
return await Task.FromResult(new Result());
|
|
}
|
|
|
|
public override void onClear() {}
|
|
|
|
public async Task<Result> initStorageAttribute()
|
|
{
|
|
var owner = getOwner() as CaliumStorageEntity;
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!");
|
|
|
|
// 0. Web3 Connection 체크
|
|
var web3_action = getOwner().getEntityAction<CaliumWeb3Action>();
|
|
NullReferenceCheckHelper.throwIfNull(web3_action, () => $"web3_action is null !!! - {owner.toBasicString()}");
|
|
var result = await web3_action.checkWeb3Connection();
|
|
if (result.isFail()) return result;
|
|
|
|
// 1. 데이터 로딩
|
|
result = await loadStorageAttribute();
|
|
if (result.isSuccess()) return result;
|
|
|
|
// 2. Storage Doc 을 찾지 못하는 에러가 아닌 경우 에러 처리
|
|
if (result.ErrorCode != ServerErrorCode.DynamoDbQueryNoMatchAttribute) return result;
|
|
|
|
// 3. 신규 데이터 저장
|
|
var dynamodb_client = GameServerApp.getServerLogic().getDynamoDbClient();
|
|
|
|
var doc = new CaliumStorageDoc();
|
|
result = await dynamodb_client.simpleInsertDocumentWithDocType<CaliumStorageDoc>(doc);
|
|
|
|
return result;
|
|
}
|
|
|
|
public double getTotalCalium(CaliumStorageType storageType)
|
|
{
|
|
var attribute = getOwner().getEntityAttribute<CaliumStorageAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(attribute, () => $"calium_storage_attribute is null !!! - {getOwner().toBasicString()}");
|
|
|
|
return storageType switch
|
|
{
|
|
CaliumStorageType.Converter => attribute.ConverterTotalCalium,
|
|
CaliumStorageType.Operator => attribute.OperatorTotalCalium,
|
|
_ => -1
|
|
};
|
|
}
|
|
|
|
public async Task<CaliumStorageAttribute> getCaliumStorageInfo()
|
|
{
|
|
await checkNewCaliumStoragePivotTime();
|
|
|
|
var attribute = getOwner().getEntityAttribute<CaliumStorageAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(attribute, () => $"calium_storage_attribute is null !!! - {getOwner().toBasicString()}");
|
|
|
|
return attribute;
|
|
}
|
|
|
|
public async Task<double> getCaliumConverterEfficiency()
|
|
{
|
|
await checkNewCaliumStoragePivotTime();
|
|
|
|
var attribute = getOwner().getEntityAttribute<CaliumStorageAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(attribute, () => $"calium_storage_attribute is null !!! - {getOwner().toBasicString()}");
|
|
|
|
return attribute.DailyConvertRate;
|
|
}
|
|
|
|
public async Task<Result> loadStorageAttribute()
|
|
{
|
|
var dynamodb_client = GameServerApp.getServerLogic().getDynamoDbClient();
|
|
|
|
var owner = getOwner() as CaliumStorageEntity;
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!");
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>(owner, LogActionType.ConvertCalium, dynamodb_client);
|
|
batch.addQuery(new DBQCaliumStorageLoad());
|
|
|
|
var result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
return result;
|
|
}
|
|
|
|
public void sendChangeStorageInfo()
|
|
{
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
var rabbit_mq = server_logic.getRabbitMqConnector() as RabbitMQ4Game;;
|
|
NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!! - {getOwner().toBasicString()}");
|
|
|
|
var server_message = new ServerMessage();
|
|
server_message.NtfChangeCaliumStorageInfo = new();
|
|
|
|
rabbit_mq.sendMessageToExchangeAllGame(server_message);
|
|
}
|
|
|
|
public async Task<Result> enableCaliumStorage()
|
|
{
|
|
await checkNewCaliumStoragePivotTime();
|
|
var result = new Result();
|
|
|
|
var storage_attribute = getOwner().getEntityAttribute<CaliumStorageAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(storage_attribute, () => $"storage_attribute is null !!! - {getOwner().toBasicString()}");
|
|
|
|
if (storage_attribute.DailyPivotDate < CaliumStorageHelper.CurrentPivotTimeDate())
|
|
{
|
|
var err_msg = $"rollup date is old data !!! : current[{storage_attribute.DailyPivotDate}] / to[{CaliumStorageHelper.CurrentPivotTimeDate()}]";
|
|
result.setFail(ServerErrorCode.FailToGetEchoSystemRollUp, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<bool> checkRetryCaliumEchoSystem()
|
|
{
|
|
return await m_cache_request.checkRetryKey();
|
|
}
|
|
|
|
private Result initializeStorage(CaliumStorageAttrib attrib, RollUpData? rollUp)
|
|
{
|
|
var result = new Result();
|
|
|
|
if (null == rollUp)
|
|
{
|
|
var err_msg = "fail to initialize calium storage : roll up data is null!!";
|
|
result.setFail(ServerErrorCode.GetFailEchoSystemResponse, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
return result;
|
|
}
|
|
|
|
attrib.DailyEpoch = rollUp.m_epoch - 1;
|
|
attrib.DailyPivotDate = CaliumStorageHelper.CurrentPivotTimeDate().AddDays(-1);
|
|
|
|
var calium = CaliumStorageHelper.SubTractDoubleByLong(rollUp.m_stack_converter_volume, rollUp.m_convertor_volume);
|
|
attrib.ConverterStorage.ConverterCumulativeCalium = calium;
|
|
attrib.ConverterStorage.DailyConvertRate = rollUp.m_daily_converter_rate;
|
|
attrib.ConverterStorage.TotalCalium = calium;
|
|
attrib.ConverterStorage.LastFillUpDate = CaliumStorageHelper.CurrentPivotTimeDate().AddHours(-1 * MetaHelper.GameConfigMeta.CaliumConverterCycleTime);
|
|
attrib.ConverterStorage.DailyFillUpStandardCalium = rollUp.m_convertor_volume;
|
|
|
|
attrib.ExchangerStorage.DailyInflationRate = rollUp.m_daily_inflation_rate;
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<Result> changeCaliumConverterTotal(double delta)
|
|
{
|
|
var result = new Result();
|
|
if (delta == 0) return result;
|
|
|
|
var owner = getOwner() as CaliumStorageEntity;
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!");
|
|
|
|
// 1. delta 값 변경
|
|
var item_request_batch = new QueryBatchEx<QueryRunnerWithItemRequest>(owner, LogActionType.ConvertCalium, GameServerApp.getServerLogic().getDynamoDbClient(), true);
|
|
item_request_batch.addQuery(new DBQStorageCaliumUpdate(CaliumStorageType.Converter, delta, true));
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(item_request_batch);
|
|
if (result.isFail()) return result;
|
|
|
|
// 2. calium storage attribute 갱신
|
|
_ = loadStorageAttribute();
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<CaliumStorageDoc?> getCaliumStorageDoc()
|
|
{
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
var dynamodb_client = server_logic.getDynamoDbClient();
|
|
|
|
var query_config = dynamodb_client.makeQueryConfigForReadByPKOnly(CaliumStorageDoc.pk);
|
|
var (result, found_doc) = await dynamodb_client.simpleQueryDocTypeWithQueryOperationConfig<CaliumStorageDoc>(query_config);
|
|
if (result.isFail() || null == found_doc) return null;
|
|
|
|
return found_doc;
|
|
}
|
|
|
|
private async Task checkNewCaliumStoragePivotTime()
|
|
{
|
|
var owner = getOwner() as CaliumStorageEntity;
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!");
|
|
|
|
var attribute = getOwner().getEntityAttribute<CaliumStorageAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(attribute, () => $"calium_storage_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
// 1. calium storage daily data 갱신 날짜 체크
|
|
if (attribute.DailyPivotDate >= CaliumStorageHelper.CurrentPivotTimeDate()) return;
|
|
|
|
// 2. calium storage 데이터 수정
|
|
_ = await loadStorageAttribute();
|
|
}
|
|
|
|
public async Task onFillUpDailyCalium()
|
|
{
|
|
NullReferenceCheckHelper.throwIfNull(m_cache_request, () => $"m_cache_request is null !!! - {getOwner().toBasicString()}");
|
|
|
|
// 1. 시작 조건 체크
|
|
var is_start = await m_cache_request.startCaliumConverterManage();
|
|
if (!is_start) return;
|
|
|
|
// 2. doc 데이터 로딩
|
|
var found_doc = await getCaliumStorageDoc();
|
|
NullReferenceCheckHelper.throwIfNull(found_doc, () => $"calium_storage_doc is null !!! - {getOwner().toBasicString()}");
|
|
|
|
var calium_storage_attrib = found_doc.getAttrib<CaliumStorageAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(calium_storage_attrib, () => $"calium_storage_attrib is null !!! - {getOwner().toBasicString()}");
|
|
|
|
// 3. Daily Calium Converter 정보 갱신 처리
|
|
var update = await updateDailyCaliumConverter(found_doc);
|
|
if (false == update.is_success) return;
|
|
|
|
// 4. 미 충전 횟수 체크
|
|
var check_fill_up = checkMissFillUpDailyCalium(calium_storage_attrib);
|
|
|
|
// 5. daily calium 충전
|
|
var fill_up_calium = await fillUpDailyCalium(calium_storage_attrib, check_fill_up.missFillUpCount, check_fill_up.lastFillUpDate);
|
|
if (fill_up_calium <= 0) return;
|
|
|
|
// 6. business log 기록
|
|
var calium_log_data = new CaliumConverterLogData();
|
|
calium_log_data.CurrentDailyCalium = 0;
|
|
calium_log_data.CurrentTotalCalium = getTotalCalium(CaliumStorageType.Converter);
|
|
calium_log_data.DeltaDailyCalium = 0;
|
|
calium_log_data.DeltaTotalCalium = CaliumStorageHelper.AddDoubleByLong(fill_up_calium, update.mis_pivot_calium);
|
|
calium_log_data.AmountDeltaType = AmountDeltaType.Acquire;
|
|
|
|
var calium_business_log = new CaliumBusinessLog(new LogActionEx(LogActionType.FillupCalium), calium_log_data);
|
|
|
|
var calium_converter = GameServerApp.getServerLogic().findGlobalEntity<CaliumStorageEntity>();
|
|
NullReferenceCheckHelper.throwIfNull(calium_converter, () => $"calium_converter is null !!!");
|
|
BusinessLogger.collectLog(calium_converter, calium_business_log);
|
|
}
|
|
|
|
private async Task onSyncConverterCalium()
|
|
{
|
|
// 실행 기본 딜레이 처리
|
|
await Task.Delay(10_000);
|
|
|
|
var owner = getOwner() as CaliumStorageEntity;
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!");
|
|
|
|
// 1. 시작 조건 체크
|
|
var is_start = await m_cache_request.startCaliumConverterManage(true);
|
|
if (!is_start) return;
|
|
|
|
// 2. doc 데이터 로딩
|
|
var found_doc = await getCaliumStorageDoc();
|
|
NullReferenceCheckHelper.throwIfNull(found_doc, () => $"calium_storage_doc is null !!! - {getOwner().toBasicString()}");
|
|
|
|
var calium_storage_attrib = found_doc.getAttrib<CaliumStorageAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(calium_storage_attrib, () => $"calium_storage_attrib is null !!! - {getOwner().toBasicString()}");
|
|
|
|
// 3. sync 시작 체크
|
|
var is_check = checkSyncEchoSystem(calium_storage_attrib);
|
|
if (is_check) return;
|
|
|
|
// 4. echoSystem 조회
|
|
var web3_action = getOwner().getEntityAction<CaliumWeb3Action>();
|
|
NullReferenceCheckHelper.throwIfNull(web3_action, () => $"web3_action is null !!! - {getOwner().toBasicString()}");
|
|
var (result, msg) = await web3_action.getConverterSyncDataAsync();
|
|
if (result.isFail())
|
|
{
|
|
var log = new CaliumEchoSystemFailLogData();
|
|
log.FailCode = msg?.m_code ?? string.Empty;
|
|
log.FailMessages = msg?.m_messages ?? new();
|
|
CaliumStorageHelper.writeFailEchoSystemLog(owner, log);
|
|
|
|
Log.getLogger().error($"fail to sync converter from echo system !!! : code[{log.FailCode}] message[{log.FailMessages}]");
|
|
return;
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(msg, () => $"web3 response is null !!! - {getOwner().toBasicString()}");
|
|
|
|
// 5. 동기화 체크 : 적용 회차
|
|
if (calium_storage_attrib.DailyEpoch != msg.m_sync?.m_epoch)
|
|
{
|
|
var log = new CaliumEchoSystemFailLogData();
|
|
log.FailCode = "caliverse_error";
|
|
log.FailMessages = new List<string> { $"failed to match epoch!! - current[{calium_storage_attrib.DailyEpoch}] / echoSystem[{msg.m_sync?.m_epoch}]" };
|
|
CaliumStorageHelper.writeFailEchoSystemLog(owner, log);
|
|
|
|
Log.getLogger().error($"fail to sync converter from echo system !!! : code[{log.FailCode}] message[{log.FailMessages}]");
|
|
return;
|
|
}
|
|
|
|
// 6. 동기화 체크 : 총 누적 량
|
|
if (false == CaliumStorageHelper.compareDoubleByLong(calium_storage_attrib.ConverterStorage.ConverterCumulativeCalium, msg.m_sync.m_stack_calium))
|
|
{
|
|
var log = new CaliumEchoSystemFailLogData();
|
|
log.FailCode = "caliverse_error";
|
|
log.FailMessages = new List<string> { $"failed to match converter calium!! - current[{calium_storage_attrib.ConverterStorage.ConverterCumulativeCalium}] / echoSystem[{msg.m_sync.m_stack_calium}]" };
|
|
CaliumStorageHelper.writeFailEchoSystemLog(owner, log);
|
|
|
|
Log.getLogger().error($"fail to sync converter from echo system !!! : code[{log.FailCode}] message[{log.FailMessages}]");
|
|
return;
|
|
}
|
|
|
|
// 7. Sync Date 수정
|
|
var item_request_batch = new QueryBatchEx<QueryRunnerWithItemRequest>(owner, LogActionType.CaliumSyncEchoSystem, GameServerApp.getServerLogic().getDynamoDbClient(), true);
|
|
item_request_batch.addQuery(new DBQStorageCaliumSyncDateUpdate(DateTimeHelper.Current));
|
|
|
|
_ = await QueryHelper.sendQueryAndBusinessLog(item_request_batch);
|
|
|
|
var success_log = $"success to sync converter from echo system !!! : epoch[{calium_storage_attrib.DailyEpoch}] converter_cumulative_calium[{calium_storage_attrib.ConverterStorage.ConverterCumulativeCalium}]";
|
|
Log.getLogger().info(success_log);
|
|
}
|
|
|
|
private bool checkSyncEchoSystem(CaliumStorageAttrib caliumStorageAttrib)
|
|
{
|
|
var current_pivot_date = CaliumStorageHelper.CurrentPivotTimeDate();
|
|
if (caliumStorageAttrib.DailyRollUpCheckDate < current_pivot_date.AddHours(1)) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
private async Task<(bool is_success, double mis_pivot_calium)> updateDailyCaliumConverter(CaliumStorageDoc originDoc)
|
|
{
|
|
var pivot_time = CaliumStorageHelper.CurrentPivotTimeDate();
|
|
|
|
var calium_storage_attrib = originDoc.getAttrib<CaliumStorageAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(calium_storage_attrib, () => $"calium_storage_attrib is null !!! - {getOwner().toBasicString()}");
|
|
|
|
// 1. Daily Calium Converter 갱신 조건 체크
|
|
if (calium_storage_attrib.DailyPivotDate >= pivot_time) return (true, 0);
|
|
|
|
// 2. Daily Calium Roll Up 체크
|
|
var (result, mis_pivot_calium) = await checkEchoSystemDailyCaliumAsync(calium_storage_attrib, pivot_time);
|
|
if (result.isFail())
|
|
{
|
|
// retry 처리
|
|
if (result.ErrorCode != ServerErrorCode.GetFailEchoSystemResponse)
|
|
{
|
|
await m_cache_request.setRetryKey();
|
|
}
|
|
|
|
return (false, mis_pivot_calium);
|
|
}
|
|
|
|
// 2. doc 갱신
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
var dynamodb_client = server_logic.getDynamoDbClient();
|
|
|
|
result = await dynamodb_client.simpleUpdateDocumentWithDocType<CaliumStorageDoc>(originDoc);
|
|
if (result.isFail())
|
|
{
|
|
var err_msg = $"failed to update daily calium converter info !!! - doc:{originDoc.toBasicString()} / {getOwner().toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
|
|
await m_cache_request.setRetryKey();
|
|
return (false, -1);
|
|
}
|
|
|
|
await m_cache_request.deleteRetryKey();
|
|
|
|
Log.getLogger().debug($"updateDailyCaliumConverter : finished!!! - mis_pivot_calium[{mis_pivot_calium}]");
|
|
return (true, mis_pivot_calium);
|
|
}
|
|
|
|
private async Task<(Result, double mis_pivot_calium)> checkEchoSystemDailyCaliumAsync(CaliumStorageAttrib caliumStorageAttrib, DateTime pivotTime)
|
|
{
|
|
var mis_pivot_calium = 0.0;
|
|
|
|
// 1. echoSystem 조회
|
|
var web3_action = getOwner().getEntityAction<CaliumWeb3Action>();
|
|
NullReferenceCheckHelper.throwIfNull(web3_action, () => $"web3_action is null !!! - {getOwner().toBasicString()}");
|
|
var (result, msg) = await web3_action.getDailyRollUpDataAsync(caliumStorageAttrib.DailyEpoch + caliumStorageAttrib.MisEpoch);
|
|
if (result.isFail() && msg?.m_code != "FIN.WRY.000") return (result, -1);
|
|
|
|
// 1-1. 최초 호출인 경우 데이터 정리
|
|
if (caliumStorageAttrib.DailyEpoch <= 0)
|
|
{
|
|
result = initializeStorage(caliumStorageAttrib, msg?.m_list?.FirstOrDefault());
|
|
if(result.isFail()) return (result, 0);
|
|
}
|
|
|
|
// 2. Data 를 찾지 못하면, 당일 Rollup 이 되지 않은 상태, 예전 데이터로 채워서 넣어야함.
|
|
if (msg?.m_code == "FIN.WRY.000")
|
|
{
|
|
msg = makePreviousRollUpData(caliumStorageAttrib);
|
|
caliumStorageAttrib.MisEpoch += 1;
|
|
result.setSuccess();
|
|
}
|
|
else
|
|
{
|
|
caliumStorageAttrib.MisEpoch = 0;
|
|
}
|
|
|
|
NullReferenceCheckHelper.throwIfNull(msg, () => $"web3 response is null !!! - epoch:{caliumStorageAttrib.DailyEpoch} / {getOwner().toBasicString()}");
|
|
NullReferenceCheckHelper.throwIfNull(msg.m_list, () => $"web3 response is null !!! - epoch:{caliumStorageAttrib.DailyEpoch} / {getOwner().toBasicString()}");
|
|
|
|
Log.getLogger().debug($"checkEchoSystemDailyCaliumAsync : RollUpData Count[{msg.m_list.Count}]");
|
|
|
|
// 3. Daily 데이터 적용
|
|
foreach (var rollup in msg.m_list)
|
|
{
|
|
var pivot_calium = supplyRollUpData(caliumStorageAttrib, rollup, mis_pivot_calium, pivotTime);
|
|
mis_pivot_calium = CaliumStorageHelper.AddDoubleByLong(mis_pivot_calium, pivot_calium);
|
|
}
|
|
|
|
caliumStorageAttrib.DailyPivotDate = pivotTime;
|
|
|
|
Log.getLogger().debug($"checkEchoSystemDailyCaliumAsync : DailyPivotDate[{pivotTime}] / mis_pivot_calium[{mis_pivot_calium}]");
|
|
return (result, mis_pivot_calium);
|
|
}
|
|
|
|
private CaliumRollUpResponse makePreviousRollUpData(CaliumStorageAttrib attrib)
|
|
{
|
|
var response = new CaliumRollUpResponse();
|
|
response.m_list = new List<RollUpData>();
|
|
|
|
var rollup = new RollUpData();
|
|
rollup.m_create_time = attrib.DailyPivotDate.AddDays(1).AddHours(-1);
|
|
rollup.m_daily_converter_rate = attrib.ConverterStorage.DailyConvertRate;
|
|
rollup.m_epoch = attrib.DailyEpoch;
|
|
rollup.m_daily_inflation_rate = attrib.ExchangerStorage.DailyInflationRate;
|
|
rollup.m_convertor_volume = attrib.ConverterStorage.DailyFillUpStandardCalium;
|
|
|
|
response.m_list.Add(rollup);
|
|
|
|
return response;
|
|
}
|
|
|
|
private double supplyRollUpData(CaliumStorageAttrib caliumStorageAttrib, RollUpData rollup, double mis_pivot_calium, DateTime pivotTime)
|
|
{
|
|
Log.getLogger().debug($"supplyRollUpData : Attrib [epoch-{caliumStorageAttrib.DailyEpoch}] RollUp [epoch-{rollup.m_epoch}]");
|
|
|
|
if (rollup.m_epoch != 0 && rollup.m_epoch == caliumStorageAttrib.DailyEpoch)
|
|
{
|
|
// 그날의 미지급 Calium 추가
|
|
var check_pivot_time = CaliumStorageHelper.CurrentPivotTimeDate(caliumStorageAttrib.ConverterStorage.LastFillUpDate);
|
|
var data = checkMissFillUpDailyCalium(caliumStorageAttrib, check_pivot_time.AddDays(1).AddSeconds(-1));
|
|
var fill_up_calium = calculateFillupCalium(caliumStorageAttrib, data.missFillUpCount, data.lastFillUpDate);
|
|
|
|
mis_pivot_calium = CaliumStorageHelper.AddDoubleByLong(mis_pivot_calium, fill_up_calium);
|
|
caliumStorageAttrib.ConverterStorage.TotalCalium = CaliumStorageHelper.AddDoubleByLong(caliumStorageAttrib.ConverterStorage.TotalCalium, fill_up_calium);
|
|
caliumStorageAttrib.ConverterStorage.LastFillUpDate = check_pivot_time.AddHours(MetaHelper.GameConfigMeta.CaliumConverterCycleTime * 2);
|
|
|
|
Log.getLogger().debug($"supplyRollUpData : 1. mis_pivot_calium[{mis_pivot_calium}]");
|
|
return mis_pivot_calium;
|
|
}
|
|
|
|
caliumStorageAttrib.ConverterStorage.ConverterCumulativeCalium = CaliumStorageHelper.AddDoubleByLong(caliumStorageAttrib.ConverterStorage.ConverterCumulativeCalium, rollup.m_convertor_volume);
|
|
|
|
// 1일을 추가한 이유 : create_time 이 전일 23:00:00 ~ 23:59:59 에 생성되기 때문
|
|
var check_date = new DateTime(rollup.m_create_time.Year, rollup.m_create_time.Month, rollup.m_create_time.Day, 0, 0, 0);
|
|
check_date = check_date.AddDays(1);
|
|
|
|
// PivotTime 이 00시 기준이 아닌 경우 체크해야 하기 때문에 시간 추가
|
|
check_date = check_date.AddHours(MetaHelper.GameConfigMeta.CaliumConverterPivotTime);
|
|
|
|
if (check_date < pivotTime)
|
|
{
|
|
mis_pivot_calium = CaliumStorageHelper.AddDoubleByLong(mis_pivot_calium, rollup.m_convertor_volume);
|
|
caliumStorageAttrib.ConverterStorage.TotalCalium = CaliumStorageHelper.AddDoubleByLong(caliumStorageAttrib.ConverterStorage.TotalCalium, rollup.m_convertor_volume);
|
|
caliumStorageAttrib.ConverterStorage.LastFillUpDate = check_date.AddHours(MetaHelper.GameConfigMeta.CaliumConverterCycleTime * 2);
|
|
}
|
|
|
|
if (caliumStorageAttrib.DailyEpoch >= rollup.m_epoch)
|
|
{
|
|
Log.getLogger().debug($"supplyRollUpData : 2. mis_pivot_calium[{mis_pivot_calium}]");
|
|
return mis_pivot_calium;
|
|
}
|
|
caliumStorageAttrib.DailyEpoch = rollup.m_epoch;
|
|
caliumStorageAttrib.ConverterStorage.DailyFillUpStandardCalium = rollup.m_convertor_volume;
|
|
caliumStorageAttrib.ConverterStorage.DailyConvertRate = rollup.m_daily_converter_rate;
|
|
caliumStorageAttrib.ExchangerStorage.DailyInflationRate = rollup.m_daily_inflation_rate;
|
|
|
|
Log.getLogger().debug($"supplyRollUpData : 3. mis_pivot_calium[{mis_pivot_calium}]");
|
|
return mis_pivot_calium;
|
|
}
|
|
|
|
private (int missFillUpCount, DateTime lastFillUpDate) checkMissFillUpDailyCalium(CaliumStorageAttrib caliumStorageAttrib, DateTime? nextPivotTime = null)
|
|
{
|
|
var current = nextPivotTime ?? DateTimeHelper.Current;
|
|
var miss_fill_up_count = 0;
|
|
|
|
// 1. 마지막 충전 시간 확인
|
|
var last_fill_up_date = caliumStorageAttrib.ConverterStorage.LastFillUpDate;
|
|
var fill_up_date = (last_fill_up_date == DateTimeHelper.MinTime) ? current : last_fill_up_date;
|
|
var next_fill_up_date = getNextFillDate(caliumStorageAttrib, fill_up_date);
|
|
|
|
// 2. 다음 충전 시간 체크
|
|
while (next_fill_up_date <= current)
|
|
{
|
|
miss_fill_up_count++;
|
|
|
|
fill_up_date = next_fill_up_date;
|
|
next_fill_up_date = getNextFillDate(caliumStorageAttrib, fill_up_date);
|
|
}
|
|
|
|
Log.getLogger().debug($"checkMissFillUpDailyCalium - miss_fill_up_count[{miss_fill_up_count}] / last_fill_up_date[{last_fill_up_date}] / fill_up_date[{fill_up_date}] / next_pivot_time[{nextPivotTime ?? DateTimeHelper.MinTime}]");
|
|
|
|
return (miss_fill_up_count, fill_up_date);
|
|
}
|
|
|
|
private DateTime getNextFillDate(CaliumStorageAttrib storageAttrib, DateTime current)
|
|
{
|
|
var check = storageAttrib.DailyPivotDate;
|
|
|
|
while (check <= current)
|
|
{
|
|
check = check.AddHours(MetaHelper.GameConfigMeta.CaliumConverterCycleTime);
|
|
}
|
|
|
|
return check;
|
|
}
|
|
|
|
private async Task<double> fillUpDailyCalium(CaliumStorageAttrib caliumStorageAttrib, int fillUpCount, DateTime lastFillUpDate)
|
|
{
|
|
// 1. daily calium 충전량 계산
|
|
var fill_up_calium = calculateFillupCalium(caliumStorageAttrib, fillUpCount, lastFillUpDate);
|
|
|
|
// 2. 최초 시작은 기본값으로 채움
|
|
if (caliumStorageAttrib.ConverterStorage.LastFillUpDate == DateTimeHelper.MinTime)
|
|
{
|
|
fill_up_calium = (double)MetaHelper.GameConfigMeta.CaliumConverterInitialValue;
|
|
}
|
|
|
|
Log.getLogger().debug($"fillUpDailyCalium - fill_up_calium[{fill_up_calium}] / fillUpCount[{fillUpCount}]");
|
|
|
|
if (fill_up_calium <= 0) return fill_up_calium;
|
|
|
|
// 3. calium 변경
|
|
var result = await changeCaliumConverterTotal(fill_up_calium);
|
|
if (result.isFail()) return -1;
|
|
|
|
// 4. data 갱신
|
|
_ = loadStorageAttribute();
|
|
|
|
return fill_up_calium;
|
|
}
|
|
|
|
private double calculateFillupCalium(CaliumStorageAttrib caliumStorageAttrib, int fillUpCount, DateTime lastFillupDate)
|
|
{
|
|
// 0. 충전 횟수가 0 이면, 처리 안함
|
|
if (fillUpCount <= 0) return 0;
|
|
|
|
var daily_total_calium_long = (long)(caliumStorageAttrib.ConverterStorage.DailyFillUpStandardCalium * EchoSystemHelper.DoubleCalculateDigitsLong);
|
|
|
|
var fill_up_calium_long = daily_total_calium_long / m_repeat_count;
|
|
var fill_up_leave_long = daily_total_calium_long % m_repeat_count;
|
|
|
|
fill_up_calium_long *= fillUpCount;
|
|
|
|
// 마지막 회차의 경우, 나머지 부분을 추가해줘야 한다.
|
|
if (lastFillupDate.AddHours(MetaHelper.GameConfigMeta.CaliumConverterCycleTime) >= caliumStorageAttrib.DailyPivotDate.AddDays(1))
|
|
{
|
|
fill_up_calium_long += fill_up_leave_long;
|
|
}
|
|
|
|
return fill_up_calium_long / (double)EchoSystemHelper.DoubleCalculateDigitsLong;
|
|
}
|
|
} |