using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Amazon.S3.Model; using Amazon.DynamoDBv2.Model; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.Cache; using MetaAssets; using ServerControlCenter; using static ServerCommon.MetaHelper; using static GameServer.LandAuctionDbHelper; using META_ID = System.UInt32; using LAND_AUCTION_NUMBER = System.Int32; using Microsoft.AspNetCore.Mvc; namespace GameServer { public class LandAuctionRefundBidPriceAction : EntityActionBase { private bool m_is_deletable = false; public LandAuctionRefundBidPriceAction(LandAuctionRefundBidPrice owner) : base(owner) { } public override Task onInit() { var result = new Result(); return Task.FromResult(result); } public override void onClear() { } public Result tryLoadRefundBidPriceFromDoc(LandAuctionRefundBidPriceDoc doc) { var owner = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var player = owner.getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var result = new Result(); var err_msg = string.Empty; var refund_bid_price_attribute = owner.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(refund_bid_price_attribute, () => $"refund_bid_price_attribute is null !!! - {player.toBasicString()}"); if(false == refund_bid_price_attribute.copyEntityAttributeFromDoc(doc)) { err_msg = $"Failed to copyEntityAttributeFromDoc !!! : docType:{doc.getTypeName()} - {player.toBasicString()}"; result.setFail(ServerErrorCode.DynamoDbDocCopyToEntityAttributeFailed, err_msg); Log.getLogger().error(err_msg); return result; } return result; } public async Task tryUpdateRefundBidPrice() { var owner = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var player = owner.getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var redis_connector = server_logic.getRedisDb(); var result = new Result(); var err_msg = string.Empty; ( result , var is_sucess , var auction_result , var refundable_normal_bid_price, var refundable_blind_bid_price) = await checkRefundableNow(); if(result.isFail()) { return result; } if (true == is_sucess) { err_msg = $"Success to checkRefundableNow() !!!, AuctionResult:{auction_result}" + $", refundableNormalBidAmount:{refundable_normal_bid_price}, refundableBlindBidAmount:{refundable_blind_bid_price}" + $" : {owner.toBasicString()} - {player.toBasicString()}"; Log.getLogger().debug(err_msg); result = await refundLandAuctionBidPrice(auction_result, refundable_normal_bid_price, refundable_blind_bid_price); if (result.isFail()) { err_msg = $"Failed to refundLandAuctionBidPrice() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); } } result = await deleteRefundBidPrice(auction_result); if (result.isFail()) { err_msg = $"Failed to deleteRefundBidPrice() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return result; } return result; } private async Task<(Result, bool, LandAuctionResult, double, double)> checkRefundableNow() { var refund_bid_price = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(refund_bid_price, () => $"refund_bid_price is null !!!"); var player = refund_bid_price.getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var result = new Result(); var err_msg = string.Empty; var server_logic = GameServerApp.getServerLogic(); var redis_connector = server_logic.getRedisConnector(); var refund_bid_price_attribute = refund_bid_price.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(refund_bid_price_attribute, () => $"refund_bid_price_attribute is null !!! - {refund_bid_price.toBasicString()}"); var user_guid = player.getUserGuid(); var land_meta_id = refund_bid_price_attribute.LandMetaId; var auction_number = refund_bid_price_attribute.AuctionNumber; //===================================================================================== // 1. 입찰금 정보를 읽는다. (항상 Db 에서 읽어오고 판단 !!!) //===================================================================================== (result, var refund_bid_price_doc) = await LandAuctionDbHelper.readLandAuctionRefundBidPriceDocFromDb(player, land_meta_id, auction_number); if (result.isFail()) { err_msg = $"Failed to readLandAuctionRefundBidPriceDocFromDb() !!! : {result.toBasicString()}, {refund_bid_price.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, false, LandAuctionResult.None, 0, 0); } NullReferenceCheckHelper.throwIfNull(refund_bid_price_doc, () => $"refund_bid_price_doc is null !!! - {refund_bid_price.toBasicString()}"); var refund_bid_price_attrib = refund_bid_price_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(refund_bid_price_attrib, () => $"refund_bid_price_attrib is null !!! - {refund_bid_price.toBasicString()}"); result = refund_bid_price.copyDocToEntityAttributeForRefundBidPrice(refund_bid_price_attribute, refund_bid_price_doc); if (result.isFail()) { err_msg = $"Failed to copyDocToEntityAttributeForRefundBidPrice() !!! : {result.toBasicString()}, docType:{refund_bid_price_doc.getTypeName()}, {refund_bid_price.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, false, LandAuctionResult.None, 0, 0); } //===================================================================================== // 2. 랜드 경매 결과를 확인 한다. (Cache => Db) //===================================================================================== var auction_result = LandAuctionResult.None; var land_auction_cache_request = new LandAuctionCacheRequest(land_meta_id, redis_connector); var redis_result = await land_auction_cache_request.fetchLandAuction(); if (redis_result.isFail()) { err_msg = $"Failed to fetchLandAuction() !!!, duplicated SK !!! : {redis_result.toBasicString()} - {refund_bid_price.toBasicString()}, {player.toBasicString()}"; Log.getLogger().error(err_msg); } var land_auction_cache = land_auction_cache_request.getLandAuctionCache(); if (null == land_auction_cache) { (result, var found_registry_doc) = await LandAuctionDbHelper.readLandAuctionRegistryDocFromDb(land_meta_id, auction_number); if (result.isFail()) { err_msg = $"Failed to readLandAuctionRegistryDocFromDb() !!! : {result.toBasicString()} - {refund_bid_price.toBasicString()}, {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, false, LandAuctionResult.None, 0, 0); } NullReferenceCheckHelper.throwIfNull(found_registry_doc, () => $"found_registry_doc is null !!! - {refund_bid_price.toBasicString()}"); var registry_attrib = found_registry_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(registry_attrib, () => $"registry_attrib is null !!! - {refund_bid_price.toBasicString()}"); if (LandAuctionResult.None != registry_attrib.LandAuctionResult) { auction_result = registry_attrib.LandAuctionResult; err_msg = $"LandAuctionResult:{auction_result} <= LandAuctionRegistryDoc from DB, in checkRefundableNow() : {refund_bid_price.toBasicString()} - {player.toBasicString()}"; Log.getLogger().debug(err_msg); } } else { if (LandAuctionResult.None != land_auction_cache.LandAuctionResult) { auction_result = land_auction_cache.LandAuctionResult; err_msg = $"LandAuctionResult:{auction_result} <= LandAuctionCache from Cache, in checkRefundableNow() : {refund_bid_price.toBasicString()} - {player.toBasicString()}"; Log.getLogger().debug(err_msg); } } //===================================================================================== // 3. 최고 입찰자 정보를 얻는다. //===================================================================================== (result, var found_highest_bid_user_doc) = await LandAuctionDbHelper.readLandAuctionHighestBidUserDocFromDb(land_meta_id, auction_number); if (result.isFail()) { err_msg = $"Failed to readLandAuctionHighestBidUserDocFromDb() !!! : {result.toBasicString()} - {refund_bid_price.toBasicString()}"; Log.getLogger().error(err_msg); return (result, false, LandAuctionResult.None, 0, 0); } NullReferenceCheckHelper.throwIfNull(found_highest_bid_user_doc, () => $"found_highest_bid_user_doc is null !!! - landMetaId:{land_meta_id}, auctionNumber:{auction_number}"); var highest_bid_user_attrib = found_highest_bid_user_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(highest_bid_user_attrib, () => $"highest_bid_user_attrib is null !!! - landMetaId:{land_meta_id}, auctionNumber:{auction_number}"); var bid_type = refund_bid_price_attrib.LastBidType; double deductible_bid_amount = 0; // 현재 내가 최고 입찰자인 경우 if (highest_bid_user_attrib.HighestBidUserGuid == user_guid) { // 환급 입찰금에서 차감해야 하는 금전량 deductible_bid_amount = refund_bid_price_attrib.LastBidPrice; } //===================================================================================== // 4. 랜드 경매 결과 상태를 확인 및 환급 입찰금에서 차감액을 차감 한다. //===================================================================================== double refundable_normal_bid_price = 0; double refundable_blind_bid_price = 0; if (LandAuctionResult.None != auction_result) { refundable_normal_bid_price = refund_bid_price_attribute.RefundableNormalBidPrice; refundable_blind_bid_price = refund_bid_price_attribute.RefundableBlindBidPrice; if (LandAuctionBidType.Normal == bid_type) { refundable_normal_bid_price = refundable_normal_bid_price - deductible_bid_amount; refundable_normal_bid_price = MathHelper.min(double.MaxValue, refundable_normal_bid_price); refundable_normal_bid_price = MathHelper.max(double.MinValue, refundable_normal_bid_price); } else if (LandAuctionBidType.Blind == bid_type) { refundable_blind_bid_price = refundable_blind_bid_price - deductible_bid_amount; refundable_blind_bid_price = MathHelper.min(double.MaxValue, refundable_blind_bid_price); refundable_blind_bid_price = MathHelper.max(double.MinValue, refundable_blind_bid_price); } if(0 < refundable_normal_bid_price || 0 < refundable_blind_bid_price) { return (result, true, auction_result, refundable_normal_bid_price, refundable_blind_bid_price); } } // 랜드 경매가 진행중 !!! else { // LandAuctionBidType.Normal 환급 입찰금은 언제든지 환급 가능하다 !!! if (0 < refund_bid_price_attribute.RefundableNormalBidPrice) { err_msg = $"Refundable normal Bid Price !!!, in checkRefundableNow() : auctionResult:{auction_result}, {refund_bid_price.toBasicString()} - {player.toBasicString()}"; Log.getLogger().debug(err_msg); if (LandAuctionBidType.Normal == bid_type) { refundable_normal_bid_price = refund_bid_price_attribute.RefundableNormalBidPrice - deductible_bid_amount; refundable_normal_bid_price = MathHelper.min(double.MaxValue, refundable_normal_bid_price); refundable_normal_bid_price = MathHelper.max(double.MinValue, refundable_normal_bid_price); } if(0 < refundable_normal_bid_price) { return (result, true, auction_result, refundable_normal_bid_price, 0); } } } // 환급이 불가능 하다 !!! return (result, false, auction_result, 0, 0); } private async Task deleteRefundBidPrice(LandAuctionResult auctionResult) { var refund_bid_price = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(refund_bid_price, () => $"refund_bid_price is null !!!"); var player = refund_bid_price.getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var db_connector = server_logic.getDynamoDbClient(); var result = new Result(); var err_msg = string.Empty; var refund_bid_price_attribute = refund_bid_price.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(refund_bid_price_attribute, () => $"refund_bid_price_attribute is null !!! - {refund_bid_price.toBasicString()}"); var land_meta_id = refund_bid_price_attribute.LandMetaId; var auction_number = refund_bid_price_attribute.AuctionNumber; (result, var refund_bid_price_doc) = await LandAuctionDbHelper.readLandAuctionRefundBidPriceDocFromDb(player, land_meta_id, auction_number); if (result.isFail()) { err_msg = $"Failed to readLandAuctionRefundBidPriceDocFromDb() !!! : {result.toBasicString()}, {refund_bid_price.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return result; } NullReferenceCheckHelper.throwIfNull(refund_bid_price_doc, () => $"refund_bid_price_doc is null !!! - {refund_bid_price.toBasicString()}"); var refund_bid_price_attrib = refund_bid_price_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(refund_bid_price_attrib, () => $"refund_bid_price_attrib is null !!! - {refund_bid_price.toBasicString()}"); result = refund_bid_price.copyDocToEntityAttributeForRefundBidPrice(refund_bid_price_attribute, refund_bid_price_doc); if (result.isFail()) { err_msg = $"Failed to copyDocToEntityAttributeForRefundBidPrice() !!! : {result.toBasicString()}, docType:{refund_bid_price_doc.getTypeName()} - {refund_bid_price.toBasicString()}, {player.toBasicString()}"; Log.getLogger().error(err_msg); return result; } var is_delete = false; if(LandAuctionResult.None != auctionResult) { if ( 0 >= ( LandAuctionBidType.Normal == refund_bid_price_attrib.LastBidType ? refund_bid_price_attrib.RefundableNormalBidPrice - refund_bid_price_attrib.LastBidPrice : refund_bid_price_attrib.RefundableNormalBidPrice ) && 0 >= ( LandAuctionBidType.Blind == refund_bid_price_attrib.LastBidType ? refund_bid_price_attrib.RefundableBlindBidPrice - refund_bid_price_attrib.LastBidPrice : refund_bid_price_attrib.RefundableBlindBidPrice ) ) { is_delete = true; } } if(true == is_delete) { result = await db_connector.simpleDeleteDocumentWithDocType(refund_bid_price_doc); if (result.isFail()) { err_msg = $"Failed to simpleDeleteDocumentWithDocType() !!! : {result.toBasicString()} - {refund_bid_price.toBasicString()}, {player.toBasicString()}"; Log.getLogger().error(err_msg); return result; } setDeletable(); } return result; } private async Task refundLandAuctionBidPrice( LandAuctionResult auctionResult , double refundableNormalBidPrice, double refundableBlindBidPrice) { var owner = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var player = owner.getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var redis_connector = server_logic.getRedisDb(); var result = new Result(); var err_msg = string.Empty; var new_mail_docs = new List(); DynamoDbItemRequestQueryContext? item_request_query_context = null; err_msg = $"Try LandAuction refund Bid Price : LandAuctionResult:{auctionResult}, {owner.toSummaryString()} - {player.toBasicString()}"; Log.getLogger().debug(err_msg); if (LandAuctionResult.Canceled == auctionResult) { (result, var to_add_mail_docs, var query_context) = await createMailWithBidPriceByAuctionCancel( refundableNormalBidPrice, refundableBlindBidPrice ); if (result.isFail()) { err_msg = $"Failed to createMailWithBidPriceByAuctionCancel() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return result; } new_mail_docs = to_add_mail_docs; item_request_query_context = query_context; } else { (result, var to_add_mail_docs, var query_context) = await createMailWithRefundedBidPrice( auctionResult , refundableNormalBidPrice, refundableBlindBidPrice ); if (result.isFail()) { err_msg = $"Failed to createMailWithRefundedBidPrice() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return result; } new_mail_docs = to_add_mail_docs; item_request_query_context = query_context; } var batch = new QueryBatchEx( player, LogActionType.LandAuctionBidPriceRefund , server_logic.getDynamoDbClient() , true ); { if (null != new_mail_docs) { batch.addQuery(new DBQEntityWrite(new_mail_docs)); } if (null != item_request_query_context) { batch.addQuery(new DBQWithItemRequestQueryContext(item_request_query_context)); } batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); batch.addQuery(new QueryFinal(), async (_query) => { await completedRefundBidPrice(auctionResult, _query); if (null != new_mail_docs && 0 < new_mail_docs.Count) { var found_user_mail_action = player.getEntityAction(); found_user_mail_action.NewReceivedMail(); foreach(var new_mail_doc in new_mail_docs) { err_msg = $"New Received Mail : {new_mail_doc.toAttribAllString()}, {owner.toSummaryString()} - {player.toBasicString()}"; Log.getLogger().debug(err_msg); } } err_msg = $"Completed refund Bid Price of LandAuction : LandAuctionResult:{auctionResult}, {owner.toSummaryString()} - {player.toBasicString()}"; Log.getLogger().debug(err_msg); return QueryBatchBase.QueryResultType.Success; }); } result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { return result; } return result; } private async Task completedRefundBidPrice(LandAuctionResult auctionResult, QueryExecutorBase queryExecutorBase) { await Task.CompletedTask; var refund_bid_price = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(refund_bid_price, () => $"refund_bid_price is null !!!"); var player = refund_bid_price.getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var bid_price_attribute = refund_bid_price.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(bid_price_attribute, () => $"bid_price_attribute is null !!! - {player.toBasicString()}"); var origin_bid_price_attribute = refund_bid_price.getOriginEntityAttribute(); NullReferenceCheckHelper.throwIfNull(origin_bid_price_attribute, () => $"origin_bid_price_attribute is null !!! - {player.toBasicString()}"); var result = new Result(); var err_msg = string.Empty; result = origin_bid_price_attribute.copyFromOtherEntityAttribute(bid_price_attribute); if(result.isFail()) { err_msg = $"Failed to copyFromOtherEntityAttribute() : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(result.toBasicString()); } LandAuctionBusinessLogHelper.writeBusinessLogByLandAuctionBidPriceRefund(refund_bid_price, auctionResult, queryExecutorBase); } public async Task<(Result, List?, DynamoDbItemRequestQueryContext?)> createMailWithRefundedBidPrice( LandAuctionResult auctionResult , double refundableNormalBidPrice, double refundableBlindBidPrice) { var refund_bid_price = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(refund_bid_price, () => $"refund_bid_price is null !!!"); var player = refund_bid_price.getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); ConditionValidCheckHelper.throwIfFalseWithCondition( () => LandAuctionResult.Canceled != auctionResult , () => $"Invalid LandAuctionResult !!! : LandAuctionResult.Canceled != {auctionResult} - {player.toBasicString()}"); var server_logic = GameServerApp.getServerLogic(); var db_connector = server_logic.getDynamoDbClient(); var redis_connector = server_logic.getRedisDb(); var result = new Result(); var err_msg = string.Empty; var user_land_auction_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(user_land_auction_action, () => $"user_land_auction_action is null !!! - {refund_bid_price.toBasicString()}"); var bid_price_attribute = refund_bid_price.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(bid_price_attribute, () => $"bid_price_attribute is null !!! - {refund_bid_price.toBasicString()}"); var currency_type = bid_price_attribute.BidCurrencyType; if (MetaData.Instance._CurrencyMetaTableByCurrencyType.TryGetValue(currency_type, out var currencyMetaData) == false) { result.setFail(ServerErrorCode.CurrencyNotFoundData, err_msg); return (result, null, null); } var user_guid = player.getUserGuid(); var land_meta_id = bid_price_attribute.LandMetaId; var auction_number = bid_price_attribute.AuctionNumber; if (false == server_logic.getLandManager().tryGetLand((Int32)land_meta_id, out var found_land)) { err_msg = $"Not found Land !!! : landMetaId:{land_meta_id} - {refund_bid_price.toBasicString()}"; result.setFail(ServerErrorCode.LandNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } if (false == MetaData.Instance._LandTable.TryGetValue((Int32)land_meta_id, out var found_land_meta)) { err_msg = $"Failed to MetaData.TryGetValue() !!! : LandMetaId:{land_meta_id}"; result.setFail(ServerErrorCode.LandMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } var to_new_mail_docs = new List(); DynamoDbItemRequestQueryContext? item_request_query_context = null; var to_change_attrib_actions = new Dictionary(); var user_nickname = player.getUserNickname(); if (0 < refundableNormalBidPrice) { var system_mail_key = "LandAuctionBidReturn"; if (MetaData.Instance.SystemMailMetaData.TryGetValue(system_mail_key, out var systemMailMetaData) == false) { err_msg = $"Not found SystemMailMeta !!! : mailKey:{system_mail_key} - {refund_bid_price.toBasicString()}"; result.setFail(ServerErrorCode.SystemMailMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } var contents_arguments = new List(); contents_arguments.Add(found_land_meta.getStringKeyOfLandName()); contents_arguments.Add(user_nickname); var mail_items = new List() { new ServerCommon.MailItem() { ItemId = (META_ID)currencyMetaData.ItemId, Count = refundableNormalBidPrice } }; (result, var new_mail_doc) = await Mail.createSystemMailWithMeta( player.getUserGuid(), user_nickname, systemMailMetaData, contents_arguments , mail_items, GameConfigMeta.LandAuctionFailedMailPeriodMinutes ); if (result.isFail()) { err_msg = $"Failed to createSystemMailWithMeta() !!! : {result.toBasicString()} - {refund_bid_price.toBasicString()}"; Log.getLogger().info(err_msg); return (result, null, null); } NullReferenceCheckHelper.throwIfNull(new_mail_doc, () => $"new_mail_doc is null !!! : ne - {player.toBasicString()}"); to_new_mail_docs.Add(new_mail_doc); to_change_attrib_actions.Add( nameof(LandAuctionRefundBidPriceAttrib.RefundableNormalBidPrice) , new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Decrease , Value = new AttributeValue { N = refundableNormalBidPrice.ToString() } }); bid_price_attribute.RefundableNormalBidPrice -= refundableNormalBidPrice; } if (LandAuctionResult.None != auctionResult) { if (0 < refundableBlindBidPrice) { var system_mail_key = "LandAuctionBidReturn"; if (MetaData.Instance.SystemMailMetaData.TryGetValue(system_mail_key, out var systemMailMetaData) == false) { err_msg = $"Not found SystemMailMeta !!! : mailKey:{system_mail_key} - {refund_bid_price.toBasicString()}"; result.setFail(ServerErrorCode.SystemMailMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } var contens_arguments = new List(); contens_arguments.Add(found_land_meta.getStringKeyOfLandName()); contens_arguments.Add(user_nickname); var mail_items = new List() { new ServerCommon.MailItem() { ItemId = (META_ID)currencyMetaData.ItemId, Count = refundableBlindBidPrice } }; (result, var new_mail_doc) = await Mail.createSystemMailWithMeta(player.getUserGuid(), user_nickname, systemMailMetaData, contens_arguments , mail_items, GameConfigMeta.LandAuctionFailedMailPeriodMinutes); if (result.isFail()) { err_msg = $"Failed to createSystemMailWithMeta() !!! : {result.toBasicString()} - {refund_bid_price.toBasicString()}"; Log.getLogger().info(err_msg); return (result, null, null); } NullReferenceCheckHelper.throwIfNull(new_mail_doc, () => $"new_mail_doc is null !!! : ne - {player.toBasicString()}"); to_new_mail_docs.Add(new_mail_doc); to_change_attrib_actions.Add( nameof(LandAuctionRefundBidPriceAttrib.RefundableBlindBidPrice) , new DynamoDbItemRequestHelper.AttribAction{ ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Decrease , Value = new AttributeValue { N = refundableBlindBidPrice.ToString() } }); bid_price_attribute.RefundableBlindBidPrice -= refundableBlindBidPrice; } } if(0 < to_change_attrib_actions.Count) { var refund_bid_price_doc = new LandAuctionRefundBidPriceDoc(player.getUserGuid(), land_meta_id, auction_number); (result, var query_context) = DynamoDbItemRequestHelper.makeUpdateItemRequestWithDoc(refund_bid_price_doc, to_change_attrib_actions); if (result.isFail()) { return (result, null, null); } NullReferenceCheckHelper.throwIfNull(query_context, () => $"query_context is null !!!"); item_request_query_context = query_context; } return (result, to_new_mail_docs, item_request_query_context); } public async Task<(Result, List?, DynamoDbItemRequestQueryContext?)> createMailWithBidPriceByAuctionCancel(double refundableNormalBidPrice, double refundableBlindBidPrice) { var owner = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var player = owner.getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var db_connector = server_logic.getDynamoDbClient(); var redis_connector = server_logic.getRedisDb(); var result = new Result(); var err_msg = string.Empty; var user_land_auction_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(user_land_auction_action, () => $"user_land_auction_action is null !!! - {owner.toBasicString()}"); var bid_price_attribute = owner.getEntityAttributeWithReadOnly(); NullReferenceCheckHelper.throwIfNull(bid_price_attribute, () => $"bid_price_attribute is null !!! - {owner.toBasicString()}"); var currency_type = bid_price_attribute.BidCurrencyType; if (MetaData.Instance._CurrencyMetaTableByCurrencyType.TryGetValue(currency_type, out var currencyMetaData) == false) { result.setFail(ServerErrorCode.CurrencyNotFoundData, err_msg); return (result, null, null); } var land_meta_id = bid_price_attribute.LandMetaId; var auction_number = bid_price_attribute.AuctionNumber; if (false == server_logic.getLandManager().tryGetLand((Int32)land_meta_id, out var found_land)) { err_msg = $"Not found Land !!! : landMetaId:{land_meta_id} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.LandNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } if (false == MetaData.Instance._LandTable.TryGetValue((Int32)land_meta_id, out var land_meta_data)) { err_msg = $"Failed to MetaData.TryGetValue() !!! : LandMetaId:{land_meta_id} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.LandMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, null, null); } var to_new_mail_docs = new List(); DynamoDbItemRequestQueryContext? item_request_query_context = null; var to_change_attrib_actions = new Dictionary(); var user_nickname = player.getUserNickname(); var user_guid = player.getUserGuid(); if (0 < refundableNormalBidPrice) { var system_mail_key = "LandAuctionBidReturn"; if (MetaData.Instance.SystemMailMetaData.TryGetValue(system_mail_key, out var systemMailMetaData) == false) { err_msg = $"Not found SystemMailMeta !!! : mailKey:{system_mail_key} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.SystemMailMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } var contens_arguments = new List(); contens_arguments.Add(land_meta_data.getStringKeyOfLandName()); contens_arguments.Add(user_nickname); var mail_items = new List() { new ServerCommon.MailItem() { ItemId = (META_ID)currencyMetaData.ItemId, Count = refundableNormalBidPrice } }; (result, var new_mail_doc) = await Mail.createSystemMailWithMeta( player.getUserGuid(), user_nickname, systemMailMetaData, contens_arguments , mail_items, GameConfigMeta.LandAuctionFailedMailPeriodMinutes ); if (result.isFail()) { err_msg = $"Failed to createSystemMailWithMeta() !!! : {result.toBasicString()} - {owner.toBasicString()}"; Log.getLogger().info(err_msg); return (result, null, null); } NullReferenceCheckHelper.throwIfNull(new_mail_doc, () => $"new_mail_doc is null !!! : ne - {player.toBasicString()}"); to_new_mail_docs.Add(new_mail_doc); to_change_attrib_actions.Add( nameof(LandAuctionRefundBidPriceAttrib.RefundableNormalBidPrice) , new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Decrease , Value = new AttributeValue { N = refundableNormalBidPrice.ToString() } } ); bid_price_attribute.RefundableNormalBidPrice = 0; } if (0 < refundableBlindBidPrice) { var system_mail_key = "LandAuctionHoldReturn"; if (MetaData.Instance.SystemMailMetaData.TryGetValue(system_mail_key, out var systemMailMetaData) == false) { err_msg = $"Not found SystemMailMeta !!! : mailKey:{system_mail_key} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.SystemMailMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } var mail_items = new List() { new ServerCommon.MailItem() { ItemId = (META_ID)currencyMetaData.ItemId, Count = refundableBlindBidPrice } }; (result, var new_mail_doc) = await Mail.createSystemMailWithMeta( player.getUserGuid(), user_nickname, systemMailMetaData , mail_items, GameConfigMeta.LandAuctionFailedMailPeriodMinutes ); if (result.isFail()) { err_msg = $"Failed to createSystemMailWithMeta() !!! : {result.toBasicString()} - {owner.toBasicString()}"; Log.getLogger().info(err_msg); return (result, null, null); } NullReferenceCheckHelper.throwIfNull(new_mail_doc, () => $"new_mail_doc is null !!! : ne - {player.toBasicString()}"); to_new_mail_docs.Add(new_mail_doc); to_change_attrib_actions.Add( nameof(LandAuctionRefundBidPriceAttrib.RefundableBlindBidPrice) , new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Decrease , Value = new AttributeValue { N = refundableBlindBidPrice.ToString() } }); bid_price_attribute.RefundableBlindBidPrice = 0; } if(0 < to_change_attrib_actions.Count) { var refund_bid_price_doc = new LandAuctionRefundBidPriceDoc(player.getUserGuid(), land_meta_id, auction_number); (result, var query_context) = DynamoDbItemRequestHelper.makeUpdateItemRequestWithDoc(refund_bid_price_doc, to_change_attrib_actions); if (result.isFail()) { return (result, null, null); } NullReferenceCheckHelper.throwIfNull(query_context, () => $"query_context is null !!!"); item_request_query_context = query_context; } return (result, to_new_mail_docs, item_request_query_context); } private void setDeletable() => m_is_deletable = true; public bool isDeletable() => m_is_deletable; public LAND_AUCTION_NUMBER getAuctionNumber() { var owner = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var bid_price_attribute = owner.getEntityAttributeWithReadOnly(); NullReferenceCheckHelper.throwIfNull(bid_price_attribute, () => $"bid_price_attribute is null !!! - {owner.toBasicString()}"); return bid_price_attribute.AuctionNumber; } public META_ID getLandMetaId() { var owner = getOwner() as LandAuctionRefundBidPrice; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var bid_price_attribute = owner.getEntityAttributeWithReadOnly(); NullReferenceCheckHelper.throwIfNull(bid_price_attribute, () => $"bid_price_attribute is null !!! - {owner.toBasicString()}"); return bid_price_attribute.LandMetaId; } } }