2443 lines
118 KiB
C#
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;
|
|
}
|