Files
caliverse_server/GameServer/Entity/LandAuction/Action/LandAuctionAction.cs
2025-05-01 07:20:41 +09:00

2443 lines
118 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Amazon.DynamoDBv2.Model;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
using META_ID = System.UInt32;
using LAND_AUCTION_NUMBER = System.Int32;
using REQUSTOR_ID = System.String;
using USER_GUID = System.String;
using USER_NICKNAME = System.String;
namespace GameServer;
/*=============================================================================================
# Land Auction 이벤트별 정보 흐름도
1. 경매 예약 하기
LandAuctionRegistryDoc 생성
2. 경매 활성화 하기
LandAuctionActivityDoc 생성 or 읽기 및 갱신
LandAuctionRegistryDoc 읽기 => Redis 읽기 => 경매 시작 or 종료 or 취소 호출
3. 경매 시작 하기
LandAuctionRegistryDoc 갱신 => Redis 갱신
5. 경매 종료 하기 (낙찰 & 유찰) + 운영 기능
LandAuctionRegistryDoc 갱신 => Redis 갱신
LandAuctionRecord 생성 or 갱신
6. 경매 취소 하기 + 운영 기능
LandAuctionRegistryDoc 읽기 => Redis 갱신
4. 경매 입찰 및 재입찰 하기
Redis 읽기 => LandAuctionRegistryDoc 읽기 => LandAuctionBidPriceDoc 생성 및 갱신 => LandAuctionHighestBidUserDoc 생성 및 갱신 => LandAuctionRegistryDoc 갱신 => Redis 갱신
//===========================================================================================*/
//=============================================================================================
// 랜드 경매 버전
//=============================================================================================
public class LandAuctionVersion
{
public DateTime RegisteredVersionTime { get; set; } = DateTimeHelper.MinTime;
public DateTime ProcessVersionTime { get; set; } = DateTimeHelper.MinTime;
public DateTime HighestRankVersionTime { get; set; } = DateTimeHelper.MinTime;
public bool IsSyncRequried { get; set; } = false; // 정보가 변경되어 동기화 필요 여부 (true : 동기화 대상, false: 동기화 필요 없음)
public LandAuctionVersion(DateTime registeredVersionTime, DateTime processVersionTime, DateTime highestVersionTime)
{
RegisteredVersionTime = registeredVersionTime;
ProcessVersionTime = processVersionTime;
HighestRankVersionTime = highestVersionTime;
}
public LandAuctionVersion()
{}
public void resetSyncRequried()
{
IsSyncRequried = false;
}
public string toBasicString() => $"LandAuctionVersion(RegisteredVersion:{RegisteredVersionTime}, ProcessVersion:{ProcessVersionTime}, HighestRankVersion:{HighestRankVersionTime})";
}
//=============================================================================================
// 랜드 경매 체크 결과
//=============================================================================================
public class LandAuctionCheckResult
{
public LandAuctionInfo LandAuctionInfo { get; set; } = new LandAuctionInfo();
public LandAuctionBidType LandAuctionBidType { get; set; } = LandAuctionBidType.None;
public CurrencyType MyBidCurrencyType { get; set; } = CurrencyType.None; // 직전 나의 입찰한 재화 종류 (일반 입찰은 최고가인 경우 or 블라인드 입찰에 참여한 경우)
public double MyBidPrice { get; set; } = 0; // 직전 나의 입찰가 (일반 입찰은 최고가인 경우 or 블라인드 입찰에 참여한 경우)
public LandAuctionVersion Version { get; set; } = new LandAuctionVersion();
}
//=============================================================================================
// 랜드 경매 입찰 결과
//=============================================================================================
public class LandAuctionBidResult
{
public LandAuction? TargetLandAuction { get; set; } = null;
public LandAuctionBidType CurrentBidType { get; set; } = LandAuctionBidType.None;
public DateTime BidTime { get; set; } = DateTimeHelper.MinTime;
public List<DynamoDbItemRequestQueryContext> ToUpsertItemRequestQueryContexts { get; set; } = new();
public LandAuctionTopBidderCache? CurrTopBidder { get; set; } = null;
public LandAuctionTopBidderCache? OldTopBidder { get; set; } = null;
}
//=============================================================================================
// 랜드 경매 낙찰 결과
//=============================================================================================
public class LandAuctionWinningResult
{
public USER_GUID WinningUserGuid { get; set; } = string.Empty;
public USER_NICKNAME WinningUserNickname { get; set; } = string.Empty;
public ReceivedMailDoc? ReceivedMailDoc { get; set; } = null;
}
public class LandAuctionAction : EntityActionBase
{
// 캐시 저장 단계
public enum CacheSaveStep
{
None,
Waiting, // 캐시 저장 대기중
Started, // 캐시 저장 시작
Completed, // 캐시 저장 완료
Failed // 캐시 저장 실패
}
// 공통
private DateTime m_land_auction_next_load_time = DateTimeHelper.MinTime;
// 랜드 경매 정보 관련
private LAND_AUCTION_NUMBER m_current_land_auction_number = 0;
private DateTime m_land_auction_last_loaded_time = DateTimeHelper.MinTime;
private CacheSaveStep m_cache_save_step = CacheSaveStep.None;
// 랜드 경매 마지막 완료 정보 (경매 & 최고 입찰)
private LandAuctionRegistryDoc? m_land_auction_registry_doc_for_record = null;
private LandAuctionHighestBidUserDoc? m_land_auction_highest_bid_user_doc_for_record = null;
private LandAuctionVersion? m_prev_version;
public LandAuctionAction(LandAuction owner)
: base(owner)
{
}
public override Task<Result> onInit()
{
var result = new Result();
return Task.FromResult(result);
}
public override void onClear()
{
}
public async Task<(Result, LandAuctionBidResult?)> tryBidLandAuction( LandAuctionCheckResult checkResult
, Player bidRequestor
, LandAuctionBidType reqBidType
, CurrencyType currencyType, double bidPrice )
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var db_connector = server_logic.getDynamoDbClient();
var result = new Result();
var err_msg = string.Empty;
var current_bid_type = toLandAuctionBidType();
if (current_bid_type != reqBidType)
{
err_msg = $"BidType has been changed !!! : reqBidType:{reqBidType} => currBidType:{current_bid_type} - {land_auction.toBasicString()}, {bidRequestor.toBasicString()}";
Log.getLogger().warn(err_msg);
reqBidType = current_bid_type;
}
( var is_success
, var curr_top_bidder, var old_top_bidder
, var is_db_upsert) = await land_auction.tryRankLandAuctionTopBidderCache(bidRequestor.getUserGuid(), bidPrice);
if (false == is_success)
{
err_msg = $"Failed to tryRankLandAuctionTopBidderCache() !!! - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.RedisSortedSetsReadFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
NullReferenceCheckHelper.throwIfNull(curr_top_bidder, () => $"curr_top_bidder is null !!! - {bidRequestor.toBasicString()}");
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!! - {bidRequestor.toBasicString()}");
var land_meta_id = checkResult.LandAuctionInfo.LandMetaId;
var auction_number = checkResult.LandAuctionInfo.AuctionNumber;
var bid_currency_type = checkResult.LandAuctionInfo.CurrencyType;
var bid_result = new LandAuctionBidResult();
bid_result.CurrentBidType = reqBidType;
bid_result.BidTime = DateTimeHelper.Current;
// 최고가 입찰자의 변경이 발생한 경우
if (true == is_db_upsert)
{
var highest_bid_user_nickname = string.Empty;
(result, var nickname_attrib) = await NicknameDoc.findNicknameFromGuid(curr_top_bidder.HighestBidUserGuid);
if (result.isSuccess())
{
NullReferenceCheckHelper.throwIfNull(nickname_attrib, () => $"nickname_attrib is null !!!");
highest_bid_user_nickname = nickname_attrib.Nickname;
}
var to_update_highest_bid_users = new Dictionary<string, DynamoDbItemRequestHelper.AttribAction>();
if (LandAuctionBidType.Normal == reqBidType)
{
to_update_highest_bid_users.Add(nameof(LandAuctionHighestBidUserAttrib.NormalHighestBidPrice)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Update
, Value = new AttributeValue { N = curr_top_bidder.HighestBidPrice.ToString() } });
to_update_highest_bid_users.Add(nameof(LandAuctionHighestBidUserAttrib.NormalHighestBidUserGuid)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Update
, Value = new AttributeValue { S = curr_top_bidder.HighestBidUserGuid } });
to_update_highest_bid_users.Add(nameof(LandAuctionHighestBidUserAttrib.NormalHighestBidUserNickname)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Update
, Value = new AttributeValue { S = highest_bid_user_nickname } });
}
to_update_highest_bid_users.Add(nameof(LandAuctionHighestBidUserAttrib.HighestBidPrice)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Update
, Value = new AttributeValue { N = curr_top_bidder.HighestBidPrice.ToString() } });
to_update_highest_bid_users.Add(nameof(LandAuctionHighestBidUserAttrib.HighestBidUserGuid)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Update
, Value = new AttributeValue { S = curr_top_bidder.HighestBidUserGuid } });
to_update_highest_bid_users.Add(nameof(LandAuctionHighestBidUserAttrib.HighestBidUserNickname)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Update
, Value = new AttributeValue { S = highest_bid_user_nickname } });
to_update_highest_bid_users.Add(nameof(LandAuctionHighestBidUserAttrib.HighestRankVersionTime)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Update
, Value = new AttributeValue { S = DateTimeHelper.Current.toStringWithUtcIso8601() } });
var highest_bid_user_doc = new LandAuctionHighestBidUserDoc((META_ID)land_meta_id, auction_number);
var highest_bid_exception_handler = new DynamoDbQueryExceptionNotifier.ExceptionHandler(DynamoDbQueryExceptionNotifier.ConditionalCheckFailed, ServerErrorCode.LandAuctionHighestBidUserAttribError);
(result, var highest_bid_user_item_query) = DynamoDbItemRequestHelper.makeUpdateItemRequestWithDoc<LandAuctionHighestBidUserAttrib>( highest_bid_user_doc
, to_update_highest_bid_users
, highest_bid_exception_handler );
if (result.isFail())
{
return (result, null);
}
NullReferenceCheckHelper.throwIfNull(highest_bid_user_item_query, () => $"highest_bid_user_item_query is null !!! - {land_auction.toBasicString()}, {bidRequestor.toBasicString()}");
bid_result.ToUpsertItemRequestQueryContexts.Add(highest_bid_user_item_query);
if (null != old_top_bidder)
{
var old_top_bid_user_guid = old_top_bidder.HighestBidUserGuid;
var old_top_bid_price = old_top_bidder.HighestBidPrice;
// 차순위로 변경된 최고 입찰자가 Db에 최고 입찰자로 되어 있는지 체크 (UserGuid, BidPrice) 한다.
(result, var is_exist_old_top_user) = await land_auction.isExistHighestBidderFromDb(old_top_bid_user_guid, old_top_bid_price);
if(result.isFail())
{
return (result, null);
}
if(true == is_exist_old_top_user)
{
bid_result.OldTopBidder = old_top_bidder;
}
}
}
bid_result.CurrTopBidder = curr_top_bidder;
// 입찰자의 입찰 정보를 업데이트 한다 !!!
{
var to_change_attrib_actions = new Dictionary<string, DynamoDbItemRequestHelper.AttribAction>();
// 마지막 입찰금 정보를 저장 한다.
to_change_attrib_actions.Add( nameof(LandAuctionRefundBidPriceAttrib.LastBidType)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Update
, Value = new AttributeValue { S = reqBidType.ToString() } });
to_change_attrib_actions.Add( nameof(LandAuctionRefundBidPriceAttrib.LastBidPrice)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Update
, Value = new AttributeValue { N = bidPrice.ToString() } });
// 입찰금을 환급금에 추가 한다.
if (LandAuctionBidType.Normal == reqBidType)
{
to_change_attrib_actions.Add( nameof(LandAuctionRefundBidPriceAttrib.RefundableNormalBidPrice)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Increase
, Value = new AttributeValue { N = bidPrice.ToString() } });
}
else if (LandAuctionBidType.Blind == reqBidType)
{
to_change_attrib_actions.Add(nameof(LandAuctionRefundBidPriceAttrib.RefundableBlindBidPrice)
, new DynamoDbItemRequestHelper.AttribAction { ValueAction = DynamoDbItemRequestHelper.AttribValueAction.Increase
, Value = new AttributeValue { N = bidPrice.ToString() } });
}
else
{
ConditionValidCheckHelper.throwIfFalseWithCondition( () => false
, () => $"Invalid BidType !!! : reqBidType:{reqBidType}"
+ $" - {land_auction.toBasicString()}");
}
var refund_bid_price_doc = new LandAuctionRefundBidPriceDoc(bidRequestor.getUserGuid(), (META_ID)land_meta_id, auction_number);
var refund_bid_exception_handler = new DynamoDbQueryExceptionNotifier.ExceptionHandler(DynamoDbQueryExceptionNotifier.ConditionalCheckFailed, ServerErrorCode.LandAuctionBidderRefundBidPriceAttribError);
(result, var refund_bid_price_query_context) = DynamoDbItemRequestHelper.makeUpdateItemRequestWithDoc<LandAuctionRefundBidPriceAttrib>( refund_bid_price_doc
, to_change_attrib_actions
, refund_bid_exception_handler );
if (result.isFail())
{
return (result, null);
}
NullReferenceCheckHelper.throwIfNull(refund_bid_price_query_context, () => $"refund_bid_price_query_context is null !!! - {land_auction.toBasicString()}, {bidRequestor.toBasicString()}");
bid_result.ToUpsertItemRequestQueryContexts.Add(refund_bid_price_query_context);
}
bid_result.TargetLandAuction = land_auction;
return (result, bid_result);
}
public async Task<Result> tryCheckLandAuction(META_ID landMetaId, REQUSTOR_ID requestorId, bool isLoadRequiredMeta)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!! - landMetaId:{landMetaId}, requestorId:{requestorId}");
var result = new Result();
var err_msg = string.Empty;
if (false == MetaData.Instance._LandTable.TryGetValue((Int32)landMetaId, out var land_meta_data))
{
err_msg = $"Failed to TryGetValue() !!! : landMetaId:{landMetaId} - requestorId:{requestorId}";
result.setFail(ServerErrorCode.LandMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (true == isLoadRequiredMeta)
{
result = await tryLoadLandAuctionMetaWithLock(landMetaId, ServerCommon.MetaHelper.GameConfigMeta.LandAuctionReloadIntervalSec);
if (result.isFail())
{
return result;
}
}
result = await tryRunLandAuction(requestorId);
if (result.isFail())
{
return result;
}
return result;
}
public async Task<(Result, LandAuctionCheckResult?)> tryCheckActivitingLandAuctionWithTransactionRunner(META_ID landMetaId, REQUSTOR_ID requestorId, bool isLoadRequiredMeta)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!! - landMetaId:{landMetaId}, requestorId:{requestorId}");
var result = new Result();
var err_msg = string.Empty;
if (true == isLoadRequiredMeta)
{
result = await tryLoadLandAuctionMetaWithLock(landMetaId, ServerCommon.MetaHelper.GameConfigMeta.LandAuctionReloadIntervalSec);
if (result.isFail())
{
return (result, null);
}
}
(result, var auction_check_result) = await tryRunLandAuctionWithRequestorTransactionRunner(requestorId);
if (result.isFail())
{
return (result, null);
}
return (result, auction_check_result);
}
public async Task<Result> completedCheckLandAuction( LandAuctionWinningResult? winningResult, OwnedLandHelper.OwnedLandOwnerChangedInfo? changedInfo
, REQUSTOR_ID requestorId
, QueryExecutorBase queryExecutorBase)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var query_batch = queryExecutorBase.getQueryBatch();
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {land_auction.toBasicString()}");
var trans_id = query_batch.getTransId();
var server_logic = GameServerApp.getServerLogic();
var db_client = server_logic.getDynamoDbClient();
var redis_connector = server_logic.getRedisConnector();
var result = new Result();
var err_msg = string.Empty;
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!! - {land_auction.toBasicString()}");
updateRegistryVersion(registry_attribute.RegisteredVersionTime, registry_attribute.ProcessVersionTime);
if (false == isSavableStepCache())
{
var is_success = await land_auction.tryReleaseWriteLockWithLandAuction(requestorId);
if (false == is_success)
{
err_msg = $"Failed to tryReleaseWriteLockWithLandAuction() !!! - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
}
return result;
}
var land_meta_id = registry_attribute.LandMetaId;
var auction_number = registry_attribute.AuctionNumber;
var auction_state = registry_attribute.LandAuctionState;
if (LandAuctionState.Waiting == auction_state)
{
// 랜드 경매 대기시 랭킹을 초기화 한다.
var bid_price_order_cache = new LandAuctionBidPriceOrderCacheRequest(land_meta_id, redis_connector);
await bid_price_order_cache.deleteBidPriceOrder();
var normal_bid_highest_user_cache_request = new LandAuctionNormalBidHighestUserCacheRequest(land_meta_id, redis_connector);
await normal_bid_highest_user_cache_request.deleteNormalBidHighestUser();
}
result = await land_auction.trySaveToCache(requestorId);
if (result.isFail())
{
return result;
}
var auction_result = registry_attribute.LandAuctionResult;
err_msg = $"LandAuction completed change LandAuctionState !!! : state:{registry_attribute.LandAuctionState}, result:{auction_result} - {land_auction.toBasicString()}";
Log.getLogger().debug(err_msg);
if (LandAuctionResult.Successed == auction_result)
{
var registry_doc = registry_attribute.getOriginDocBase<LandAuctionRegistryAttribute>() as LandAuctionRegistryDoc;
NullReferenceCheckHelper.throwIfNull(registry_doc, () => $"registry_doc is null !!! - {land_auction.toBasicString()}");
setLandAuctionRegistryDocForRecord(registry_doc);
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!! - {land_auction.toBasicString()}");
var highest_bid_user_doc = highest_bid_user_attribute.getOriginDocBase<LandAuctionHighestBidUserAttribute>() as LandAuctionHighestBidUserDoc;
NullReferenceCheckHelper.throwIfNull(highest_bid_user_doc, () => $"highest_bid_user_doc is null !!! - {land_auction.toBasicString()}");
setLandAuctionHighestBidUserDocForRecord(highest_bid_user_doc);
if ( null != winningResult
&& null != winningResult.ReceivedMailDoc )
{
var calium_storage_entity = server_logic.findGlobalEntity<CaliumStorageEntity>();
NullReferenceCheckHelper.throwIfNull(calium_storage_entity, () => $"calium_storage_entity is null !!! : {land_auction.toBasicString()}");
var calium_event_action = calium_storage_entity.getEntityAction<CaliumEventAction>();
NullReferenceCheckHelper.throwIfNull(calium_event_action, () => $"calium_event_action is null !!! : {land_auction.toBasicString()}");
var highest_bid_price = 0.0;
(result, var refund_bid_user_doc) = await LandAuctionDbHelper.readLandAuctionRefundBidPriceDocFromDb(winningResult.WinningUserGuid, land_meta_id, auction_number);
if(result.isFail())
{
err_msg = $"Failed to readLandAuctionRefundBidPriceDocFromDb() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().fatal(err_msg);
}
if(null == refund_bid_user_doc)
{
err_msg = $"refund_bid_user_doc is null !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
}
else
{
var refund_bid_price_attrib = refund_bid_user_doc.getAttrib<LandAuctionRefundBidPriceAttrib>();
NullReferenceCheckHelper.throwIfNull(refund_bid_price_attrib, () => $"refund_bid_price_attrib is null !!! : {land_auction.toBasicString()}");
highest_bid_price = refund_bid_price_attrib.LastBidPrice;
result = await calium_event_action.sendCaliumBurnEvent( server_logic
, trans_id, winningResult.WinningUserNickname
, "LandAuctionSuccess", highest_bid_price );
if (result.isFail())
{
err_msg = $"Failed to sendCaliumBurnEvent() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().fatal(err_msg);
}
}
NullReferenceCheckHelper.throwIfNull(changedInfo, () => $"changedInfo is null !!! - {land_auction.toBasicString()}");
(result, var land, var building) = changedInfo.applyChangedToOwnedLand();
if (result.isFail())
{
Log.getLogger().error($"Failed to applyChangedToOwnedLand() !!! : {result.toBasicString()} - {land_auction.toBasicString()}");
return result;
}
NullReferenceCheckHelper.throwIfNull(land, () => $"land is null !!! - {land_auction.toBasicString()}");
NullReferenceCheckHelper.throwIfNull(building, () => $"building is null !!! - {land_auction.toBasicString()}");
await LandNotifyHelper.sendNtfModifyLandInfo(land);
await BuildingNotifyHelper.sendNtfModifyBuildingInfo(building);
var building_info = await building.toBuildingInfo();
var building_meta_ids = new List<META_ID>() { (META_ID)building_info.BuildingMetaId };
err_msg = $"LandAuction Completed : state:{registry_attribute.LandAuctionState}, result:{auction_result}"
+ $", winningUserGuid:{winningResult.WinningUserGuid}, winningUserNickname:{winningResult.WinningUserNickname}, highestBidPrice:{highest_bid_price} - {land_auction.toBasicString()}";
Log.getLogger().debug(err_msg);
LandAuctionNotifyHelper.broadcast_GS2GS_NTF_LAND_AUCTION_WINNING_BID( winningResult.WinningUserGuid, winningResult.WinningUserNickname
, land_meta_id, building_meta_ids
, BoolType.True );
var land_log_info = land.toLandLogInfo();
var land_business_log = new LandBusinessLog(land_log_info);
var building_log_info = building.toBuildingLogInfo();
var building_business_log = new BuildingBusinessLog(building_log_info);
query_batch.appendBusinessLog(land_business_log);
query_batch.appendBusinessLog(building_business_log);
}
}
if (LandAuctionResult.None != auction_result)
{
LandAuctionBusinessLogHelper.writeBusinessLogByLandAuctionResult(land_auction, winningResult, queryExecutorBase);
// 관련 모든 캐시를 제거 한다.
var land_auction_cache = new LandAuctionCacheRequest(land_meta_id, redis_connector);
await land_auction_cache.deleteLandAuction();
var bid_price_order_cache = new LandAuctionBidPriceOrderCacheRequest(land_meta_id, redis_connector);
await bid_price_order_cache.deleteBidPriceOrder();
var normal_bid_highest_user_cache_request = new LandAuctionNormalBidHighestUserCacheRequest(land_meta_id, redis_connector);
await normal_bid_highest_user_cache_request.deleteNormalBidHighestUser();
// 랭킹 블록키도 제거 한다.
await land_auction.tryRemoveLandAuctionTopBidderBlockFromCache();
}
return result;
}
public async Task completedBidLandAuction( Player player, double reqBidPrice
, LandAuctionCheckResult checkResult, LandAuctionBidResult bidResult
, QueryExecutorBase queryExecutorBase )
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var redis_connector = server_logic.getRedisConnector();
var land_auction_info = checkResult.LandAuctionInfo;
NullReferenceCheckHelper.throwIfNull(land_auction_info, () => $"land_auction_info is null !!!");
var land_auction_action = land_auction.getEntityAction<LandAuctionAction>();
NullReferenceCheckHelper.throwIfNull(land_auction_action, () => $"land_auction_action is null");
var land_meta_id = land_auction_info.LandMetaId;
var auction_number = land_auction_info.AuctionNumber;
var result = new Result();
var err_msg = string.Empty;
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null");
// 2. 일반 입찰 최고가 정보를 DB 에서 읽는다.
(result, var found_highest_bid_user_doc) = await land_auction.tryGetLandAuctionHighestBidUserDoc((META_ID)land_meta_id, auction_number);
if (result.isSuccess())
{
if (null != found_highest_bid_user_doc)
{
result = await land_auction.copyDocToEntityAttributeForLandAuction(highest_bid_user_attribute, found_highest_bid_user_doc, true);
if (result.isFail())
{
err_msg = $"Failed to copyDocToEntityAttributeForLandAuction() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
}
}
}
// LandAuctionBidType.Normal 상태일 경우 Cache 한다 !!!
if (LandAuctionBidType.Normal == checkResult.LandAuctionBidType)
{
var normal_bid_highest_user_cache = new NormalBidHighestUserCache();
normal_bid_highest_user_cache.LandMetaId = (META_ID)land_meta_id;
normal_bid_highest_user_cache.AuctionNumber = auction_number;
normal_bid_highest_user_cache.NormalHighestBidPrice = highest_bid_user_attribute.NormalHighestBidPrice;
normal_bid_highest_user_cache.NormalHighestBidUserGuid = highest_bid_user_attribute.NormalHighestBidUserGuid;
normal_bid_highest_user_cache.NormalHighestBidUserNickname = highest_bid_user_attribute.NormalHighestBidUserNickname;
normal_bid_highest_user_cache.HighestRankVersionTime = highest_bid_user_attribute.HighestRankVersionTime;
var normal_bid_highest_user_cache_request = new LandAuctionNormalBidHighestUserCacheRequest(normal_bid_highest_user_cache, redis_connector);
result = await normal_bid_highest_user_cache_request.upsertNormalBidHighestUser(DateTimeHelper.toRemainingTimeMin(land_auction_info.AuctionEndTime.ToDateTime()));
if (result.isFail())
{
err_msg = $"Failed to upsertNormalBidHighestUser() !!! : {result.toBasicString()} - landMetaId:{land_meta_id}, auctionNumber:{auction_number}";
Log.getLogger().error(err_msg);
}
}
err_msg = $"LandAuction Bid Completed : bidType:{bidResult.CurrentBidType}, reqBidPrice:{reqBidPrice}"
+ $", {highest_bid_user_attribute.toBasicString()}, {land_auction.toBasicString()} - {player.toBasicString()}";
Log.getLogger().debug(err_msg);
LandAuctionBusinessLogHelper.writeBusinessLogByLandAuctionBid(land_auction, bidResult, queryExecutorBase);
land_auction_action.syncLandAuctionToClients(land_auction_info);
}
private void sendNoticeChat(USER_NICKNAME senderNickname, string message)
{
var server_logic = GameServerApp.getServerLogic();
var rabbit_mq_4_game = server_logic.getRabbitMqConnector() as RabbitMQ4Game;
NullReferenceCheckHelper.throwIfNull(rabbit_mq_4_game, () => $"rabbit_mq_4_game is null !!!");
rabbit_mq_4_game.sendChat(message, senderNickname, ChatType.Notice);
}
public async Task<Result> tryLoadLandAuctionMetaWithLock(META_ID landMetaId, double reloadIntervalSec = 0)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!! - landMetaId:{landMetaId}");
var server_logic = GameServerApp.getServerLogic();
var db_client = server_logic.getDynamoDbClient();
var result = new Result();
var err_msg = string.Empty;
// 1. 최신의 경매 정보를 얻어 온다.
var activity_attribute = land_auction.getEntityAttribute<LandAuctionActivityAttribute>();
NullReferenceCheckHelper.throwIfNull(activity_attribute, () => $"activity_attribute is null !!! - landMetaId:{landMetaId}");
var doc = activity_attribute.getOriginDocBase<LandAuctionActivityAttribute>();
if (null == doc)
{
// 1.1. Db 에서 활성화 경매 정보를 읽는다.
result = await land_auction.tryLoadLandAuctionActivityDoc(landMetaId);
if (result.isFail())
{
return result;
}
// 1.2. Db 에서 등록된 경매 정보를 읽는다.
result = await land_auction.tryLoadLandAuctionRegistryDoc(landMetaId, activity_attribute.AuctionNumber);
if (result.isFail())
{
return result;
}
// 1.3. Db 에서 최고가 입찰자 정보를 읽는다.
(result, _) = await land_auction.tryLoadLandAuctionHighestBidUserDoc(landMetaId, activity_attribute.AuctionNumber);
if (result.isFail())
{
return result;
}
}
else
{
using (var releaser = await land_auction.getAsyncLock())
{
err_msg = $"AsyncLock() Start - {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
// 1.2. Db 에서 등록된 경매 정보를 재로딩 시간 설정 만큼 경과 했다면 읽는다.
if (getLandAuctionLastLoadedTime() < DateTimeHelper.Current.AddSeconds(reloadIntervalSec))
{
// 1.2.1. Db 에서 활성화 경매 정보를 읽는다.
result = await land_auction.tryLoadLandAuctionActivityDoc(landMetaId);
if (result.isSuccess())
{
// 1.2.2. Db 에서 등록된 경매 정보를 읽는다.
result = await land_auction.tryLoadLandAuctionRegistryDoc(landMetaId, activity_attribute.AuctionNumber);
if (result.isSuccess())
{
setLandAuctionLastLoadedTime(DateTimeHelper.Current);
// 1.2.2. Db 에서 최고가 입찰자 정보를 읽는다.
await land_auction.tryLoadLandAuctionHighestBidUserDoc(landMetaId, activity_attribute.AuctionNumber);
}
}
}
err_msg = $"AsyncLock() End - {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
}
}
return result;
}
public async Task<Result> tryLoadLandAuctionMeta(META_ID landMetaId, double reloadIntervalSec = 0)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!! - landMetaId:{landMetaId}");
var server_logic = GameServerApp.getServerLogic();
var db_client = server_logic.getDynamoDbClient();
var result = new Result();
var err_msg = string.Empty;
// 1. 최신의 경매 정보를 얻어 온다.
var activity_attribute = land_auction.getEntityAttribute<LandAuctionActivityAttribute>();
NullReferenceCheckHelper.throwIfNull(activity_attribute, () => $"activity_attribute is null !!! - landMetaId:{landMetaId}");
// 1.2. Db 에서 등록된 경매 정보를 재로딩 시간 설정 만큼 경과 했다면 읽는다.
if (getLandAuctionLastLoadedTime() < DateTimeHelper.Current.AddSeconds(reloadIntervalSec))
{
// 1.2.1. Db 에서 활성화 경매 정보를 읽는다.
result = await land_auction.tryLoadLandAuctionActivityDoc(landMetaId);
if (result.isFail())
{
return result;
}
// 1.2.2. Db 에서 등록된 경매 정보를 읽는다.
result = await land_auction.tryLoadLandAuctionRegistryDoc(landMetaId, activity_attribute.AuctionNumber);
if (result.isFail())
{
return result;
}
setLandAuctionLastLoadedTime(DateTimeHelper.Current);
// 1.2.2. Db 에서 최고가 입찰자 정보를 읽는다.
(result, _) = await land_auction.tryLoadLandAuctionHighestBidUserDoc(landMetaId, activity_attribute.AuctionNumber);
if (result.isFail())
{
return result;
}
}
return result;
}
private async Task<Result> tryRunLandAuction(REQUSTOR_ID requestorId)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var redis_connector = server_logic.getRedisDb();
var result = new Result();
var err_msg = string.Empty;
var land_meta_id = getLandMetaId();
var auction_number = getAuctionNumber();
var auction_check_result = new LandAuctionCheckResult();
//=====================================================================================
// 랜드 경매 Write 권한 얻은 유저는 경매 진행 상태 및 버전 정보를 업데이트 할 수 있다 !!! - kangms
//=====================================================================================
if (false == isSyncRequired()
&& true == isLandAuctionState(LandAuctionState.Ended))
{
err_msg = $"Already LandAuctionState.Ended of LandAuction !!! : {getLandAuctionVersion()?.toBasicString()} - requestorId:{requestorId}, {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
return result;
}
// 1. 랜드 경매 Write 권한 얻는다.
var is_success = await land_auction.tryAcquireWriteLockWithLandAuction(requestorId, 120);
if (true == is_success)
{
using (var runner_with_scope = new EntityTransactionRunnerWithScopLock(land_auction))
{
result = await runner_with_scope.tryInvokeWithAsyncLock(() => checkAndUpdate(requestorId));
if (result.isFail())
{
return result;
}
auction_check_result.LandAuctionInfo = toLandAuctionInfo();
auction_check_result.LandAuctionBidType = toLandAuctionBidType();
Log.getLogger().debug($"Successed tryAcquireWriteLockWithLandAuction() - {land_auction.toBasicString()}");
}
}
// 2. 랜드 경매 정보를 캐시 or DB 에서 읽기만 하고 읽은 버전 정보가 직전에 읽은 버전보다 최신일 경우 복사 한다. - kangms
else
{
(result, var check_result) = await tryGetLandAuctionCheckResult(true);
if (result.isFail()) { return result; }
auction_check_result = check_result;
err_msg = $"Failed to acquire WriteLock in LandAuction !!! : requestorId:{requestorId} - {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
}
NullReferenceCheckHelper.throwIfNull(auction_check_result, () => $"auction_check_result is null !!! - requestorId:{requestorId}");
if (isSyncRequired())
{
if (true == isLandAuctionState(LandAuctionState.Ended))
{
LandAuctionManager.It.activitingToRecord(land_meta_id, land_auction);
}
syncLandAuctionToClients(auction_check_result.LandAuctionInfo);
resetSyncRequired();
}
return result;
}
private async Task<(Result, LandAuctionCheckResult?)> tryRunLandAuctionWithRequestorTransactionRunner(REQUSTOR_ID requestorId)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var redis_connector = server_logic.getRedisDb();
var result = new Result();
var err_msg = string.Empty;
var land_meta_id = getLandMetaId();
var auction_number = getAuctionNumber();
var auction_check_result = new LandAuctionCheckResult();
//=====================================================================================
// 랜드 경매 Write 권한 얻은 유저만 랜드 경매 처리 로직을 수행할 수 있다 !!! - kangms
//=====================================================================================
// 1. 랜드 경매 WriteLock 권한 얻는다.
var is_success = await land_auction.tryAcquireWriteLockWithLandAuction(requestorId, 3); // 최대 3초 동안 WriteLock 권한을 획득 한다. !!!
if (true == is_success)
{
using (var runner_with_scope = new EntityTransactionRunnerWithScopLock(land_auction, requestorId))
{
result = await runner_with_scope.tryInvokeWithAsyncLock(() => checkAndUpdate(requestorId));
if (result.isFail())
{
return (result, null);
}
auction_check_result.LandAuctionInfo = toLandAuctionInfo();
auction_check_result.LandAuctionBidType = toLandAuctionBidType();
}
}
// 2. 랜드 경매 정보를 Cache or DB 에서 읽고, RegisteredVersion 과 ProcessVersion 을 읽고 더 최신일 경우 로컬 메모리를 업데이트 한다 !!!
else
{
err_msg = $"Failed to acquire WriteLock in LandAuction !!! : requestorId:{requestorId} - {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
(result, var check_result) = await tryGetLandAuctionCheckResult(true);
if (result.isFail()) { return (result, null); }
auction_check_result = check_result;
}
NullReferenceCheckHelper.throwIfNull(auction_check_result, () => $"auction_check_result is null !!! - requestorId:{requestorId}");
if (isSyncRequired())
{
if (true == isLandAuctionState(LandAuctionState.Ended))
{
LandAuctionManager.It.activitingToRecord(land_meta_id, land_auction);
}
syncLandAuctionToClients(auction_check_result.LandAuctionInfo);
resetSyncRequired();
}
err_msg = $"{auction_check_result.toBasicString()} - requestorId:{requestorId}";
Log.getLogger().debug(err_msg);
return (result, auction_check_result);
}
private async Task<Result> checkAndUpdate(REQUSTOR_ID requestorId)
{
// 본 함수내부에서 LandAuction.AsyncLock 관련 Lock 시도를 하면 DeadLock 이 발생 한다 !!! - kangms
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var redis_connector = server_logic.getRedisConnector();
var land_auction_action = land_auction.getEntityAction<LandAuctionAction>();
NullReferenceCheckHelper.throwIfNull(land_auction_action, () => $"land_auction_action is null !!! - {land_auction.toBasicString()}");
var result = new Result();
var err_msg = string.Empty;
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!! - {land_auction.toBasicString()}");
LandAuctionWinningResult? auction_winning_result = null;
OwnedLandHelper.OwnedLandOwnerChangedInfo? owner_changed_info = null;
var land_meta_id = registry_attribute.LandMetaId;
var auction_number = registry_attribute.AuctionNumber;
LandAuctionCache? land_auction_cache = null;
var land_auction_cache_request = new LandAuctionCacheRequest(land_meta_id, redis_connector);
var fetch_result = await land_auction_cache_request.fetchLandAuction();
if (fetch_result.isSuccess())
{
land_auction_cache = land_auction_cache_request.getLandAuctionCache();
}
else
{
err_msg = $"Failed to fetchLandAuction() !!! : {fetch_result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().warn(err_msg);
}
if (null == land_auction_cache)
{
result = await land_auction_action.tryLoadLandAuctionMeta(land_meta_id);
if (result.isFail())
{
err_msg = $"Failed to tryLoadLandAuctionMeta() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
(result, var winning_result, var changed_info) = await land_auction_action.tryUpdateLandAuctionResult();
if (result.isFail())
{
return result;
}
auction_winning_result = winning_result;
owner_changed_info = changed_info;
}
else
{
if (registry_attribute.AuctionNumber > land_auction_cache.AuctionNumber)
{
// 로컬 정보의 AuctionNumber 증가된 경우 캐시 정보를 신뢰할 수 없으므로, 즉시 제거 한다.
await land_auction_cache_request.deleteLandAuction();
}
else
{
if (registry_attribute.ProcessVersionTime < land_auction_cache.ProcessVersionTime)
{
registry_attribute.copyProcessInfoFromCache(land_auction_cache);
}
}
(result, var winning_result, var changed_info) = await land_auction_action.tryUpdateLandAuctionResult();
if (result.isFail())
{
return result;
}
auction_winning_result = winning_result;
owner_changed_info = changed_info;
}
var batch = new QueryBatchEx<QueryRunnerWithDocument>( land_auction, LogActionType.LandAuctionCheck
, server_logic.getDynamoDbClient()
, true);
{
if (null != auction_winning_result && null != auction_winning_result.ReceivedMailDoc) { batch.addQuery(new DBQEntityWrite(auction_winning_result.ReceivedMailDoc)); }
if (null != owner_changed_info)
{
NullReferenceCheckHelper.throwIfNull(owner_changed_info.LandDoc, () => $"owner_changed_info.LandDoc is null !!!");
NullReferenceCheckHelper.throwIfNull(owner_changed_info.OwnedLandDoc, () => $"owner_changed_info.OwnedLandDoc is null !!!");
NullReferenceCheckHelper.throwIfNull(owner_changed_info.BuildingDoc, () => $"owner_changed_info.BuildingDoc is null !!!");
NullReferenceCheckHelper.throwIfNull(owner_changed_info.OwnedBuildingDoc, () => $"owner_changed_info.OwnedBuildingDoc is null !!!");
batch.addQuery(new DBQEntityWrite(owner_changed_info.LandDoc));
batch.addQuery(new DBQEntityWrite(owner_changed_info.OwnedLandDoc));
batch.addQuery(new DBQEntityWrite(owner_changed_info.BuildingDoc));
batch.addQuery(new DBQEntityWrite(owner_changed_info.OwnedBuildingDoc));
}
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
batch.addQuery(new QueryFinal(), async (_query) =>
{
var completed_result = await land_auction_action.completedCheckLandAuction( auction_winning_result, owner_changed_info
, requestorId
, _query);
if (completed_result.isFail())
{
var err_msg = $"Failed to completedCheckLandAuction() !!! : {completed_result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
}
return QueryBatchBase.QueryResultType.Success;
});
}
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
return result;
}
return result;
}
public async Task<Result> recoverTopBidderCacheFromDb()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var redis_connector = server_logic.getRedisDb();
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!! - {land_auction.toBasicString()}");
var land_meta_id = registry_attribute.LandMetaId;
var auction_number = registry_attribute.AuctionNumber;
var result = new Result();
var err_msg = string.Empty;
(result, var top_bidder_cache) = await land_auction.tryGetLandAuctionTopBidderCache();
if (result.isFail())
{
err_msg = $"Failed to tryGetLandAuctionTopBidderCache() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
else
{
if (null == top_bidder_cache)
{
(result, var is_loaded) = await land_auction.tryLoadLandAuctionHighestBidUserDoc(land_meta_id, auction_number);
if (result.isFail())
{
err_msg = $"Failed to tryLoadLandAuctionHighestBidUserDoc() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
if (true == is_loaded)
{
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!! - {land_auction.toBasicString()}");
await land_auction.tryRemoveLandAuctionTopBidderBlockFromCache();
(var is_success
, var curr_top_bidder
, _, _) = await land_auction.tryRankLandAuctionTopBidderCache(highest_bid_user_attribute.HighestBidUserGuid
, highest_bid_user_attribute.HighestBidPrice);
if (false == is_success)
{
err_msg = $"Failed to tryRankLandAuctionTopBidderCache() !!! - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.RedisSortedSetsReadFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
NullReferenceCheckHelper.throwIfNull(curr_top_bidder, () => $"curr_top_bidder is null !!! - {land_auction.toBasicString()}");
}
}
}
return result;
}
public async Task<(Result, LandAuctionCheckResult?)> tryGetLandAuctionCheckResult(bool isWithLock)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var redis_connector = server_logic.getRedisDb();
var result = new Result();
var err_msg = string.Empty;
var land_meta_id = getLandMetaId();
var auction_number = getAuctionNumber();
var auction_check_result = new LandAuctionCheckResult();
// 1. 랜드 경매 정보를 캐시에서 읽는다.
result = await tryFillupLandAuctionCheckResultFromCache(land_meta_id, auction_check_result);
if (result.isFail())
{
err_msg = $"Failed to tryFillupLandAuctionCheckResultFromCache() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
// 2. 랜드 경매 정보를 DB에서 읽는다.
result = await tryFillupLandAuctionCheckResultFromDb(land_meta_id, auction_check_result
, isWithLock);
if (result.isFail())
{
err_msg = $"Failed to tryFillupLandAuctionCheckResultFromDb() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return (result, null);
}
}
auction_check_result.LandAuctionInfo = toLandAuctionInfo();
auction_check_result.LandAuctionBidType = toLandAuctionBidType();
return (result, auction_check_result);
}
private async Task<Result> tryFillupLandAuctionCheckResultFromCache(META_ID landMetaId, LandAuctionCheckResult landAuctionCheckResult)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var redis_connector = server_logic.getRedisConnector();
var result = new Result();
var err_msg = string.Empty;
var auction_number = getAuctionNumber();
// 1. 랜드 경매 정보를 캐시에서 읽는다.
var land_auction_cache_request = new LandAuctionCacheRequest(landMetaId, redis_connector);
result = await land_auction_cache_request.fetchLandAuction();
if (result.isFail())
{
err_msg = $"Failed to fetchLandAuction() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
var land_auction_cache = land_auction_cache_request.getLandAuctionCache();
if (null == land_auction_cache)
{
err_msg = $"Empty cache !!!, return getLandAuctionCache() !!! - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionEmptyCacheInRedis, err_msg);
return result;
}
else
{
landAuctionCheckResult.LandAuctionInfo.LandAuctionState = land_auction_cache.LandAuctionState;
landAuctionCheckResult.LandAuctionInfo.LandAuctionResult = land_auction_cache.LandAuctionResult;
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!! - {land_auction.toBasicString()}");
result = land_auction.copyCacheToEntityAttributeForLandAuction(registry_attribute, land_auction_cache);
if (result.isFail())
{
err_msg = $"Failed to copyCacheToEntityAttributeForLandAuction() !!! : {result.toBasicString()}, cacheType:{land_auction_cache.getTypeName()} - landMetaId:{landMetaId}";
Log.getLogger().error(err_msg);
return result;
}
}
// 2. 일반 입찰 최고가 유저 정보를 캐시에서 읽는다.
var normal_bid_highest_cache_request = new LandAuctionNormalBidHighestUserCacheRequest(landMetaId, redis_connector);
result = await normal_bid_highest_cache_request.fetchNormalBidHighestUser();
if (result.isFail())
{
err_msg = $"Failed to fetchNormalBidHighestUser() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
var normal_bid_highest_cache = normal_bid_highest_cache_request.getNormalBidHighestUserCache();
if (null == normal_bid_highest_cache)
{
err_msg = $"Empty cache !!!, return getNormalBidHighestUserCache() !!! - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionEmptyCacheInRedis, err_msg);
return result;
}
else
{
landAuctionCheckResult.LandAuctionInfo.HighestBid = normal_bid_highest_cache.NormalHighestBidPrice;
landAuctionCheckResult.LandAuctionInfo.WinningUserGuid = normal_bid_highest_cache.NormalHighestBidUserGuid;
landAuctionCheckResult.LandAuctionInfo.WinningUserNickname = normal_bid_highest_cache.NormalHighestBidUserNickname;
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!! - {land_auction.toBasicString()}");
result = land_auction.copyCacheToEntityAttributeForLandAuction(highest_bid_user_attribute, normal_bid_highest_cache);
if (result.isFail())
{
err_msg = $"Failed to copyCacheToEntityAttributeForLandAuction() !!! : {result.toBasicString()}, cacheType:{normal_bid_highest_cache.getTypeName()} - landMetaId:{landMetaId}";
Log.getLogger().error(err_msg);
return result;
}
}
return result;
}
public async Task<Result> tryFillupLandAuctionCheckResultFromDb(META_ID landMetaId, LandAuctionCheckResult landAuctionCheckResult
, bool isWithLock)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var result = new Result();
var err_msg = string.Empty;
(result, var found_activity_doc) = await LandAuctionDbHelper.readLandAuctionActivityDocFromDb(landMetaId);
if (result.isFail())
{
err_msg = $"Failed to readLandAuctionActivityDocFromDb() !!! : {result.toBasicString()} - landMetaId:{landMetaId}";
Log.getLogger().error(err_msg);
return result;
}
NullReferenceCheckHelper.throwIfNull(found_activity_doc, () => $"found_activity_doc is null !!!");
var ativity_attib = found_activity_doc.getAttrib<LandAuctionActivityAttrib>();
NullReferenceCheckHelper.throwIfNull(ativity_attib, () => $"ativity_attib is null !!!");
var land_meta_id = ativity_attib.LandMetaId;
var auction_number = ativity_attib.AuctionNumber;
(result, var found_registry_doc) = await LandAuctionDbHelper.readLandAuctionRegistryDocFromDb(landMetaId, auction_number);
if (result.isFail())
{
err_msg = $"Failed to readLandAuctionRegistryDocFromDb() !!! : {result.toBasicString()} - landMetaId:{landMetaId}, auctionNumber:{auction_number}";
Log.getLogger().error(err_msg);
return result;
}
else
{
NullReferenceCheckHelper.throwIfNull(found_registry_doc, () => $"found_registry_doc is null !!!");
var registry_attrib = found_registry_doc.getAttrib<LandAuctionRegistryAttrib>();
NullReferenceCheckHelper.throwIfNull(registry_attrib, () => $"registry_attrib is null !!!");
landAuctionCheckResult.LandAuctionInfo = new();
landAuctionCheckResult.LandAuctionInfo.LandMetaId = (Int32)land_meta_id;
landAuctionCheckResult.LandAuctionInfo.AuctionNumber = auction_number;
landAuctionCheckResult.LandAuctionInfo.AuctionReservationNoticeStartTime = registry_attrib.AuctionReservationNoticeStartTime.ToTimestamp();
landAuctionCheckResult.LandAuctionInfo.CurrencyType = registry_attrib.BidCurrencyType;
landAuctionCheckResult.LandAuctionInfo.StartingBid = registry_attrib.BidStartPrice;
landAuctionCheckResult.LandAuctionInfo.AuctionStartTime = registry_attrib.AuctionStartTime.ToTimestamp();
landAuctionCheckResult.LandAuctionInfo.AuctionEndTime = registry_attrib.AuctionEndTime.ToTimestamp();
landAuctionCheckResult.LandAuctionInfo.LandAuctionState = registry_attrib.LandAuctionState;
landAuctionCheckResult.LandAuctionInfo.LandAuctionResult = registry_attrib.LandAuctionResult;
landAuctionCheckResult.LandAuctionInfo.IsLandOwnerChanged = LandAuctionResult.Successed == registry_attrib.LandAuctionResult ? BoolType.True : BoolType.False;
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!! - {land_auction.toBasicString()}");
result = await land_auction.copyDocToEntityAttributeForLandAuction(registry_attribute, found_registry_doc
, isWithLock);
if (result.isFail())
{
return result;
}
}
(result, var found_highest_bid_user_doc) = await LandAuctionDbHelper.readLandAuctionHighestBidUserDocFromDb(landMetaId, auction_number);
if (result.isFail())
{
err_msg = $"Failed to readLandAuctionHighestBidUserDocFromDb() !!! : {result.toBasicString()} - landMetaId:{landMetaId}, auctionNumber:{auction_number}";
Log.getLogger().error(err_msg);
return result;
}
if (null != found_highest_bid_user_doc)
{
var highest_bid_user_attrib = found_highest_bid_user_doc.getAttrib<LandAuctionHighestBidUserAttrib>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attrib, () => $"highest_bid_user_attrib is null !!!");
landAuctionCheckResult.LandAuctionInfo.HighestBid = highest_bid_user_attrib.NormalHighestBidPrice;
landAuctionCheckResult.LandAuctionInfo.WinningUserGuid = highest_bid_user_attrib.NormalHighestBidUserGuid;
landAuctionCheckResult.LandAuctionInfo.WinningUserNickname = highest_bid_user_attrib.NormalHighestBidUserNickname;
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!! - {land_auction.toBasicString()}");
result = await land_auction.copyDocToEntityAttributeForLandAuction(highest_bid_user_attribute, found_highest_bid_user_doc
, isWithLock);
if (result.isFail())
{
return result;
}
}
return result;
}
public async Task<(Result, LandAuctionWinningResult?, OwnedLandHelper.OwnedLandOwnerChangedInfo?)> tryUpdateLandAuctionResult()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var result = new Result();
var err_msg = string.Empty;
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
var land_meta_id = registry_attribute.LandMetaId;
var check_land_owner_result = OwnedLandHelper.checkLandWithoutOwner(land_meta_id);
if (check_land_owner_result.isFail())
{
Log.getLogger().warn($"Failed to checkLandWithoutOwner() !!! : {check_land_owner_result.toBasicString()} - {land_auction.toBasicString()}");
return (result, null, null);
}
if (true == registry_attribute.IsCancelAuction)
{ return (await cancelLandAuctionResult(), null, null); }
else if (true == isLandAuctionStateByTime(LandAuctionState.Waiting))
{ return (await waitingLandAuctionResult(), null, null); }
else if (true == isLandAuctionStateByTime(LandAuctionState.Scheduled))
{ return (await scheduleLandAuctionResult(), null, null); }
else if (true == isLandAuctionStateByTime(LandAuctionState.Started))
{ return (await startLandAuctionResult(), null, null); }
else if (true == isLandAuctionStateByTime(LandAuctionState.Ended))
{ return await stopLandAuctionResult(); }
return (result, null, null);
}
private async Task<Result> cancelLandAuctionResult()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
var result = new Result();
var err_msg = string.Empty;
var highest_bid_user_nickname = string.Empty;
var land_auction_state = registry_attribute.LandAuctionState;
if (LandAuctionState.Ended != land_auction_state)
{
var land_meta_id = registry_attribute.LandMetaId;
var auction_number = registry_attribute.AuctionNumber;
var bid_currency_type = registry_attribute.BidCurrencyType;
registry_attribute.LandAuctionState = LandAuctionState.Ended;
registry_attribute.LandAuctionResult = LandAuctionResult.Canceled;
Log.getLogger().info($"try cancelLandAuctionResult() !!! - {toBasicString()}");
// 최고 입찰자 정보를 읽고, 랭킹 정보를 블록 처리 한다. !!!
(var is_success, var curr_top_bidder) = await land_auction.tryGetLandAuctionTopBidderCacheWithBlock();
if (null == curr_top_bidder)
{
// DB 정보를 읽는다.
(result, var is_loaded) = await land_auction.tryLoadLandAuctionHighestBidUserDoc(land_meta_id, auction_number);
if (result.isFail())
{
err_msg = $"Failed to tryLoadLandAuctionHighestBidUserDoc() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
if (true == is_loaded)
{
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!!");
curr_top_bidder = new LandAuctionTopBidderCache();
curr_top_bidder.LandMetaId = highest_bid_user_attribute.LandMetaId;
curr_top_bidder.HighestBidUserGuid = highest_bid_user_attribute.HighestBidUserGuid;
curr_top_bidder.HighestBidPrice = highest_bid_user_attribute.HighestBidPrice;
highest_bid_user_nickname = highest_bid_user_attribute.HighestBidUserNickname;
}
}
if (null != curr_top_bidder)
{
// 최고 입찰자가 존재 하지만 랜드 소유권 변경은 하고, 최고 입찰자 저장만 시킨다.
var highest_bid_user_guid = curr_top_bidder.HighestBidUserGuid;
// 최고 입찰자의 닉네임이 없다면
if (highest_bid_user_nickname.isNullOrWhiteSpace())
{
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!!");
if (highest_bid_user_attribute.HighestBidUserGuid == highest_bid_user_guid)
{
highest_bid_user_nickname = highest_bid_user_attribute.HighestBidUserNickname;
}
else
{
(result, var nickname_attrib) = await NicknameDoc.findNicknameFromGuid(highest_bid_user_guid);
NullReferenceCheckHelper.throwIfNull(nickname_attrib, () => $"nickname_attrib is null !!!");
if (result.isFail())
{
err_msg = $"Not found Highest Bid UserNickname !!! : userGuid:{highest_bid_user_guid} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
}
else
{
// 랭킹에 한하여 Cache => DB 에 저장 한다.
highest_bid_user_attribute.LandMetaId = curr_top_bidder.LandMetaId;
highest_bid_user_attribute.AuctionNumber = auction_number;
highest_bid_user_attribute.BidCurrencyType = bid_currency_type;
highest_bid_user_attribute.HighestBidPrice = curr_top_bidder.HighestBidPrice;
highest_bid_user_attribute.HighestBidUserGuid = curr_top_bidder.HighestBidUserGuid;
highest_bid_user_attribute.HighestBidUserNickname = nickname_attrib.Nickname;
highest_bid_user_attribute.modifiedEntityAttribute(true);
highest_bid_user_nickname = nickname_attrib.Nickname;
}
}
}
}
registry_attribute.ProcessVersionTime = DateTimeHelper.Current;
registry_attribute.modifiedEntityAttribute();
// 랜드 경매 종료 기록 정보를 등록 한다.
var land_auction_record_attribute = land_auction.getEntityAttribute<LandAuctionRecordAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_record_attribute, () => $"land_auction_record_attribute is null !!!");
land_auction_record_attribute.LandMetaId = registry_attribute.LandMetaId;
land_auction_record_attribute.AuctionNumber = registry_attribute.AuctionNumber;
land_auction_record_attribute.modifiedEntityAttribute(true);
m_cache_save_step = CacheSaveStep.Waiting;
}
return result;
}
private async Task<Result> waitingLandAuctionResult()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
var land_meta_id = registry_attribute.LandMetaId;
var auction_number = registry_attribute.AuctionNumber;
var result = new Result();
var err_msg = string.Empty;
var land_auction_state = registry_attribute.LandAuctionState;
if (LandAuctionState.Waiting != land_auction_state)
{
registry_attribute.LandAuctionState = LandAuctionState.Waiting;
registry_attribute.LandAuctionResult = LandAuctionResult.None;
registry_attribute.ProcessVersionTime = DateTimeHelper.Current;
registry_attribute.modifiedEntityAttribute();
m_cache_save_step = CacheSaveStep.Waiting;
err_msg = $"try change state of LandAuction : to:{registry_attribute.LandAuctionState} <= from:{land_auction_state} - {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
}
return await Task.FromResult(result);
}
private async Task<Result> scheduleLandAuctionResult()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var db_connector = server_logic.getDynamoDbClient();
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
var land_meta_id = registry_attribute.LandMetaId;
var auction_number = registry_attribute.AuctionNumber;
var result = new Result();
var err_msg = string.Empty;
var land_auction_state = registry_attribute.LandAuctionState;
if (LandAuctionState.Scheduled != land_auction_state)
{
registry_attribute.LandAuctionState = LandAuctionState.Scheduled;
registry_attribute.LandAuctionResult = LandAuctionResult.None;
registry_attribute.ProcessVersionTime = DateTimeHelper.Current;
registry_attribute.modifiedEntityAttribute();
var highest_bid_user_doc = new LandAuctionHighestBidUserDoc((META_ID)land_meta_id, auction_number);
var highest_bid_user_attrib = highest_bid_user_doc.getAttrib<LandAuctionHighestBidUserAttrib>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attrib, () => $"highest_bid_user_attrib is null !!! - {land_auction.toBasicString()}");
highest_bid_user_attrib.BidCurrencyType = registry_attribute.BidCurrencyType;
highest_bid_user_attrib.NormalHighestBidPrice = 0;
highest_bid_user_attrib.NormalHighestBidUserGuid = string.Empty;
highest_bid_user_attrib.NormalHighestBidUserNickname = string.Empty;
highest_bid_user_attrib.HighestBidPrice = 0;
highest_bid_user_attrib.HighestBidUserGuid = string.Empty;
highest_bid_user_attrib.HighestBidUserNickname = string.Empty;
result = await db_connector.simpleUpsertDocumentWithDocType<LandAuctionHighestBidUserDoc>(highest_bid_user_doc);
if (result.isFail())
{
err_msg = $"Failed to simpleUpsertDocumentWithDocType<LandAuctionHighestBidUserDoc> !!! : {highest_bid_user_doc.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
m_cache_save_step = CacheSaveStep.Waiting;
err_msg = $"try change state of LandAuction : to:{registry_attribute.LandAuctionState} <= from:{land_auction_state} - {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
}
return result;
}
private async Task<Result> startLandAuctionResult()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var result = new Result();
var err_msg = string.Empty;
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
var land_auction_state = registry_attribute.LandAuctionState;
if (LandAuctionState.Started != land_auction_state)
{
registry_attribute.LandAuctionState = LandAuctionState.Started;
registry_attribute.ProcessVersionTime = DateTimeHelper.Current;
registry_attribute.modifiedEntityAttribute();
m_cache_save_step = CacheSaveStep.Waiting;
err_msg = $"try change state of LandAuction : to:{registry_attribute.LandAuctionState} <= from:{land_auction_state} - {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
}
result = await recoverTopBidderCacheFromDb();
if (result.isFail())
{
err_msg = $"Failed to recoverTopBidderCacheFromDb() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
return await Task.FromResult(result);
}
private async Task<(Result, LandAuctionWinningResult?, OwnedLandHelper.OwnedLandOwnerChangedInfo?)> stopLandAuctionResult()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
var result = new Result();
var err_msg = string.Empty;
var land_auction_result = registry_attribute.LandAuctionResult;
var land_auction_state = registry_attribute.LandAuctionState;
if (LandAuctionState.Ended == land_auction_state)
{
return (result, null, null);
}
var auction_winning_result = new LandAuctionWinningResult();
OwnedLandHelper.OwnedLandOwnerChangedInfo? owner_changed_info = null;
var highest_bid_user_nickname = string.Empty;
var land_meta_id = registry_attribute.LandMetaId;
var auction_number = registry_attribute.AuctionNumber;
var bid_currency_type = registry_attribute.BidCurrencyType;
// 랜드 경매 종료 상태를 설정 한다.
registry_attribute.LandAuctionState = LandAuctionState.Ended;
// 최고 입찰자 정보를 읽고, 랭킹 정보를 블록 처리 한다. !!!
(var is_success, var curr_top_bidder) = await land_auction.tryGetLandAuctionTopBidderCacheWithBlock();
if (null == curr_top_bidder)
{
// DB 정보를 읽는다.
(result, var is_loaded) = await land_auction.tryLoadLandAuctionHighestBidUserDoc(land_meta_id, auction_number);
if (result.isFail())
{
err_msg = $"Failed to tryLoadLandAuctionHighestBidUserDoc() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
return (result, null, null);
}
if ( false == is_loaded
|| false == isExistLandAuctionHighestBidUser() )
{
// 최고 입찰자는 없으므로, 랜드 경매 결과를 실패 처리 한다.
registry_attribute.LandAuctionResult = LandAuctionResult.Failed;
}
else
{
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!!");
curr_top_bidder = new LandAuctionTopBidderCache();
curr_top_bidder.LandMetaId = highest_bid_user_attribute.LandMetaId;
curr_top_bidder.HighestBidUserGuid = highest_bid_user_attribute.HighestBidUserGuid;
curr_top_bidder.HighestBidPrice = highest_bid_user_attribute.HighestBidPrice;
highest_bid_user_nickname = highest_bid_user_attribute.HighestBidUserNickname;
}
}
if (null != curr_top_bidder)
{
// 최고 입찰자가 존재하므로 랜드 경매 결과는 성공 이다 !!!
registry_attribute.LandAuctionResult = LandAuctionResult.Successed;
if (false == GameServerApp.getServerLogic().getLandManager().tryGetLand((Int32)land_meta_id, out var found_land))
{
err_msg = $"Not found Land !!! : landMetaId:{land_meta_id} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandNotFound, err_msg);
Log.getLogger().error(err_msg);
return (result, null, null);
}
var highest_bid_user_guid = curr_top_bidder.HighestBidUserGuid;
// 랜드 소유를 변경하기 기본 조건들을 체크하고 Doc 정보를 구성 한다.
(result, var changed_info) = await OwnedLandHelper.makeOwnedLandOwnerChangedInfo(land_meta_id, OwnedType.Own, highest_bid_user_guid);
if (result.isFail())
{
err_msg = $"Failed to makeOwnedLandOwnerChangedInfo() !!! : {result.toBasicString()}, landMetaId:{land_meta_id} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
return (result, null, null);
}
NullReferenceCheckHelper.throwIfNull(changed_info, () => $"changed_info is null !!! - {land_auction.toBasicString()}");
owner_changed_info = changed_info;
// 최고 입찰자의 닉네임이 없다면
if (highest_bid_user_nickname.isNullOrWhiteSpace())
{
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!!");
if (highest_bid_user_attribute.HighestBidUserGuid == highest_bid_user_guid)
{
highest_bid_user_nickname = highest_bid_user_attribute.HighestBidUserNickname;
}
else
{
(result, var nickname_attrib) = await NicknameDoc.findNicknameFromGuid(highest_bid_user_guid);
NullReferenceCheckHelper.throwIfNull(nickname_attrib, () => $"nickname_attrib is null !!!");
if (result.isFail())
{
err_msg = $"Not found Highest Bid UserNickname !!! : userGuid:{highest_bid_user_guid} - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
}
else
{
// 랭킹에 한하여 Cache => DB 에 저장 한다.
highest_bid_user_attribute.LandMetaId = curr_top_bidder.LandMetaId;
highest_bid_user_attribute.AuctionNumber = auction_number;
highest_bid_user_attribute.BidCurrencyType = bid_currency_type;
highest_bid_user_attribute.HighestBidPrice = curr_top_bidder.HighestBidPrice;
highest_bid_user_attribute.HighestBidUserGuid = curr_top_bidder.HighestBidUserGuid;
highest_bid_user_attribute.HighestBidUserNickname = nickname_attrib.Nickname;
highest_bid_user_attribute.modifiedEntityAttribute(true);
highest_bid_user_nickname = nickname_attrib.Nickname;
}
}
}
(result, var new_mail_doc) = await createMailWithLandItem(highest_bid_user_guid, highest_bid_user_nickname);
if (result.isFail())
{
return (result, null, null);
}
auction_winning_result.WinningUserGuid = highest_bid_user_guid;
auction_winning_result.WinningUserNickname = highest_bid_user_nickname;
auction_winning_result.ReceivedMailDoc = new_mail_doc;
}
registry_attribute.ProcessVersionTime = DateTimeHelper.Current;
registry_attribute.modifiedEntityAttribute();
// 랜드 경매 종료 기록 정보를 등록 한다.
var land_auction_record_attribute = land_auction.getEntityAttribute<LandAuctionRecordAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_record_attribute, () => $"land_auction_record_attribute is null !!!");
land_auction_record_attribute.LandMetaId = registry_attribute.LandMetaId;
land_auction_record_attribute.AuctionNumber = registry_attribute.AuctionNumber;
land_auction_record_attribute.modifiedEntityAttribute(true);
m_cache_save_step = CacheSaveStep.Waiting;
err_msg = $"try change result and state of LandAuction :"
+ $" Result(to:{registry_attribute.LandAuctionResult} <= from:{land_auction_result})"
+ $" State(to:{registry_attribute.LandAuctionState} <= from:{land_auction_state})"
+ $" - {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
return (result, auction_winning_result, owner_changed_info);
}
public Result isBidableLandAuction( LandAuctionCheckResult checkResult
, CurrencyType currencyType, double bidPrice )
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_meta_id = checkResult.LandAuctionInfo.LandMetaId;
var auction_number = checkResult.LandAuctionInfo.AuctionNumber;
var result = isValid(auction_number);
if (result.isFail()) { return result; }
// 1. 랜드 소유권 설정 상태를 체크 한다.
result = OwnedLandHelper.checkLandWithoutOwner((META_ID)land_meta_id);
if (result.isFail()) { return result; }
// 2. 경매 시작 상태를 체크 한다.
if (false == checkResult.isLandAuctionState(LandAuctionState.Started))
{
var remain_sec = DateTimeHelper.toRemainingTimeSec(checkResult.LandAuctionInfo.AuctionStartTime.ToDateTime());
var err_msg = $"Not Started state LandAuction !!! : remainSecFromStartTime:{remain_sec} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionNotStarted, err_msg);
return result;
}
// 3. 경매 입찰 종류를 체크 한다.
var curr_bid_currency_type = checkResult.LandAuctionInfo.CurrencyType;
if (curr_bid_currency_type != currencyType)
{
var err_msg = $"Invalid Bid CurrencyType !!! : currBidCurrencyType:{curr_bid_currency_type} == reqCurrencyType:{currencyType} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionBidCurrencyTypeInvalid, err_msg);
return result;
}
// 4. 입찰금을 체크 한다.
var start_bid_price = checkResult.LandAuctionInfo.StartingBid;
if (start_bid_price > bidPrice)
{
var err_msg = $"Not enough bid price !!!, less than Starting Bid Price : startBidPrice:{start_bid_price} <= reqCurrencyType:{bidPrice} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionBidPriceNotEnough, err_msg);
return result;
}
return result;
}
public bool isHistory()
{
if (true == isLandAuctionState(LandAuctionState.Ended)
&& true == isLandAuctionResult(LandAuctionResult.Successed))
{
return true;
}
return false;
}
public bool isScheduling()
{
if ((true == isLandAuctionStateByTime(LandAuctionState.Scheduled)
|| true == isLandAuctionStateByTime(LandAuctionState.Started))
&& true != isLandAuctionState(LandAuctionState.Ended))
{
return true;
}
return false;
}
public bool isLandAuctionResult(LandAuctionResult auctionResult)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
return auctionResult == registry_attribute.LandAuctionResult;
}
public bool isLandAuctionStateByTime(LandAuctionState state)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
return registry_attribute.isLandAuctionStateByTime(state);
}
public bool isLandAuctionState(LandAuctionState state)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
return registry_attribute.LandAuctionState == state;
}
public async Task<(Result, ReceivedMailDoc?)> createMailWithLandItem(USER_GUID highestBidUserGuid, USER_NICKNAME highestBidUserNickname)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var redis_connector = server_logic.getRedisDb();
var result = new Result();
var err_msg = string.Empty;
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
var land_meta_id = registry_attribute.LandMetaId;
var auction_number = registry_attribute.AuctionNumber;
var system_mail_key = "LandAuctionResult";
if (MetaData.Instance.SystemMailMetaData.TryGetValue(system_mail_key, out var systemMailMetaData) == false)
{
err_msg = $"Not found SystemMailMeta !!! : mailKey:{system_mail_key} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.SystemMailMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
if (false == MetaData.Instance._LandTable.TryGetValue((Int32)land_meta_id, out var land_meta_data))
{
err_msg = $"Not found LandMeta !!! : landMetaId:{land_meta_id} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
if (0 >= land_meta_data.LinkedItem)
{
err_msg = $"Not set LinkedItem of LandItem : landMetaId:{land_meta_id} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionLandItemNotSet, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
if (false == server_logic.getLandManager().tryGetLand((Int32)land_meta_id, out var found_land))
{
err_msg = $"Not found Land !!! : landMetaId:{land_meta_id} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
var found_land_auction = LandAuctionManager.It.findActivitingLandAuction(land_meta_id);
if (null == found_land_auction)
{
err_msg = $"Not found activiting LandAuction !!! : landMetaId:{land_meta_id} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
var contens_arguments = new List<string>();
contens_arguments.Add(land_meta_data.getStringKeyOfLandName());
contens_arguments.Add(highestBidUserNickname);
contens_arguments.Add(found_land_auction.getWinningBidValue());
var mail_items = new List<ServerCommon.MailItem>();
var mail_item = new ServerCommon.MailItem() { ItemId = (META_ID)land_meta_data.LinkedItem, Count = 1 };
mail_items.Add(mail_item);
(result, var new_mail_doc) = await Mail.createSystemMailWithMeta( highestBidUserGuid, highestBidUserNickname, systemMailMetaData
, contens_arguments
, mail_items, ServerCommon.MetaHelper.GameConfigMeta.LandAuctionSuccessedMailPeriodMinutes);
if (result.isFail())
{
err_msg = $"Failed to createSystemMailWithMeta() !!! : {result.toBasicString()} - {land_auction.toBasicString()}";
Log.getLogger().info(err_msg);
return (result, null);
}
return (result, new_mail_doc);
}
public async Task sendTopBidderInfo( LandAuctionBidType bidType
, LandAuctionTopBidderCache currTopBidder, LandAuctionTopBidderCache? oldTopBidder)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var result = new Result();
var err_msg = string.Empty;
if(null == oldTopBidder)
{
var curr_top_user_guid = currTopBidder.HighestBidUserGuid;
await sendTopBidderInfoByUSER_GUID(curr_top_user_guid, BoolType.False);
}
else
{
var has_received_refund_mail = LandAuctionBidType.Normal == bidType ? BoolType.True : BoolType.False;
// 현재 최고가 입찰자가 직전 최고가 입찰자와 동일한 경우
if (currTopBidder.HighestBidUserGuid == oldTopBidder.HighestBidUserGuid)
{
var curr_top_user_guid = currTopBidder.HighestBidUserGuid;
await sendTopBidderInfoByUSER_GUID(curr_top_user_guid, has_received_refund_mail);
}
else
{
var curr_top_user_guid = currTopBidder.HighestBidUserGuid;
await sendTopBidderInfoByUSER_GUID(curr_top_user_guid, BoolType.False);
var old_top_user_guid = oldTopBidder.HighestBidUserGuid;
await sendTopBidderInfoByUSER_GUID(old_top_user_guid, has_received_refund_mail);
}
}
}
private async Task sendTopBidderInfoByUSER_GUID(USER_GUID targetUserGuid, BoolType hasReceivedRefundMail = BoolType.True)
{
await Task.CompletedTask;
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var server_logic = GameServerApp.getServerLogic();
var result = new Result();
var err_msg = string.Empty;
var curr_top_user_guid = targetUserGuid;
var bid_currency_type = getBidCurrencyType();
// LandAuctionBidType.Normal과 LandAuctionBidType.Blind 는 모두 Normal 기준 값으로 동기화 한다. - kangms
var highest_bid_price = getNormalHighestBidPrice();
var highest_bid_user_guid = getNormalHighestBidUserGuid();
var highest_bid_user_nickaname = getNormalHighestBidUserNickname();
if (false == LandAuctionNotifyHelper.broadcast_GS2GS_NTF_LAND_AUCTION_HIGHEST_BIDDER_CHANGE( curr_top_user_guid, hasReceivedRefundMail
, getLandMetaId()
, bid_currency_type, highest_bid_price
, highest_bid_user_guid, highest_bid_user_nickaname))
{
err_msg = $"Failed to send_GS2GS_NTF_LAND_AUCTION_HIGHEST_BIDDER_CHANGE() !!! - {land_auction.toBasicString()}";
Log.getLogger().error(err_msg);
}
}
public async Task<Result> tryLoadLandAuctionForRecord(LAND_AUCTION_NUMBER landAuctionNumber)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var result = new Result();
var err_msg = string.Empty;
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
if (registry_attribute.AuctionNumber == landAuctionNumber)
{
var registry_doc = registry_attribute.getOriginDocBase<LandAuctionRegistryAttribute>() as LandAuctionRegistryDoc;
NullReferenceCheckHelper.throwIfNull(registry_doc, () => $"registry_doc is null !!!");
setLandAuctionRegistryDocForRecord(registry_doc);
}
else
{
(result, var record_doc) = await LandAuctionDbHelper.readLandAuctionRegistryDocFromDb(registry_attribute.LandMetaId, landAuctionNumber);
if (result.isFail())
{
err_msg = $"Failed to readLandAuctionRegistryDocFromDb() !!! : {result.toBasicString()} - {toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
NullReferenceCheckHelper.throwIfNull(record_doc, () => $"record_doc is null !!!");
setLandAuctionRegistryDocForRecord(record_doc);
}
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!!");
if (highest_bid_user_attribute.AuctionNumber == landAuctionNumber)
{
var highest_bid_user_doc = highest_bid_user_attribute.getOriginDocBase<LandAuctionHighestBidUserAttribute>() as LandAuctionHighestBidUserDoc;
NullReferenceCheckHelper.throwIfNull(highest_bid_user_doc, () => $"highest_bid_user_doc is null !!!");
setLandAuctionHighestBidUserDocForRecord(highest_bid_user_doc);
}
else
{
(result, var highest_bid_user_doc) = await LandAuctionDbHelper.readLandAuctionHighestBidUserDocFromDb(registry_attribute.LandMetaId, landAuctionNumber);
if (result.isFail())
{
err_msg = $"Failed to readLandAuctionHighestBidUserDocFromDb() !!! : {result.toBasicString()} - {toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
if (null != highest_bid_user_doc)
{
setLandAuctionHighestBidUserDocForRecord(highest_bid_user_doc);
}
}
return result;
}
private bool isExistLandAuctionHighestBidUser()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attribute, () => $"highest_bid_user_attribute is null !!!");
if( 0 >= highest_bid_user_attribute.LandMetaId
|| true == highest_bid_user_attribute.HighestBidUserGuid.isNullOrWhiteSpace()
|| true == highest_bid_user_attribute.HighestBidUserNickname.isNullOrWhiteSpace() )
{
return false;
}
return true;
}
public Result isValid(LAND_AUCTION_NUMBER auctionNumber)
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var result = new Result();
var err_msg = string.Empty;
var curr_auction_number = getAuctionNumber();
if(curr_auction_number != auctionNumber)
{
err_msg = $"Invalid LandAuction auctionNumber !!! : currAuctionNumber:{curr_auction_number} != reqAuctionNumber:{auctionNumber} - {land_auction.toBasicString()}";
result.setFail(ServerErrorCode.LandAuctionInvalidAuctionNumber, err_msg);
return result;
}
return result;
}
public LandAuctionBidType toLandAuctionBidType()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
// 랜드 경매 종료 상태를 설정 한다.
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
// 현재 입찰 종류를 반환 받는다.
return LandAuctionMetaHelper.toCurrentBidType(registry_attribute.AuctionEndTime);
}
public LandAuctionState getLandAuctionState()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
return registry_attribute.LandAuctionState;
}
public async Task<LandInfo> toLandInfo()
{
var server_logic = GameServerApp.getServerLogic();
var land_manager = server_logic.getLandManager();
var result = new Result();
var err_msg = string.Empty;
var land_meta_id = getLandMetaId();
if (false == land_manager.tryGetLand((Int32)land_meta_id, out var found_land))
{
err_msg = $"Failed to tryGetLand() !!! : landMetaId:{land_meta_id}";
Log.getLogger().error(err_msg);
return new LandInfo();
}
return await found_land.toLandInfo();
}
public LandAuctionInfo toLandAuctionInfo()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(registry_attribute, () => $"registry_attribute is null !!!");
var land_auction_info = new LandAuctionInfo();
land_auction_info.LandMetaId = (Int32)registry_attribute.LandMetaId;
land_auction_info.AuctionNumber = registry_attribute.AuctionNumber;
land_auction_info.AuctionReservationNoticeStartTime = registry_attribute.AuctionReservationNoticeStartTime.ToTimestamp();
land_auction_info.CurrencyType = registry_attribute.BidCurrencyType;
land_auction_info.StartingBid = getStartBidPrice();
land_auction_info.AuctionStartTime = registry_attribute.AuctionStartTime.ToTimestamp();
land_auction_info.AuctionEndTime = registry_attribute.AuctionEndTime.ToTimestamp();
var bid_type = toLandAuctionBidType();
if(LandAuctionBidType.Normal == bid_type)
{
land_auction_info.HighestBid = getNormalHighestBidPrice();
land_auction_info.WinningUserGuid = getNormalHighestBidUserGuid();
land_auction_info.WinningUserNickname = getNormalHighestBidUserNickname();
}
else
{
land_auction_info.HighestBid = getNormalHighestBidPrice();
land_auction_info.WinningUserGuid = getNormalHighestBidUserGuid();
land_auction_info.WinningUserNickname = getNormalHighestBidUserNickname();
}
land_auction_info.LandAuctionState = registry_attribute.LandAuctionState;
land_auction_info.LandAuctionResult = registry_attribute.LandAuctionResult;
land_auction_info.IsLandOwnerChanged = toLandOwnerChanged();
return land_auction_info;
}
public async Task<LandAuctionCompact?> toLandAuctionCompact()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var registry_doc_4_record= getLandAuctionRegistryDocForRecord();
if(null == registry_doc_4_record)
{
var err_msg = string.Empty;
var auction_number = getAuctionNumber();
var record_result = await tryLoadLandAuctionForRecord(auction_number);
if (record_result.isFail())
{
err_msg = $"Failed to tryLoadLandAuctionForRecord() !!! : {record_result.toBasicString()} - {toBasicString()}";
Log.getLogger().error(err_msg);
return null;
}
registry_doc_4_record = getLandAuctionRegistryDocForRecord();
NullReferenceCheckHelper.throwIfNull(registry_doc_4_record, () => $"registry_doc_4_record is null !!!");
}
var registry_attrib = registry_doc_4_record.getAttrib<LandAuctionRegistryAttrib>();
NullReferenceCheckHelper.throwIfNull(registry_attrib, () => $"registry_attrib is null !!!");
var land_auction_compact = new LandAuctionCompact();
land_auction_compact.LandMetaId = (Int32)registry_attrib.LandMetaId;
land_auction_compact.AuctionNumber = registry_attrib.AuctionNumber;
land_auction_compact.AuctionReservationNoticeStartTime = registry_attrib.AuctionReservationNoticeStartTime.ToTimestamp();
land_auction_compact.CurrencyType = registry_attrib.BidCurrencyType;
land_auction_compact.AuctionStartTime = registry_attrib.AuctionStartTime.ToTimestamp();
land_auction_compact.AuctionEndTime = registry_attrib.AuctionEndTime.ToTimestamp();
var highest_bid_user_doc_4_record = getLandAuctionHighestBidUserDocForRecord();
if(null != highest_bid_user_doc_4_record)
{
var highest_bid_user_attrib = highest_bid_user_doc_4_record.getAttrib<LandAuctionHighestBidUserAttrib>();
NullReferenceCheckHelper.throwIfNull(highest_bid_user_attrib, () => $"highest_bid_user_attrib is null !!!");
land_auction_compact.HighestBid = highest_bid_user_attrib.HighestBidPrice;
land_auction_compact.WinningUserGuid = highest_bid_user_attrib.HighestBidUserGuid;
land_auction_compact.WinningUserNickname = highest_bid_user_attrib.HighestBidUserNickname;
}
land_auction_compact.LandAuctionState = registry_attrib.LandAuctionState;
land_auction_compact.LandAuctionResult = registry_attrib.LandAuctionResult;
return land_auction_compact;
}
private LandAuctionHighestBidUserDoc? getLandAuctionHighestBidUserDocForRecord()
=> m_land_auction_highest_bid_user_doc_for_record;
private void setLandAuctionHighestBidUserDocForRecord(LandAuctionHighestBidUserDoc landAuctionHighestBidUserDoc)
=> m_land_auction_highest_bid_user_doc_for_record = landAuctionHighestBidUserDoc;
private LandAuctionRegistryDoc? getLandAuctionRegistryDocForRecord()
=> m_land_auction_registry_doc_for_record;
private void setLandAuctionRegistryDocForRecord(LandAuctionRegistryDoc landAuctionRegistryDoc)
=> m_land_auction_registry_doc_for_record = landAuctionRegistryDoc;
public LandAuctionSummary toLandAuctionSummary()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_summary = new LandAuctionSummary();
land_auction_summary.LandAuctionInfo = toLandAuctionInfo();
return land_auction_summary;
}
public double getHighestBidPrice()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_highest_bid_user_attribute, () => $"land_auction_highest_bid_user_attribute is null !!!");
return land_auction_highest_bid_user_attribute.HighestBidPrice;
}
public USER_GUID getHighestBidUserGuid()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_highest_bid_user_attribute, () => $"land_auction_highest_bid_user_attribute is null !!!");
return land_auction_highest_bid_user_attribute.HighestBidUserGuid;
}
public USER_NICKNAME getHighestBidUserNickname()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_highest_bid_user_attribute, () => $"land_auction_highest_bid_user_attribute is null !!!");
return land_auction_highest_bid_user_attribute.HighestBidUserNickname;
}
public double getNormalHighestBidPrice()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_highest_bid_user_attribute, () => $"land_auction_highest_bid_user_attribute is null !!!");
return land_auction_highest_bid_user_attribute.NormalHighestBidPrice;
}
public USER_GUID getNormalHighestBidUserGuid()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_highest_bid_user_attribute, () => $"land_auction_highest_bid_user_attribute is null !!!");
return land_auction_highest_bid_user_attribute.NormalHighestBidUserGuid;
}
public USER_NICKNAME getNormalHighestBidUserNickname()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_highest_bid_user_attribute = land_auction.getEntityAttribute<LandAuctionHighestBidUserAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_highest_bid_user_attribute, () => $"land_auction_highest_bid_user_attribute is null !!!");
return land_auction_highest_bid_user_attribute.NormalHighestBidUserNickname;
}
public double getStartBidPrice()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_registry_attribute, () => $"land_auction_registry_attribute is null !!!");
return land_auction_registry_attribute.BidStartPrice;
}
public CurrencyType getBidCurrencyType()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_registry_attribute, () => $"land_auction_registry_attribute is null !!!");
return land_auction_registry_attribute.BidCurrencyType;
}
public BoolType toLandOwnerChanged()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_registry_attribute, () => $"land_auction_registry_attribute is null !!!");
return LandAuctionResult.Successed == land_auction_registry_attribute.LandAuctionResult ? BoolType.True : BoolType.False;
}
public LAND_AUCTION_NUMBER getAuctionNumber()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_registry_attribute, () => $"land_auction_registry_attribute is null !!!");
return land_auction_registry_attribute.AuctionNumber;
}
public META_ID getLandMetaId()
{
var land_auction = getOwner() as LandAuction;
NullReferenceCheckHelper.throwIfNull(land_auction, () => $"land_auction is null !!!");
var land_auction_registry_attribute = land_auction.getEntityAttribute<LandAuctionRegistryAttribute>();
NullReferenceCheckHelper.throwIfNull(land_auction_registry_attribute, () => $"land_auction_registry_attribute is null !!!");
return land_auction_registry_attribute.LandMetaId;
}
public void syncLandAuctionToClients(LandAuctionInfo landAuctionInfo)
{
var land_auction_summary = new LandAuctionSummary();
land_auction_summary.LandAuctionInfo = landAuctionInfo;
getLandAuctionVersion()?.toBasicString();
LandAuctionNotifyHelper.broadcast_GS2C_NTF_LAND_AUCTION_SUMMARY(land_auction_summary);
}
private void resetSyncRequired()
{
if (null == m_prev_version) return;
m_prev_version.resetSyncRequried();
}
public bool isSyncRequired()
{
return null == m_prev_version ? false : m_prev_version.IsSyncRequried;
}
public void updateHighestRankVersion(DateTime highestRankVersionTime)
{
if (null == m_prev_version)
{
m_prev_version = new LandAuctionVersion(DateTimeHelper.MinTime, DateTimeHelper.MinTime, highestRankVersionTime);
m_prev_version.IsSyncRequried = true;
}
else
{
(var is_success, var new_version) = m_prev_version.checkChangedVersion(DateTimeHelper.MinTime, DateTimeHelper.MinTime, highestRankVersionTime);
if (true == is_success)
{
m_prev_version = new_version;
}
}
}
public void updateProcessVersion(DateTime processVersionTime)
{
if (null == m_prev_version)
{
m_prev_version = new LandAuctionVersion(DateTimeHelper.MinTime, processVersionTime, DateTimeHelper.MinTime);
m_prev_version.IsSyncRequried = true;
}
else
{
(var is_success, var new_version) = m_prev_version.checkChangedVersion(DateTimeHelper.MinTime, processVersionTime, DateTimeHelper.MinTime);
if (true == is_success)
{
m_prev_version = new_version;
}
}
}
public void updateRegistryVersion(DateTime registeredVersionTime, DateTime processVersionTime)
{
if(null == m_prev_version)
{
m_prev_version = new LandAuctionVersion(registeredVersionTime, processVersionTime, DateTimeHelper.MinTime);
m_prev_version.IsSyncRequried = true;
}
else
{
(var is_success, var new_version) = m_prev_version.checkChangedVersion(registeredVersionTime, processVersionTime, DateTimeHelper.MinTime);
if (true == is_success)
{
m_prev_version = new_version;
}
}
}
public LandAuctionVersion? getLandAuctionVersion() => m_prev_version;
public void resetCacheSaveStep() => m_cache_save_step = CacheSaveStep.None;
public bool isSavableStepCache() => CacheSaveStep.Waiting == m_cache_save_step;
public CacheSaveStep getCaheSaveStep() => m_cache_save_step;
public DateTime getLandAuctionLastLoadedTime() => m_land_auction_last_loaded_time;
public void setLandAuctionLastLoadedTime(DateTime loadedTime) => m_land_auction_last_loaded_time = loadedTime;
public LAND_AUCTION_NUMBER getCurrentLanAuctionNumber() => m_current_land_auction_number;
public void setCurrentLandAuctionNumber(LAND_AUCTION_NUMBER currentNumber) => m_current_land_auction_number = currentNumber;
}