초기커밋
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class CaliumContentAction : EntityActionBase
|
||||
{
|
||||
public CaliumContentAction(CaliumStorageEntity owner) : base(owner) { }
|
||||
|
||||
public override async Task<Result> onInit() => await Task.FromResult(new Result());
|
||||
|
||||
public override void onClear() {}
|
||||
|
||||
}
|
||||
298
GameServer/Entity/CaliumStorage/Action/CaliumEventAction.cs
Normal file
298
GameServer/Entity/CaliumStorage/Action/CaliumEventAction.cs
Normal file
@@ -0,0 +1,298 @@
|
||||
using Amazon.DynamoDBv2;
|
||||
using Amazon.DynamoDBv2.Model;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class CaliumEventAction : EntityActionBase
|
||||
{
|
||||
private enum ReTryStatus
|
||||
{
|
||||
None = 0,
|
||||
Success = 1,
|
||||
Fail = 2
|
||||
}
|
||||
|
||||
public CaliumEventAction(CaliumStorageEntity owner) : base(owner) { }
|
||||
|
||||
public override async Task<Result> onInit() => await Task.FromResult(new Result());
|
||||
|
||||
public override void onClear() {}
|
||||
|
||||
public async Task<Result> sendCaliumEventFromDB(CaliumEventDoc sendDoc)
|
||||
{
|
||||
var owner = getOwner() as CaliumStorageEntity;
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!");
|
||||
|
||||
var web3_action = owner.getEntityAction<CaliumWeb3Action>();
|
||||
NullReferenceCheckHelper.throwIfNull(web3_action, () => $"calium_web3_action is null !!! - {getOwner().toBasicString()}");
|
||||
|
||||
// 0. 이벤트 전송
|
||||
var request = CaliumStorageHelper.makeCaliumEventRequest(sendDoc);
|
||||
var (result, response) = await web3_action.postCaliumEvent(request);
|
||||
|
||||
// 1. 성공시 리턴 ( 상태 수정 : Success )
|
||||
if (result.isSuccess())
|
||||
{
|
||||
await updateCaliumEventStatus(sendDoc, CaliumEventStatus.Sending, CaliumEventStatus.Success);
|
||||
return result;
|
||||
}
|
||||
|
||||
var res = checkRetryFail(result.ErrorCode, response?.m_code);
|
||||
|
||||
// 2. 이미 처리된 데이터 ( 상태 수정 : Success )
|
||||
if (res == ReTryStatus.Success)
|
||||
{
|
||||
await updateCaliumEventStatus(sendDoc, CaliumEventStatus.Sending, CaliumEventStatus.Success);
|
||||
return new Result();
|
||||
}
|
||||
|
||||
// 3. 실패시 재시도 (상태 수정 : Regist)
|
||||
if (res == ReTryStatus.None)
|
||||
{
|
||||
await updateCaliumEventStatus(sendDoc, CaliumEventStatus.Sending, CaliumEventStatus.Regist);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 재시도 불가 기록 (상태 수정 : Failed)
|
||||
await updateCaliumEventStatus(sendDoc, CaliumEventStatus.Sending, CaliumEventStatus.Failed);
|
||||
|
||||
// 4. 로그 기록
|
||||
var log = new CaliumEchoSystemFailLogData { EventData = request };
|
||||
log.FailCode = response?.m_code ?? string.Empty;
|
||||
log.FailMessages = response?.m_messages ?? new();
|
||||
log.EventData = request;
|
||||
CaliumStorageHelper.writeFailEchoSystemLog(owner, log);
|
||||
Log.getLogger().error($"Failed to send Calium Event !! : {owner.toBasicString()}");
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 칼리움 소각시 Web3 통보 함수
|
||||
/// </summary>
|
||||
/// <param name="actor"> 소각 행위자 </param>
|
||||
/// <param name="eventGuid"> Transaction ID </param>
|
||||
/// <param name="userNickname"> 유저 닉네임 </param>
|
||||
/// <param name="subType"> 소각 행위 구분 </param>
|
||||
/// <param name="caliumDelta"> 칼리움 변화량 ( 음수값 ) </param>
|
||||
/// <returns></returns>
|
||||
public async Task<Result> sendCaliumBurnEvent(IWithLogActor actor, string eventGuid, string userNickname, string subType, double caliumDelta)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
if (ServerCore.TypeHelper.NumericSignType.Positive == ServerCore.TypeHelper.checkNumericSignType<double>(caliumDelta))
|
||||
{
|
||||
caliumDelta *= -1;
|
||||
}
|
||||
|
||||
var send = await sendCaliumEvent(actor, CaliumEventType.calium_burn, eventGuid, userNickname, subType, 0, caliumDelta, true);
|
||||
|
||||
if (false == send.is_success)
|
||||
{
|
||||
var err_msg =
|
||||
$"fail to send calium event !! : eventGuid[{eventGuid}] subtype[{subType}] userNickanme[{userNickname}] caliumDelta[{caliumDelta}] / {nameof(sendCaliumEventFromPlayer)}";
|
||||
result.setFail(ServerErrorCode.FailToSendEchoSystem, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<(bool is_success, CaliumEventData event_data)> sendCaliumEventFromPlayer(Player player, CaliumEventType type, string subType, double sapphireDelta, double caliumdelta, bool isReTry = true)
|
||||
{
|
||||
return await sendCaliumEvent(player, type, player.getUserGuid(), player.getUserNickname(), subType, sapphireDelta, caliumdelta, isReTry);
|
||||
}
|
||||
|
||||
public async Task<(Result result, CaliumEventDoc? change_doc)> updateCaliumEventStatus(CaliumEventDoc targetDoc, CaliumEventStatus beforeStatus, CaliumEventStatus afterStatus)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var dynamoDb_client = server_logic.getDynamoDbClient();
|
||||
NullReferenceCheckHelper.throwIfNull(dynamoDb_client, () => $"dynamodb client is null !!! ");
|
||||
|
||||
var make_primary_key = targetDoc.getPrimaryKey();
|
||||
|
||||
var updateRequest = makeUpdateItemRequest(targetDoc, make_primary_key.toKeyWithAttributeValue(), nameof(CaliumEventAttrib.Status), beforeStatus, afterStatus);
|
||||
if (updateRequest.result.isFail() || null == updateRequest.request)
|
||||
{
|
||||
if (updateRequest.result.isSuccess())
|
||||
{
|
||||
result.setFail(ServerErrorCode.FailToGetEchoSystemException, $"failed to make item request!!! - {getOwner().toBasicString()}");
|
||||
}
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
(result, var change_doc) = await dynamoDb_client.simpleQueryDocTypesWithUpdateItemRequest<CaliumEventDoc>(updateRequest.request);
|
||||
return (result, change_doc);
|
||||
}
|
||||
|
||||
private async Task<(bool is_success, CaliumEventData event_data)> sendCaliumEvent(IWithLogActor actor, CaliumEventType type, string eventGuid, string userNickname, string subType, double sapphireDelta, double caliumDelta, bool isRetry)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var owner = getOwner() as CaliumStorageEntity;
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!");
|
||||
|
||||
var web3_action = owner.getEntityAction<CaliumWeb3Action>();
|
||||
NullReferenceCheckHelper.throwIfNull(web3_action, () => $"calium_web3_action is null !!! - {getOwner().toBasicString()}");
|
||||
|
||||
// 0. echoSystem 전송
|
||||
var request = await CaliumStorageHelper.makeCaliumEventRequest(owner, type, subType, userNickname, sapphireDelta, caliumDelta);
|
||||
(result, var response) = await web3_action.postCaliumEvent(request);
|
||||
|
||||
// 1. 성공시 리턴
|
||||
if (result.isSuccess()) return (true, request);
|
||||
|
||||
// 2. 실패시 DB 기록 및 Retry
|
||||
if (isRetry)
|
||||
{
|
||||
var event_guid = await retryPostCaliumEvent(eventGuid, result.ErrorCode, request, response);
|
||||
result.setSuccess();
|
||||
return (true, request);
|
||||
}
|
||||
|
||||
// 3. 실패시 실패 로그 기록
|
||||
var fail_log = new CaliumEchoSystemFailLogData();
|
||||
fail_log.FailCode = response?.m_code ?? string.Empty;
|
||||
fail_log.FailMessages = response?.m_messages ?? new();
|
||||
fail_log.ReTry = false;
|
||||
fail_log.EventData = request;
|
||||
|
||||
CaliumStorageHelper.writeFailEchoSystemLog(actor, fail_log);
|
||||
|
||||
return (false, request);
|
||||
}
|
||||
|
||||
private async Task<string> retryPostCaliumEvent(string userGuid, ServerErrorCode errCode, CaliumEventRequest request, EchoSystemBaseResponse? response)
|
||||
{
|
||||
var calium_entity = getOwner() as CaliumStorageEntity;
|
||||
NullReferenceCheckHelper.throwIfNull(calium_entity, () => "calium_entity is null !!!");
|
||||
|
||||
string event_guid;
|
||||
|
||||
var res = checkRetryFail(errCode, response?.m_code);
|
||||
|
||||
// 0. 이미 처리된 메시지
|
||||
if (res == ReTryStatus.Success)
|
||||
{
|
||||
event_guid = await saveCaliumEventToDB(userGuid, request, CaliumEventStatus.Success);
|
||||
return event_guid;
|
||||
}
|
||||
|
||||
// 1. 실패시 재시도 저장
|
||||
if (res != ReTryStatus.Fail)
|
||||
{
|
||||
event_guid = await saveCaliumEventToDB(userGuid, request, CaliumEventStatus.Regist);
|
||||
return event_guid;
|
||||
}
|
||||
|
||||
// 2. 재시도 불가 기록
|
||||
event_guid = await saveCaliumEventToDB(userGuid, request, CaliumEventStatus.Failed);
|
||||
|
||||
// 3. 로그 기록 ( 비즈니스? DB? )
|
||||
var fail_log = new CaliumEchoSystemFailLogData();
|
||||
fail_log.FailCode = response?.m_code ?? string.Empty;
|
||||
fail_log.FailMessages = response?.m_messages ?? new();
|
||||
fail_log.ReTry = true;
|
||||
fail_log.EventData = request;
|
||||
|
||||
CaliumStorageHelper.writeFailEchoSystemLog(calium_entity, fail_log);
|
||||
|
||||
return event_guid;
|
||||
}
|
||||
|
||||
private ReTryStatus checkRetryFail(ServerErrorCode errCode, string? code)
|
||||
{
|
||||
// 1. http 에러인 경우
|
||||
if (ServerErrorCode.FailToGetEchoSystemHttpError == errCode) return ReTryStatus.Fail;
|
||||
|
||||
// 2. DB insert fail 인 경우
|
||||
if (ServerErrorCode.GetFailEchoSystemResponse == errCode && code == "RET.WCE.101") return ReTryStatus.None;
|
||||
|
||||
// 3. 이미 처리된 Message 인 경우 ( 성공 처리 )
|
||||
if (ServerErrorCode.GetFailEchoSystemResponse == errCode && code == "FIN_WCE_200") return ReTryStatus.Success;
|
||||
|
||||
return ReTryStatus.Fail;
|
||||
}
|
||||
|
||||
private async Task<string> saveCaliumEventToDB(string userGuid, CaliumEventRequest request, CaliumEventStatus isRetry)
|
||||
{
|
||||
var doc = new CaliumEventDoc(request.m_event_id);
|
||||
var attrib = doc.getAttrib<CaliumEventAttrib>();
|
||||
NullReferenceCheckHelper.throwIfNull(attrib, () => $"calium event attrib is null !!! - userGuid[{userGuid}] / {getOwner().toBasicString()}");
|
||||
|
||||
attrib.UserGuid = userGuid;
|
||||
attrib.EventData.m_server_type = request.m_server_type;
|
||||
attrib.EventData.m_event_type = request.m_event_type;
|
||||
attrib.EventData.m_sub_type = request.m_sub_type;
|
||||
attrib.EventData.m_div_type = request.m_div_type;
|
||||
attrib.EventData.m_div_id = request.m_div_id;
|
||||
attrib.EventData.m_calium_delta = request.m_calium_delta;
|
||||
attrib.EventData.m_sapphire_delta = request.m_sapphire_delta;
|
||||
attrib.EventData.m_current_epoch = request.m_current_epoch;
|
||||
attrib.EventData.m_current_inflation_rate = request.m_current_inflation_rate;
|
||||
attrib.Status = isRetry;
|
||||
|
||||
var dynamoDb_client = GameServerApp.getServerLogic().getDynamoDbClient();
|
||||
await dynamoDb_client.simpleUpsertDocumentWithDocType(doc);
|
||||
|
||||
return request.m_event_id;
|
||||
}
|
||||
|
||||
private (Result result, UpdateItemRequest? request) makeUpdateItemRequest( CaliumEventDoc target_doc, Dictionary<string, AttributeValue> attributeValueWithPrimaryKey
|
||||
, string targetAttribName
|
||||
, CaliumEventStatus beforeStatus
|
||||
, CaliumEventStatus afterStatus )
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var dynamoDb_client = server_logic.getDynamoDbClient();
|
||||
NullReferenceCheckHelper.throwIfNull(dynamoDb_client, () => $"dynamodb client is null !!! ");
|
||||
|
||||
var result = new Result();
|
||||
|
||||
var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(dynamoDb_client.getTableFullName(target_doc.TableName));
|
||||
query_builder.withKeys(attributeValueWithPrimaryKey);
|
||||
|
||||
var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
|
||||
var target_key = JsonHelper.getJsonPropertyName<CaliumEventAttrib>(targetAttribName);
|
||||
var (is_success, attribute_expression) = DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, target_key);
|
||||
if (false == is_success)
|
||||
{
|
||||
var err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{target_key}";
|
||||
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
query_builder.withExpressionAttributeNames(DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, target_key));
|
||||
|
||||
// 변경값 설정
|
||||
var update_expression = $"SET {attribute_expression} = :changeValue";
|
||||
query_builder.withUpdateExpression(update_expression);
|
||||
|
||||
// 조건 추가
|
||||
query_builder.withConditionExpression($"{attribute_expression} = :beforeValue");
|
||||
|
||||
// 설정값 등록
|
||||
var expression_attribute_values = new Dictionary<string, AttributeValue>
|
||||
{
|
||||
{ ":changeValue", new AttributeValue { S = afterStatus.ToString() } },
|
||||
{ ":beforeValue", new AttributeValue { S = beforeStatus.ToString() } }
|
||||
};
|
||||
query_builder.withExpressionAttributeValues(expression_attribute_values);
|
||||
|
||||
query_builder.withReturnValues(ReturnValue.ALL_NEW);
|
||||
|
||||
return query_builder.build();
|
||||
}
|
||||
}
|
||||
602
GameServer/Entity/CaliumStorage/Action/CaliumStorageAction.cs
Normal file
602
GameServer/Entity/CaliumStorage/Action/CaliumStorageAction.cs
Normal file
@@ -0,0 +1,602 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
62
GameServer/Entity/CaliumStorage/Action/CaliumWeb3Action.cs
Normal file
62
GameServer/Entity/CaliumStorage/Action/CaliumWeb3Action.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class CaliumWeb3Action : EntityActionBase
|
||||
{
|
||||
private readonly EchoSystemRequester m_echo_requester;
|
||||
public const string SERVER_TYPE = "caliverse";
|
||||
|
||||
public CaliumWeb3Action(CaliumStorageEntity owner) : base(owner)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var server_config = server_logic.getServerConfig();
|
||||
|
||||
var ip = AwsHelper.getAwsPublicIPv4OrEthernetIPv4();
|
||||
var port = server_config.getAppParamPort();
|
||||
|
||||
m_echo_requester = new EchoSystemRequester(server_config.EchoSystemConfig.BaseAddress, server_logic.getServerName(), $"{ip}.{port}", server_config.EchoSystemConfig.SlackAddress);
|
||||
}
|
||||
|
||||
public override async Task<Result> onInit() => await Task.FromResult(new Result());
|
||||
|
||||
public override void onClear() {}
|
||||
|
||||
public async Task<(Result result, CaliumRollUpResponse? response)> getDailyRollUpDataAsync(int epoch)
|
||||
{
|
||||
if (epoch > 0)
|
||||
{
|
||||
return await m_echo_requester.getDailyRollUpData(epoch);
|
||||
}
|
||||
|
||||
var current_pivot_date = CaliumStorageHelper.CurrentPivotTimeDate();
|
||||
|
||||
// 1일을 감소한 이유 : create_time 이 전일 23:00:00 ~ 23:59:59 에 생성되기 때문
|
||||
current_pivot_date = current_pivot_date.AddDays(-1);
|
||||
return await m_echo_requester.getDailyRollUpData(current_pivot_date);
|
||||
}
|
||||
|
||||
public async Task<(Result result, ConverterSyncResponse? response)> getConverterSyncDataAsync()
|
||||
{
|
||||
return await m_echo_requester.getConverterSyncData();
|
||||
}
|
||||
|
||||
public async Task<(Result result, CaliumEventResponse? response)> postCaliumEvent(CaliumEventRequest data)
|
||||
{
|
||||
return await m_echo_requester.postCaliumEvent(data);
|
||||
}
|
||||
|
||||
public async Task<Result> checkWeb3Connection()
|
||||
{
|
||||
return await m_echo_requester.checkWeb3Connection();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class CaliumConverterFailBusinessLog : ILogInvokerEx
|
||||
{
|
||||
private CaliumConverterFailLogData m_data_to_log;
|
||||
|
||||
public CaliumConverterFailBusinessLog(CaliumConverterFailLogData log) : base(LogDomainType.CaliumStorageFail)
|
||||
{
|
||||
m_data_to_log = log;
|
||||
}
|
||||
|
||||
public override bool hasLog() => true;
|
||||
|
||||
protected override void fillup(ref BusinessLog.LogBody body)
|
||||
{
|
||||
body.append(new CaliumConverterFailLogData(this, m_data_to_log));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class CaliumEchoSystemFailBusinessLog : ILogInvokerEx
|
||||
{
|
||||
private CaliumEchoSystemFailLogData m_data_to_log;
|
||||
|
||||
public CaliumEchoSystemFailBusinessLog(CaliumEchoSystemFailLogData log) : base(LogDomainType.CaliumEchoSystem)
|
||||
{
|
||||
m_data_to_log = log;
|
||||
}
|
||||
|
||||
public override bool hasLog() => true;
|
||||
|
||||
protected override void fillup(ref BusinessLog.LogBody body)
|
||||
{
|
||||
body.append(new CaliumEchoSystemFailLogData(this, m_data_to_log));
|
||||
}
|
||||
}
|
||||
83
GameServer/Entity/CaliumStorage/CaliumConverterCheat.cs
Normal file
83
GameServer/Entity/CaliumStorage/CaliumConverterCheat.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
[ChatCommandAttribute("caliumconverter", typeof(ChatCommandCaliumConverter), AuthAdminLevelType.Developer, AuthAdminLevelType.GmNormal, AuthAdminLevelType.GmSuper)]
|
||||
internal class ChatCommandCaliumConverter : ChatCommandBase
|
||||
{
|
||||
public override async Task invoke(Player player, string token, string[] args)
|
||||
{
|
||||
Log.getLogger().info($"ChatCommandCaliumConverter");
|
||||
|
||||
var message = new ClientToGame();
|
||||
message.Request = new ClientToGameReq();
|
||||
message.Request.ReqCaliumConverter = new();
|
||||
|
||||
var result = await GameServerApp.getServerLogic().onCallProtocolHandler(player, message);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"fail to run ConvertCaliumCommand!! : {result.toBasicString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ChatCommandAttribute("initcaliumforuser", typeof(ChatCommandInitCaliumForUser), AuthAdminLevelType.Developer, AuthAdminLevelType.GmNormal, AuthAdminLevelType.GmSuper)]
|
||||
internal class ChatCommandInitCaliumForUser : ChatCommandBase
|
||||
{
|
||||
public override async Task invoke(Player player, string token, string[] args)
|
||||
{
|
||||
Log.getLogger().info($"InitCaliumForUserCommand");
|
||||
|
||||
var result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "CheatInitCaliumForUserDaily", initCaliumDelegate);
|
||||
if (result.isFail())
|
||||
{
|
||||
Log.getLogger().error($"fail to run InitCaliumForUserCommand!! : {result.toBasicString()} / {player.toBasicString()}");
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
async Task<Result> initCaliumDelegate() => await initCalium(player);
|
||||
}
|
||||
|
||||
private async Task<Result> initCalium(Player player)
|
||||
{
|
||||
var user_calium_attribute = player.getEntityAttribute<CaliumAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(user_calium_attribute, () => $"user_calium_attribute is null !!! - {player.toBasicString()}");
|
||||
|
||||
user_calium_attribute.DailyCalium = (double)MetaHelper.GameConfigMeta.CaliumConverterLimitPerPerson;
|
||||
user_calium_attribute.modifiedEntityAttribute();
|
||||
|
||||
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.ConvertCalium, GameServerApp.getServerLogic().getDynamoDbClient(), true);
|
||||
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
||||
|
||||
return await QueryHelper.sendQueryAndBusinessLog(batch);
|
||||
}
|
||||
}
|
||||
|
||||
[ChatCommandAttribute("caliumcontentcreate", typeof(ChatCommandCaliumContentCreate), AuthAdminLevelType.Developer, AuthAdminLevelType.GmNormal, AuthAdminLevelType.GmSuper)]
|
||||
internal class ChatCommandCaliumContentCreate : ChatCommandBase
|
||||
{
|
||||
public override async Task invoke(Player player, string token, string[] args)
|
||||
{
|
||||
Log.getLogger().info($"ChatCommandCaliumContentCreate");
|
||||
|
||||
if (args.Length < 2) return;
|
||||
|
||||
var content_id = args[0];
|
||||
if (false == double.TryParse(args[1], out var calium)) return;
|
||||
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
|
||||
var message = new ServerMessage();
|
||||
message.ReqCreateContentStorage = new();
|
||||
message.ReqCreateContentStorage.ContentId = content_id;
|
||||
message.ReqCreateContentStorage.Calium = calium;
|
||||
message.ReqCreateContentStorage.RequestServerName = server_logic.getServerName();
|
||||
|
||||
var handler = new ReqCreateCaliumContentStorageHandler();
|
||||
var result = await handler.createCaliumContentStorage(message.ReqCreateContentStorage.ContentId, message.ReqCreateContentStorage.Calium);
|
||||
}
|
||||
}
|
||||
57
GameServer/Entity/CaliumStorage/CaliumStorageEntity.cs
Normal file
57
GameServer/Entity/CaliumStorage/CaliumStorageEntity.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class CaliumStorageEntity : EntityBase, IWithLogActor
|
||||
{
|
||||
public CaliumStorageEntity() : base(EntityType.CaliumConverter)
|
||||
{}
|
||||
|
||||
public override async Task<Result> onInit()
|
||||
{
|
||||
// attribute
|
||||
addEntityAttribute(new CaliumStorageAttribute(this));
|
||||
|
||||
// action
|
||||
addEntityAction(new CaliumStorageAction(this));
|
||||
addEntityAction(new CaliumContentAction(this));
|
||||
addEntityAction(new CaliumEventAction(this));
|
||||
addEntityAction(new CaliumWeb3Action(this));
|
||||
|
||||
return await base.onInit();
|
||||
}
|
||||
|
||||
public override string toBasicString()
|
||||
{
|
||||
return $"{this.getTypeName()}";
|
||||
}
|
||||
|
||||
public override string toSummaryString()
|
||||
{
|
||||
return $"{this.getTypeName()}";
|
||||
}
|
||||
|
||||
public virtual ILogActor toLogActor()
|
||||
{
|
||||
var server_logic = ServerLogicApp.getServerLogicApp();
|
||||
var log_info = new CaliumActorLog();
|
||||
|
||||
log_info.initLogInfo(
|
||||
// 서버 정보
|
||||
server_logic.getServerConfig().getRegionId()
|
||||
, server_logic.getServerConfig().getWorldId()
|
||||
, server_logic.getServerType().toServerType()
|
||||
);
|
||||
|
||||
return log_info;
|
||||
}
|
||||
}
|
||||
162
GameServer/Entity/CaliumStorage/CaliumStorageHelper.cs
Normal file
162
GameServer/Entity/CaliumStorage/CaliumStorageHelper.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public static class CaliumStorageHelper
|
||||
{
|
||||
public const double FixedExchangeRate = 0.01;
|
||||
|
||||
public static DateTime CurrentPivotTimeDate(DateTime? customDate = null)
|
||||
{
|
||||
var current = customDate ?? DateTimeHelper.Current;
|
||||
|
||||
if (current.Hour < ServerCommon.MetaHelper.GameConfigMeta.CaliumConverterPivotTime)
|
||||
{
|
||||
current = current.AddDays(-1);
|
||||
}
|
||||
|
||||
return new DateTime(current.Year, current.Month, current.Day, ServerCommon.MetaHelper.GameConfigMeta.CaliumConverterPivotTime, 0, 0);
|
||||
}
|
||||
|
||||
public static async Task<double> calculateCaliumFromSapphire(double sapphire, bool isCeiling = false)
|
||||
{
|
||||
// 1. 기본 정보 조회
|
||||
var calium_storage_entity = GameServerApp.getServerLogic().findGlobalEntity<CaliumStorageEntity>();
|
||||
NullReferenceCheckHelper.throwIfNull(calium_storage_entity, () => "calium_storage_entity is null !!!");
|
||||
|
||||
var calium_storage_action = calium_storage_entity.getEntityAction<CaliumStorageAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(calium_storage_action, () => $"calium_storage_action is null !!! - {calium_storage_entity.toBasicString()}");
|
||||
|
||||
var info = await calium_storage_action.getCaliumStorageInfo();
|
||||
|
||||
// 2. calium 교환비 계산 : (사파이어 * 고정 교환비) / 인플레이션 가중치(당일, % 처리)
|
||||
var calium = MultiplyDoubleByLong(sapphire, FixedExchangeRate);
|
||||
calium /= info.DailyInflationRate / 100;
|
||||
|
||||
// 3. 소수점 2자리수에서 판매는 올림 / 교환은 버림
|
||||
calium = isCeiling ? roundUpDefaultDigitsFromDouble(calium) : roundDownDefaultDigitsFromDouble(calium);
|
||||
|
||||
Log.getLogger().debug($"calculateCaliumFromSapphire !! : sapphire[{sapphire}] / calium[{calium}] / isCeiling[{isCeiling}] / swap_rate[{info.DailyInflationRate}]");
|
||||
|
||||
return calium;
|
||||
}
|
||||
|
||||
public static bool compareDoubleByLong(double first, double second)
|
||||
{
|
||||
var first_long = (long)(roundHalfUpDefaultDigitsFromDouble(first) * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
var second_long = (long)(roundHalfUpDefaultDigitsFromDouble(second) * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
|
||||
return first_long == second_long;
|
||||
}
|
||||
|
||||
public static double roundHalfUpDefaultDigitsFromDouble(double value)
|
||||
{
|
||||
var default_value = Math.Round(value * EchoSystemHelper.DoubleCalculateDigitsLong, 0);
|
||||
|
||||
var value_long = (long)default_value;
|
||||
return value_long / (double)EchoSystemHelper.DoubleCalculateDigitsLong;
|
||||
}
|
||||
|
||||
public static double roundDownDefaultDigitsFromDouble(double value)
|
||||
{
|
||||
var value_long = (long)(value * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
return value_long / (double)EchoSystemHelper.DoubleCalculateDigitsLong;
|
||||
}
|
||||
|
||||
public static double roundUpDefaultDigitsFromDouble(double value)
|
||||
{
|
||||
var default_value = Math.Ceiling(value * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
|
||||
var value_long = (long)default_value;
|
||||
return value_long / (double)EchoSystemHelper.DoubleCalculateDigitsLong;
|
||||
}
|
||||
|
||||
public static double AddDoubleByLong(double first, double second)
|
||||
{
|
||||
var first_long = (long)(first * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
var second_long = (long)(second * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
|
||||
var add = first_long + second_long;
|
||||
|
||||
return add / (double)EchoSystemHelper.DoubleCalculateDigitsLong;
|
||||
}
|
||||
|
||||
public static double SubTractDoubleByLong(double first, double second)
|
||||
{
|
||||
var first_long = (long)(first * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
var second_long = (long)(second * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
|
||||
var add = first_long - second_long;
|
||||
|
||||
return add / (double)EchoSystemHelper.DoubleCalculateDigitsLong;
|
||||
}
|
||||
|
||||
public static double MultiplyDoubleByLong(double first, double second)
|
||||
{
|
||||
var first_long = (long)(first * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
var second_long = (long)(second * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
|
||||
var mul = first_long * second_long;
|
||||
|
||||
return mul / (double)(EchoSystemHelper.DoubleCalculateDigitsLong * EchoSystemHelper.DoubleCalculateDigitsLong);
|
||||
}
|
||||
|
||||
public static void writeFailEchoSystemLog(IWithLogActor logActor, CaliumEchoSystemFailLogData log)
|
||||
{
|
||||
var log_action = new LogActionEx(LogActionType.FailCaliumEchoSystem);
|
||||
var invokers = new List<ILogInvoker>();
|
||||
invokers.Add(new CaliumEchoSystemFailBusinessLog(log));
|
||||
|
||||
BusinessLogger.collectLogs(log_action, logActor, invokers);
|
||||
}
|
||||
|
||||
public static async Task<CaliumEventRequest> makeCaliumEventRequest(CaliumStorageEntity owner, CaliumEventType type, string subType, string userNickname, double sapphireDelta, double caliumDelta)
|
||||
{
|
||||
var storage_action = owner.getEntityAction<CaliumStorageAction>();
|
||||
NullReferenceCheckHelper.throwIfNull(storage_action, () => $"calium_storage_action is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var storage = await storage_action.getCaliumStorageInfo();
|
||||
|
||||
var request = new CaliumEventRequest();
|
||||
request.m_server_type = CaliumWeb3Action.SERVER_TYPE;
|
||||
request.m_event_type = type.ToString();
|
||||
request.m_sub_type = subType;
|
||||
request.m_div_id = userNickname;
|
||||
request.m_calium_delta = caliumDelta;
|
||||
request.m_sapphire_delta = sapphireDelta;
|
||||
request.m_current_epoch = storage.DailyApplyEpoch;
|
||||
request.m_current_inflation_rate = storage.DailyInflationRate;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
public static CaliumEventRequest makeCaliumEventRequest(CaliumEventDoc sendDoc)
|
||||
{
|
||||
var attrib = sendDoc.getAttrib<CaliumEventAttrib>();
|
||||
NullReferenceCheckHelper.throwIfNull(attrib, () => $"calium_event_attrib is null !!! - {sendDoc.toBasicString()}");
|
||||
|
||||
// 2. echoSystem 전송
|
||||
var request = new CaliumEventRequest();
|
||||
request.m_event_id = sendDoc.getCombinationKeyForSK();
|
||||
request.m_server_type = attrib.EventData.m_server_type;
|
||||
request.m_event_type = attrib.EventData.m_event_type;
|
||||
request.m_sub_type = attrib.EventData.m_sub_type;
|
||||
request.m_div_type = attrib.EventData.m_div_type;
|
||||
request.m_div_id = attrib.EventData.m_div_id;
|
||||
request.m_calium_delta = attrib.EventData.m_calium_delta;
|
||||
request.m_sapphire_delta = attrib.EventData.m_sapphire_delta;
|
||||
request.m_current_epoch = attrib.EventData.m_current_epoch;
|
||||
request.m_current_inflation_rate = attrib.EventData.m_current_inflation_rate;
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
100
GameServer/Entity/CaliumStorage/DbQuery/DBQCaliumStorageLoad.cs
Normal file
100
GameServer/Entity/CaliumStorage/DbQuery/DBQCaliumStorageLoad.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class DBQCaliumStorageLoad : QueryExecutorBase
|
||||
{
|
||||
private string m_pk = string.Empty;
|
||||
|
||||
public DBQCaliumStorageLoad() : base(nameof(DBQCaliumStorageLoad)) {}
|
||||
|
||||
//===================================================================================================
|
||||
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
|
||||
//===================================================================================================
|
||||
public override Task<Result> onPrepareQuery()
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var owner = getOwner();
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
||||
|
||||
var doc = new CaliumStorageDoc();
|
||||
doc.setCombinationKeyForPK(string.Empty);
|
||||
|
||||
var error_code = doc.onApplyPKSK();
|
||||
if (error_code.isFail())
|
||||
{
|
||||
var err_msg = $"Failed to onApplyPKSK() !!! : {error_code.toBasicString()} - {toBasicString()}, {owner.toBasicString()}";
|
||||
result.setFail(error_code, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
m_pk = doc.getPK();
|
||||
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
//===================================================================================================
|
||||
// onPrepareQuery()를 성공할 경우 호출된다.
|
||||
//===================================================================================================
|
||||
public override async Task<Result> onQuery()
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var owner = getOwner();
|
||||
NullReferenceCheckHelper.throwIfNull(owner, () => "owner is null !!!");
|
||||
|
||||
var query_batch = getQueryBatch();
|
||||
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!!");
|
||||
|
||||
var db_connector = query_batch.getDynamoDbConnector();
|
||||
var query_config = db_connector.makeQueryConfigForReadByPKOnly(m_pk);
|
||||
|
||||
(result, var read_docs) = await db_connector.simpleQueryDocTypesWithQueryOperationConfig<CaliumStorageDoc>(query_config, eventTid: query_batch.getTransId());
|
||||
if (result.isFail()) return result;
|
||||
|
||||
if (read_docs.Count <= 0)
|
||||
{
|
||||
result.setFail(ServerErrorCode.DynamoDbQueryNoMatchAttribute, $"fail to find calium storage doc");
|
||||
return result;
|
||||
}
|
||||
|
||||
var calium_storage_doc = read_docs.FirstOrDefault();
|
||||
NullReferenceCheckHelper.throwIfNull(calium_storage_doc, () => $"calium_storage_doc is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var calium_storage_attribute = owner.getEntityAttribute<CaliumStorageAttribute>();
|
||||
NullReferenceCheckHelper.throwIfNull(calium_storage_attribute, () => $"calium_storage_attribute is null !!! - {owner.toBasicString()}");
|
||||
|
||||
if (false == calium_storage_attribute.copyEntityAttributeFromDoc(calium_storage_doc))
|
||||
{
|
||||
var err_msg = $"failed to load Calium Storage !!! - {owner.toBasicString()}";
|
||||
result.setFail(ServerErrorCode.FailToLoadCalium, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//===================================================================================================
|
||||
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
|
||||
//===================================================================================================
|
||||
public override Task onQueryResponseCommit()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
//===================================================================================================
|
||||
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
|
||||
//===================================================================================================
|
||||
public override Task onQueryResponseRollback(Result errorResult)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private new CaliumStorageEntity? getOwner() => getQueryBatch()?.getLogActor() as CaliumStorageEntity;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using Amazon.DynamoDBv2.DocumentModel;
|
||||
using Amazon.DynamoDBv2.Model;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class DBQContentCaliumCreate : QueryExecutorBase
|
||||
{
|
||||
private readonly string m_contentId;
|
||||
private readonly double m_calium;
|
||||
|
||||
public DBQContentCaliumCreate(string contentId, double calium) : base(nameof(DBQContentCaliumCreate))
|
||||
{
|
||||
m_contentId = contentId;
|
||||
m_calium = calium;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
|
||||
//=====================================================================================
|
||||
public override async Task<Result> onPrepareQuery() => await Task.FromResult(new Result());
|
||||
|
||||
//=====================================================================================
|
||||
// onPrepareQuery()를 성공할 경우 호출된다.
|
||||
//=====================================================================================
|
||||
public override async Task<Result> onQuery()
|
||||
{
|
||||
var owner = getOwner();
|
||||
|
||||
var query_batch = getQueryBatch() as QueryBatch<QueryRunnerWithItemRequest>;
|
||||
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var query_runner_with_item_request = query_batch.getQueryRunner();
|
||||
NullReferenceCheckHelper.throwIfNull(query_runner_with_item_request, () => $"query_runner_with_item_request is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var db_connector = query_batch.getDynamoDbConnector();
|
||||
var create = await makeCreateItemRequestCaliumContentStorage(db_connector);
|
||||
if (create.result.isFail()) return create.result;
|
||||
NullReferenceCheckHelper.throwIfNull(create.putItemRequest, () => $"create_request is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var query_context = create.putItemRequest.createItemRequestQueryContext(QueryType.Insert);
|
||||
var result = await query_runner_with_item_request.tryRegisterQueryContext(query_context);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
|
||||
//=====================================================================================
|
||||
public override async Task onQueryResponseCommit()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
|
||||
//=====================================================================================
|
||||
public override async Task onQueryResponseRollback(Result errorResult)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
private async Task<(Result result, PutItemRequest? putItemRequest)> makeCreateItemRequestCaliumContentStorage(DynamoDbClient dbClient)
|
||||
{
|
||||
var target_doc = new CaliumContentDoc(m_contentId);
|
||||
var attrib = target_doc.getAttrib<CaliumContentAttrib>();
|
||||
NullReferenceCheckHelper.throwIfNull(attrib, () => $"calium_content_attrib is null !!! - {getOwner().toBasicString()}");
|
||||
|
||||
attrib.ContentId = m_contentId;
|
||||
attrib.TotalCalium = m_calium;
|
||||
|
||||
var (result, document) = await target_doc.onCopyToDocument();
|
||||
if (result.isFail()) return (result, null);
|
||||
|
||||
var put_item_request = new PutItemRequest();
|
||||
put_item_request.TableName = dbClient.getTableFullName(ServerBase.DynamoDbDefine.TableNames.Main);
|
||||
put_item_request.Item = document.ToAttributeMap();
|
||||
|
||||
return (result, put_item_request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using Amazon.DynamoDBv2;
|
||||
using Amazon.DynamoDBv2.Model;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class DBQStorageCaliumSyncDateUpdate : QueryExecutorBase
|
||||
{
|
||||
private PrimaryKey m_primary_key = new();
|
||||
private DateTime m_sync_date { get; set; }
|
||||
|
||||
public DBQStorageCaliumSyncDateUpdate(DateTime syncDate) : base(nameof(DBQStorageCaliumSyncDateUpdate))
|
||||
{
|
||||
m_sync_date = syncDate;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
|
||||
//=====================================================================================
|
||||
public override async Task<Result> onPrepareQuery()
|
||||
{
|
||||
var owner = getOwner();
|
||||
|
||||
var (result, make_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey<CaliumStorageDoc>(string.Empty);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
NullReferenceCheckHelper.throwIfNull(make_primary_key, () => $"make_primary_key is null !!! - {owner.toBasicString()}");
|
||||
|
||||
m_primary_key = make_primary_key;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// onPrepareQuery()를 성공할 경우 호출된다.
|
||||
//=====================================================================================
|
||||
public override async Task<Result> onQuery()
|
||||
{
|
||||
var owner = getOwner();
|
||||
|
||||
var query_batch = getQueryBatch() as QueryBatch<QueryRunnerWithItemRequest>;
|
||||
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var query_runner_with_item_request = query_batch.getQueryRunner();
|
||||
NullReferenceCheckHelper.throwIfNull(query_runner_with_item_request, () => $"query_runner_with_item_request is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var db_connector = query_batch.getDynamoDbConnector();
|
||||
var target = JsonHelper.getJsonPropertyName<CaliumStorageAttrib>(nameof(CaliumStorageAttrib.DailyRollUpCheckDate));
|
||||
var update = makeUpdateItemRequest(db_connector, m_primary_key.toKeyWithAttributeValue(), target);
|
||||
if (update.result.isFail()) return update.result;
|
||||
NullReferenceCheckHelper.throwIfNull(update.updateRequest, () => $"update_request is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var exception_handler = new DynamoDbQueryExceptionNotifier.ExceptionHandler(DynamoDbQueryExceptionNotifier.ConditionalCheckFailed, ServerErrorCode.LackOfTotalCalium);
|
||||
|
||||
var query_context = update.updateRequest.createItemRequestQueryContext(QueryType.Update, exception_handler);
|
||||
var result = await query_runner_with_item_request.tryRegisterQueryContext(query_context);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
|
||||
//=====================================================================================
|
||||
public override async Task onQueryResponseCommit()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
|
||||
//=====================================================================================
|
||||
public override async Task onQueryResponseRollback(Result errorResult)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
private (Result result, UpdateItemRequest? updateRequest) makeUpdateItemRequest(DynamoDbClient dbClient, Dictionary<string, AttributeValue> attributeValueWithPrimaryKey, string targetAttribName)
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
if (string.IsNullOrEmpty(targetAttribName))
|
||||
{
|
||||
err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : targetAttribName - {targetAttribName}";
|
||||
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
var target_doc = new CaliumStorageDoc();
|
||||
|
||||
var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(dbClient.getTableFullName(target_doc.TableName));
|
||||
query_builder.withKeys(attributeValueWithPrimaryKey);
|
||||
|
||||
var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
|
||||
(var is_success, var attribute_expression) = DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, targetAttribName);
|
||||
if (false == is_success)
|
||||
{
|
||||
err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{targetAttribName}";
|
||||
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
var attribute_names = DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, targetAttribName);
|
||||
query_builder.withExpressionAttributeNames(attribute_names);
|
||||
|
||||
var update_expression = $"SET {attribute_expression} = :changeValue";
|
||||
query_builder.withUpdateExpression(update_expression);
|
||||
|
||||
var expression_attribute_values = new Dictionary<string, AttributeValue>
|
||||
{
|
||||
{ ":changeValue", new AttributeValue { S = m_sync_date.toString("yyyy-MM-ddTHH:mm:ss") } }
|
||||
};
|
||||
query_builder.withExpressionAttributeValues(expression_attribute_values);
|
||||
|
||||
query_builder.withReturnValues(ReturnValue.ALL_NEW);
|
||||
|
||||
return query_builder.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
using System.Globalization;
|
||||
|
||||
|
||||
using Amazon.DynamoDBv2;
|
||||
using Amazon.DynamoDBv2.Model;
|
||||
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
using ServerCommon;
|
||||
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public enum CaliumStorageType
|
||||
{
|
||||
None = 0,
|
||||
Converter = 1,
|
||||
Operator = 2
|
||||
}
|
||||
|
||||
public class DBQStorageCaliumUpdate : QueryExecutorBase
|
||||
{
|
||||
private CaliumStorageType m_storage_type { get; set; } = CaliumStorageType.None;
|
||||
private double m_delta { get; set; }
|
||||
private bool m_is_update_last_date { get; set; }
|
||||
private bool m_is_pivot { get; set; }
|
||||
|
||||
private PrimaryKey m_primary_key = new();
|
||||
|
||||
//=====================================================================================
|
||||
// 0 < deltaCount => 증가
|
||||
// 0 > deltaCount => 감소
|
||||
//=====================================================================================
|
||||
|
||||
public DBQStorageCaliumUpdate(CaliumStorageType storageType, double deltaCalium, bool isUpdateLastDate = false, bool isPivot = false) : base(nameof(DBQStorageCaliumUpdate))
|
||||
{
|
||||
m_storage_type = storageType;
|
||||
m_delta = deltaCalium;
|
||||
m_is_update_last_date = isUpdateLastDate;
|
||||
m_is_pivot = isPivot;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// DB 쿼리 직전에 준비해야 할 로직들을 작성한다.
|
||||
//=====================================================================================
|
||||
public override async Task<Result> onPrepareQuery()
|
||||
{
|
||||
var owner = getOwner();
|
||||
|
||||
var (result, make_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey<CaliumStorageDoc>(string.Empty);
|
||||
if (result.isFail())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
NullReferenceCheckHelper.throwIfNull(make_primary_key, () => $"make_primary_key is null !!! - {owner.toBasicString()}");
|
||||
|
||||
m_primary_key = make_primary_key;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// onPrepareQuery()를 성공할 경우 호출된다.
|
||||
//=====================================================================================
|
||||
public override async Task<Result> onQuery()
|
||||
{
|
||||
var owner = getOwner();
|
||||
|
||||
var query_batch = getQueryBatch() as QueryBatch<QueryRunnerWithItemRequest>;
|
||||
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var query_runner_with_item_request = query_batch.getQueryRunner();
|
||||
NullReferenceCheckHelper.throwIfNull(query_runner_with_item_request, () => $"query_runner_with_item_request is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var db_connector = query_batch.getDynamoDbConnector();
|
||||
var update = makeUpdateItemRequestChangeConverterTotalCalium(db_connector, m_primary_key.toKeyWithAttributeValue(), convertCaliumStorageTypeToValueName());
|
||||
if (update.result.isFail()) return update.result;
|
||||
NullReferenceCheckHelper.throwIfNull(update.updateRequest, () => $"update_request is null !!! - {owner.toBasicString()}");
|
||||
|
||||
var exception_handler = new DynamoDbQueryExceptionNotifier.ExceptionHandler(DynamoDbQueryExceptionNotifier.ConditionalCheckFailed, ServerErrorCode.LackOfTotalCalium);
|
||||
|
||||
var query_context = update.updateRequest.createItemRequestQueryContext(QueryType.Update, exception_handler);
|
||||
var result = await query_runner_with_item_request.tryRegisterQueryContext(query_context);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// DB 쿼리를 성공하고, doFnCommit()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
|
||||
//=====================================================================================
|
||||
public override async Task onQueryResponseCommit()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
// DB 쿼리를 실패하고, doFnRollback()가 QueryResultType.NotCalledQueryFunc를 반환할 경우 호출된다.
|
||||
//=====================================================================================
|
||||
public override async Task onQueryResponseRollback(Result errorResult)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
private string convertCaliumStorageTypeToValueName()
|
||||
{
|
||||
return m_storage_type switch
|
||||
{
|
||||
CaliumStorageType.Converter => JsonHelper.getJsonPropertyName<CaliumConverterInfo>(nameof(CaliumConverterInfo.TotalCalium)),
|
||||
CaliumStorageType.Operator => JsonHelper.getJsonPropertyName<CaliumOperatorInfo>(nameof(CaliumOperatorInfo.TotalCalium)),
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
private (Result result, UpdateItemRequest? updateRequest) makeUpdateItemRequestChangeConverterTotalCalium( DynamoDbClient dbClient
|
||||
, Dictionary<string, AttributeValue> attributeValueWithPrimaryKey
|
||||
, string targetAttribName )
|
||||
{
|
||||
var result = new Result();
|
||||
string err_msg;
|
||||
|
||||
if (string.IsNullOrEmpty(targetAttribName))
|
||||
{
|
||||
err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : targetAttribName - {targetAttribName}";
|
||||
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
var target_doc = new CaliumStorageDoc();
|
||||
|
||||
var query_builder = new DynamoDbItemRequestHelper.UpdateItemRequestBuilder(dbClient.getTableFullName(target_doc.TableName));
|
||||
query_builder.withKeys(attributeValueWithPrimaryKey);
|
||||
|
||||
var attrib_path_json_string = target_doc.toJsonStringOfAttribs();
|
||||
(var is_success, var attribute_expression) = DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, targetAttribName);
|
||||
if (false == is_success)
|
||||
{
|
||||
err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{targetAttribName}";
|
||||
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return (result, null);
|
||||
}
|
||||
|
||||
var attribute_names = DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, targetAttribName);
|
||||
query_builder.withExpressionAttributeNames(attribute_names);
|
||||
|
||||
var update_expression = (m_delta >= 0)
|
||||
? $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) + :changeValue"
|
||||
: $"SET {attribute_expression} = if_not_exists({attribute_expression}, :start) - :changeValue";
|
||||
|
||||
query_builder.withUpdateExpression(update_expression);
|
||||
|
||||
// 차감시 조건 추가
|
||||
if (m_delta < 0)
|
||||
{
|
||||
query_builder.withConditionExpression($"{attribute_expression} >= :changeValue");
|
||||
}
|
||||
|
||||
var expression_attribute_values = new Dictionary<string, AttributeValue>
|
||||
{
|
||||
{ ":changeValue", new AttributeValue { N = Math.Abs(m_delta).ToString(CultureInfo.InvariantCulture) } },
|
||||
{ ":start", new AttributeValue { N = "0" } }
|
||||
};
|
||||
query_builder.withExpressionAttributeValues(expression_attribute_values);
|
||||
|
||||
// 마지막 업데이트 날짜 수정
|
||||
if (m_is_update_last_date)
|
||||
{
|
||||
result = updateLastDate(query_builder, attrib_path_json_string);
|
||||
if (result.isFail()) return (result, null);
|
||||
}
|
||||
|
||||
query_builder.withReturnValues(ReturnValue.ALL_NEW);
|
||||
|
||||
return query_builder.build();
|
||||
}
|
||||
|
||||
private Result updateLastDate(DynamoDbItemRequestHelper.UpdateItemRequestBuilder query_builder, string attrib_path_json_string)
|
||||
{
|
||||
var result = new Result();
|
||||
|
||||
var request = query_builder.getItemRequest();
|
||||
var attribute_last_date = JsonHelper.getJsonPropertyName<CaliumConverterInfo>(nameof(CaliumConverterInfo.LastFillUpDate));
|
||||
|
||||
// 1. add attribute names
|
||||
var attribute_last_date_names = DynamoDbClientHelper.toExpressionAttributeNamesFromJson(attrib_path_json_string, attribute_last_date);
|
||||
foreach (var name in attribute_last_date_names.Where(name => !request.ExpressionAttributeNames.ContainsKey(name.Key)))
|
||||
{
|
||||
request.ExpressionAttributeNames.Add(name.Key, name.Value);
|
||||
}
|
||||
|
||||
// 2. add attribute expression
|
||||
var (is_success, last_date_expression) = DynamoDbClientHelper.toAttributeExpressionFromJson(attrib_path_json_string, attribute_last_date);
|
||||
if (false == is_success)
|
||||
{
|
||||
var err_msg = $"Failed to DynamoDbClientHelper.toAttributeExpressionFromJson() !!! : attribPath:{attrib_path_json_string}, targetKey:{attribute_last_date}";
|
||||
result.setFail(ServerErrorCode.AttribPathMakeFailed, err_msg);
|
||||
Log.getLogger().error(result.toBasicString());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
request.UpdateExpression += ", ";
|
||||
request.UpdateExpression += $"{last_date_expression} = :lastDateValue";
|
||||
|
||||
// 3. add values
|
||||
request.ExpressionAttributeValues.Add(":lastDateValue", new AttributeValue { S = DateTimeHelper.Current.toString("yyyy-MM-ddTHH:mm:ss")});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
|
||||
using ServerCore;
|
||||
using ServerBase;
|
||||
using ServerCommon;
|
||||
using ServerCommon.BusinessLogDomain;
|
||||
using MetaAssets;
|
||||
|
||||
|
||||
namespace GameServer;
|
||||
|
||||
public class ReqCreateCaliumContentStorageHandler
|
||||
{
|
||||
public async Task<Result> createCaliumContentStorage(string contentId, double calium)
|
||||
{
|
||||
var server_logic = GameServerApp.getServerLogic();
|
||||
var calium_storage_entity = server_logic.findGlobalEntity<CaliumStorageEntity>();
|
||||
NullReferenceCheckHelper.throwIfNull(calium_storage_entity, () => "calium_storage_entity is null !!!");
|
||||
|
||||
// 1. contentId 검사
|
||||
// Todo(sangyeob.kim) : calium content Id 를 위한 xlxs 등록되면 추가한다.
|
||||
|
||||
// 2. calium content storage 생성
|
||||
var result = await calium_storage_entity.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "CreateCaliumContentStorage", createCaliumContentStorageDelegate);
|
||||
if (result.isFail())
|
||||
{
|
||||
var err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {calium_storage_entity.toBasicString()}";
|
||||
Log.getLogger().error(err_msg);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
async Task<Result> createCaliumContentStorageDelegate() => await createCaliumContentStorage(calium_storage_entity, contentId, calium);
|
||||
}
|
||||
|
||||
private async Task<Result> createCaliumContentStorage(CaliumStorageEntity caliumStorageEntity, string contentId, double calium)
|
||||
{
|
||||
var dynamoDb_client = GameServerApp.getServerLogic().getDynamoDbClient();
|
||||
NullReferenceCheckHelper.throwIfNull(dynamoDb_client, () => $"dynamoDb_client is null !!! - {caliumStorageEntity.toBasicString()}");
|
||||
|
||||
var batch = new QueryBatchEx<QueryRunnerWithItemRequest>(caliumStorageEntity, LogActionType.CreateCaliumContent, dynamoDb_client, true);
|
||||
batch.addQuery(new DBQStorageCaliumUpdate(CaliumStorageType.Operator, -1 * calium));
|
||||
batch.addQuery(new DBQContentCaliumCreate(contentId, calium));
|
||||
|
||||
var result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user