using System.Collections.Concurrent; using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using NeoSmart.AsyncLock; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using MetaAssets; using static ClientToGameMessage.Types; using static ClientToGameReq.Types; using static ClientToGameRes.Types; using SESSION_ID = System.Int32; using WORLD_META_ID = System.UInt32; using META_ID = System.UInt32; using ENTITY_GUID = System.String; using ACCOUNT_ID = System.String; using OWNER_GUID = System.String; using USER_GUID = System.String; using CHARACTER_GUID = System.String; using UGC_NPC_META_GUID = System.String; using ITEM_GUID = System.String; using ANCHOR_GUID = System.String; using UGC_NPC_NICKNAME = System.String; namespace GameServer; public class PlayerAction : EntityActionBase { private ConcurrentDictionary m_characters = new(); private AsyncLock m_characters_lock = new(); private Character? m_selected_character_nullable = null; private ConcurrentDictionary m_ugc_npcs = new(); private AsyncLock m_ugc_npc_lock = new(); public PlayerAction(Player owner) : base(owner) { } public override async Task onInit() { await Task.CompletedTask; var result = new Result(); return result; } public override void onClear() { m_characters.Clear(); m_selected_character_nullable = null; } public async Task commitTransaction(TransactionIdType toCommitTransactionIdType) { var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var result = new Result(); var err_msg = string.Empty; var found_transaction_runner = owner.findTransactionRunner(toCommitTransactionIdType); if(null == found_transaction_runner) { err_msg = $"Not found TransactionRunner !!! : transactionIdType:{toCommitTransactionIdType} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.TransactionRunnerNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return result; } result = await found_transaction_runner.onCommitResults(); if(result.isFail()) { return result; } return result; } public UgcNpc? findUgcNpc(UGC_NPC_META_GUID ugcNpcMetaGuid) { m_ugc_npcs.TryGetValue(ugcNpcMetaGuid, out var found_ugc_npc); return found_ugc_npc; } public UgcNpc? findUgcNpcByNickname(UGC_NPC_NICKNAME ugcNpcNickname) { var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); foreach (var each in m_ugc_npcs) { var ugc_npc = each.Value; var ugc_npc_attribute = ugc_npc.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {owner.toBasicString()}"); if(ugc_npc_attribute.Nickname.ToLower() == ugcNpcNickname.ToLower()) { return ugc_npc; } } return null; } public Result fillupOwnerEntities(OwnerEntityType ownerEntityType, ref Dictionary foundOwnerEntities) { var owner = getOwner() as Player; ArgumentNullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); ArgumentNullReferenceCheckHelper.throwIfNull(foundOwnerEntities, () => $"foundOwnerEntities is null !!! - {owner.toBasicString()}"); var result = new Result(); var err_msg = string.Empty; var user_attribute = owner.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!! - {toBasicString()}"); var user_guid = user_attribute.UserGuid; if (OwnerEntityType.User == ownerEntityType) { if (false == foundOwnerEntities.TryAdd(user_guid, owner)) { err_msg = $"Already added UserGuid !!! : userGuid:{user_guid} - {toBasicString()}"; result.setFail(ServerErrorCode.UserGuidAlreadyAdded, err_msg); return result; } } else if (OwnerEntityType.UgcNpc == ownerEntityType) { foreach (var each in m_ugc_npcs) { var ugc_npc_meta_guid = each.Key; var ugc_npc = each.Value; if(false == foundOwnerEntities.TryAdd(ugc_npc_meta_guid, ugc_npc)) { err_msg = $"Already added UgcNpcMetaGuid !!! : ugcNpcMetaGuid:{ugc_npc_meta_guid} - {toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcMetaGuidAlreadyAdded, err_msg); Log.getLogger().error(result.toBasicString()); continue; } } } else if (OwnerEntityType.Myhome == ownerEntityType) { var myhome_agent_action = owner.getEntityAction(); NullReferenceCheckHelper.throwIfNull(myhome_agent_action, () => $"myhome_agent_action is null !!! - {toBasicString()}"); var myhomes = myhome_agent_action.getMyHomes(); foreach (var myhome in myhomes) { var myhome_attribute = myhome.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(myhome_attribute, () => $"myhome_attribute is null !!! - {toBasicString()}"); var myhome_guid = myhome_attribute.MyhomeGuid; if (false == foundOwnerEntities.TryAdd(myhome_guid, myhome)) { err_msg = $"Already added MyhomeGuid !!! : myhomeGuid:{myhome_guid} - {toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcMetaGuidAlreadyAdded, err_msg); Log.getLogger().error(result.toBasicString()); continue; } } } else { err_msg = $"Can't fillup OwnerEntity !!!, Invalid OwnerEntityType : ownerEntityType:{ownerEntityType} - {toBasicString()}"; result.setFail(ServerErrorCode.OwnerEntityCannotFillup, err_msg); return result; } return result; } public async Task tryLoadUgcNpc(UgcNpc toLoadUgcNpc, UgcNpcDoc ugcNpcDoc) { var owner = getOwner() as Player; ArgumentNullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); ArgumentNullReferenceCheckHelper.throwIfNull(ugcNpcDoc, () => $"ugcNpcDoc is null !!! - {owner.toBasicString()}"); var result = new Result(); var err_msg = string.Empty; var doc_ugc_npc_attrib = ugcNpcDoc.getAttrib(); NullReferenceCheckHelper.throwIfNull(doc_ugc_npc_attrib, () => $"doc_ugc_npc_attrib is null !!! - {owner.toBasicString()}"); var ugc_npc_meta_guid = doc_ugc_npc_attrib.UgcNpcMetaGuid; using (m_ugc_npc_lock.Lock()) { var found_duplicated_ugc_npc = findUgcNpc(ugc_npc_meta_guid); if (null != found_duplicated_ugc_npc) { err_msg = $"Found duplicated UgcNpc from UgcNpcDoc !!! : duplicatedUgcNpc:{found_duplicated_ugc_npc.toBasicString()} - {ugcNpcDoc.toBasicString()}, {owner.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcDocLoadDuplicatedUgcNpc, err_msg); Log.getLogger().error(result.toBasicString()); return result; } var ugc_npc_action = toLoadUgcNpc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {owner.toBasicString()}"); result = await ugc_npc_action.createByUgcNpcDocWithMaster(ugcNpcDoc, owner); if (result.isFail()) { return result; } if (false == m_ugc_npcs.TryAdd(ugc_npc_meta_guid, toLoadUgcNpc)) { err_msg = $"Failed to TryAdd() !!! : {toLoadUgcNpc.toBasicString()} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcDocLoadDuplicatedUgcNpc, err_msg); Log.getLogger().error(result.toBasicString()); return result; } owner.attachSummenedEntityGuid(ugc_npc_meta_guid); toLoadUgcNpc.attachMasterGuid(owner.getUserGuid()); } return result; } public async Task tryAttachUgcNpcInGameZone(UgcNpc toAttachUgcNpcInGameZone) { var owner = getOwner() as Player; ArgumentNullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); ArgumentNullReferenceCheckHelper.throwIfNull(toAttachUgcNpcInGameZone, () => $"toAttachUgcNpcInGameZone is null !!! - {owner.toBasicString()}"); var result = new Result(); var err_msg = string.Empty; var ugc_npc_attribute = toAttachUgcNpcInGameZone.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {owner.toBasicString()}"); var ugc_npc_meta_guid = ugc_npc_attribute.UgcNpcMetaGuid; using (m_ugc_npc_lock.Lock()) { if (false == m_ugc_npcs.TryAdd(ugc_npc_meta_guid, toAttachUgcNpcInGameZone)) { err_msg = $"Failed to TryAdd() !!! : {toAttachUgcNpcInGameZone.toBasicString()} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcDocLoadDuplicatedUgcNpc, err_msg); Log.getLogger().error(result.toBasicString()); return result; } owner.attachSummenedEntityGuid(ugc_npc_meta_guid); toAttachUgcNpcInGameZone.attachMasterGuid(owner.getUserGuid()); } return await Task.FromResult(result); } public async Task<(Result, UgcNpc?, NpcLocationInTargetDoc?)> tryLocateUgcNpcToMyhome(string myhomeGuid, int myhomeInstanceMetaId, NpcLocation npcLocation, UGC_NPC_META_GUID selectedUgcNpcMetaGuid) { var result = new Result(); var err_msg = string.Empty; var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"owner is null !!!"); var server_logic = GameServerApp.getServerLogic(); NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic is null !!! - {player.toBasicString()}"); var dynamo_db_client = server_logic.getDynamoDbClient(); NullReferenceCheckHelper.throwIfNull(dynamo_db_client, () => $"dynamo_db_client is null !!! - {player.toBasicString()}"); //예외 체크 !!! //1. 해당 UgcNpc의 사용 상태를 체크 한다. var located_ugc_npc = findUgcNpc(selectedUgcNpcMetaGuid); if (located_ugc_npc == null) { err_msg = $"UgcNpc Not Found UgcNpc Guid : {selectedUgcNpcMetaGuid} - {player.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } var ugc_npc_attribute = located_ugc_npc.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!!"); if (ugc_npc_attribute.State != EntityStateType.None) { err_msg = $"UgcNpc is Busy : UgcNpcGuid{selectedUgcNpcMetaGuid} - {located_ugc_npc.toBasicString()}, {player.toBasicString()}"; result.setFail(ServerErrorCode.NpcIsBusy, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } ugc_npc_attribute.LocatedInstanceGuid = myhomeGuid; ugc_npc_attribute.LocatedInstanceMetaId = (META_ID)myhomeInstanceMetaId; var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!! - {player.toBasicString()}"); var curr_map = game_zone_action.getLinkedToMap(); NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!! - {player.toBasicString()}"); var ugc_npc_action = located_ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {player.toBasicString()}"); ugc_npc_action.modifyStateInfo(EntityStateType.UsingByMyHome, npcLocation.CurrentPos, npcLocation.AnchorMetaGuid); var location_unique_id = curr_map.makeLOCATION_UNIQUE_IDByMetaIdWithLocationTargetType(LocationTargetType.Instance, myhomeGuid); //2. NpcLocationInTargetDoc를 신규 등록 설정 한다. var npc_location_in_target_doc = new NpcLocationInTargetDoc( location_unique_id, npcLocation.AnchorMetaGuid , EntityType.UgcNpc, ugc_npc_attribute.UgcNpcMetaGuid, npcLocation , ugc_npc_attribute.OwnerEntityType, ugc_npc_attribute.OwnerGuid ); result = await dynamo_db_client.simpleUpsertDocumentWithDocType(npc_location_in_target_doc); if (result.isFail()) { err_msg = $"Failed to simpleUpsertDocumentWithDocType() !!! : {npc_location_in_target_doc.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } return (result, located_ugc_npc, npc_location_in_target_doc); } public async Task<(Result, UgcNpc?, NpcLocationInTargetDoc?)> tryReleaseUgcNpcFromMyhome(string myhomeGuid, string anchorGuid, string ugcNpcGuid) { var result = new Result(); var err_msg = string.Empty; var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"owner is null !!!"); var server_logic = GameServerApp.getServerLogic(); NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic is null !!! - {player.toBasicString()}"); var dynamo_db_client = server_logic.getDynamoDbClient(); NullReferenceCheckHelper.throwIfNull(dynamo_db_client, () => $"dynamo_db_client is null !!! - {player.toBasicString()}"); var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!! - {player.toBasicString()}"); var curr_map = game_zone_action.getLinkedToMap(); NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!! - {player.toBasicString()}"); var ugc_npc = findUgcNpc(ugcNpcGuid); NullReferenceCheckHelper.throwIfNull(ugc_npc, () => $"ugc_npc is null !!! - {player.toBasicString()}"); var ugc_npc_action = ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {player.toBasicString()}"); ugc_npc_action.modifyStateInfo(EntityStateType.None, new EntityPos(), ""); var ugc_npc_attribute = ugc_npc.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {player.toBasicString()}"); ugc_npc_attribute.LocatedInstanceGuid = string.Empty; ugc_npc_attribute.LocatedInstanceMetaId = 0; var location_unique_id = curr_map.makeLOCATION_UNIQUE_IDByMetaIdWithLocationTargetType(LocationTargetType.Instance, myhomeGuid); var npc_location_in_target_doc = new NpcLocationInTargetDoc(location_unique_id, anchorGuid); result = await dynamo_db_client.simpleDeleteDocumentWithDocType(npc_location_in_target_doc); if (result.isFail()) { err_msg = $"Failed to simpleDeleteDocumentWithDocType() !!! : {npc_location_in_target_doc.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } return (result, ugc_npc, npc_location_in_target_doc); } public async Task<(Result, UgcNpc?, NpcLocationInTargetDoc?)> tryModifyUgcNpcToMyhome(string myhomeGuid, NpcLocation npcLocation, UGC_NPC_META_GUID selectedUgcNpcMetaGuid, EntityStateType ugcNpcState, META_ID metaId = 0) { var result = new Result(); var err_msg = string.Empty; var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"owner is null !!!"); var server_logic = GameServerApp.getServerLogic(); NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic is null !!! - {player.toBasicString()}"); var dynamo_db_client = server_logic.getDynamoDbClient(); NullReferenceCheckHelper.throwIfNull(dynamo_db_client, () => $"dynamo_db_client is null !!! - {player.toBasicString()}"); var located_ugc_npc = findUgcNpc(selectedUgcNpcMetaGuid); if (located_ugc_npc == null) { err_msg = $"UgcNpc Not Found UgcNpc Guid : {selectedUgcNpcMetaGuid} - {player.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } var ugc_npc_attribute = located_ugc_npc.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {player.toBasicString()}"); if (ugc_npc_attribute.AnchorMetaGuid != npcLocation.AnchorMetaGuid) { err_msg = $"AnchorMetaGuid is not Match : UgcNpcGuid{selectedUgcNpcMetaGuid} - {located_ugc_npc.toBasicString()}, {player.toBasicString()}"; result.setFail(ServerErrorCode.AnchorIsNotInMyhome, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!! - {player.toBasicString()}"); var curr_map = game_zone_action.getLinkedToMap(); NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!! - {player.toBasicString()}"); var ugc_npc_action = located_ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {player.toBasicString()}"); ugc_npc_action.modifyStateInfo(ugcNpcState, npcLocation.CurrentPos, npcLocation.AnchorMetaGuid, metaId); var location_unique_id = curr_map.makeLOCATION_UNIQUE_IDByMetaIdWithLocationTargetType(LocationTargetType.Instance, myhomeGuid); var npc_location_in_target_doc = new NpcLocationInTargetDoc(location_unique_id, npcLocation.AnchorMetaGuid , EntityType.UgcNpc, ugc_npc_attribute.UgcNpcMetaGuid, npcLocation , ugc_npc_attribute.OwnerEntityType, ugc_npc_attribute.OwnerGuid); result = await dynamo_db_client.simpleUpsertDocumentWithDocType(npc_location_in_target_doc); if (result.isFail()) { err_msg = $"Failed to simpleUpsertDocumentWithDocType() !!! : {npc_location_in_target_doc.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } return (result, located_ugc_npc, npc_location_in_target_doc); } public async Task tryDeleteUgcNpc(string toDeleteUgcNpcNickname) { await Task.CompletedTask; var result = new Result(); var err_msg = string.Empty; var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var fn_ugc_npc_delete = async delegate () { var result = new Result(); UGC_NPC_META_GUID found_ugc_npc_meta_guid = string.Empty; UgcNpc? to_delete_ugc_npc_nullable = null; var server_logic = GameServerApp.getServerLogic(); NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic is null !!! - {owner.toBasicString()}"); foreach (var each in m_ugc_npcs) { var ugc_npc_meta_guid = each.Key; var ugc_npc = each.Value; var ugc_npc_action = ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {owner.toBasicString()}"); if(false == ugc_npc_action.isEqualUgcNpc(toDeleteUgcNpcNickname)) { continue; } found_ugc_npc_meta_guid = ugc_npc_meta_guid; if (true == ugc_npc_action.isLocatedUgcNpc()) { err_msg = $"UgcNpc located state !!! : {ugc_npc.toSummaryString()} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcLocatedState, err_msg); continue; } (result, _) = await ugc_npc_action.tryDelete(); if (result.isFail()) { return result; } to_delete_ugc_npc_nullable = ugc_npc; break; } if (null == to_delete_ugc_npc_nullable) { err_msg = $"Not found UgcNpc !!! : ugcNpcNickname:{toDeleteUgcNpcNickname} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().warn(result.toBasicString()); return result; } var batch = new QueryBatchEx( owner, LogActionType.ItemUse , server_logic.getDynamoDbClient() , true); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); batch.addQuery(new QueryFinal(), async (_query) => { await Task.CompletedTask; var is_success = m_ugc_npcs.TryRemove(found_ugc_npc_meta_guid, out _); if(false == is_success) { err_msg = $"Failed to TryRemove() !!! : {to_delete_ugc_npc_nullable.toBasicString()} - {owner.toBasicString()}"; Log.getLogger().error(err_msg); } var found_transaction_runner = owner.findTransactionRunner(TransactionIdType.PrivateContents); NullReferenceCheckHelper.throwIfNull(found_transaction_runner, () => $"found_transaction_runner is null !!! - {owner.toBasicString()}"); UgcNpcNotifyHelper.send_GS2C_NTF_UGC_NPC_DELETION(owner, found_ugc_npc_meta_guid, found_transaction_runner.getCommonResult()); return QueryBatchBase.QueryResultType.Success; }); } result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { return result; } return result; }; result = await owner.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "UgcNpcDeletion", fn_ugc_npc_delete); if (result.isFail()) { err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {owner.toBasicString()}"; Log.getLogger().error(err_msg); } return result; } public async Task trySellUgcNpc(UGC_NPC_META_GUID toSellUgcNpcMetaGuid) { await Task.CompletedTask; var result = new Result(); var err_msg = string.Empty; var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var found_ugc_npc = findUgcNpc(toSellUgcNpcMetaGuid); if(null == found_ugc_npc) { err_msg = $"Not found UgcNpc !!! : ugcNpcMetaGuid:{toSellUgcNpcMetaGuid} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().warn(result.toBasicString()); return result; } var ugc_npc_action = found_ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {owner.toBasicString()}"); if (true == ugc_npc_action.isLocatedUgcNpc()) { err_msg = $"UgcNpc located state !!! : {found_ugc_npc.toSummaryString()} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcLocatedState, err_msg); return result; } var ugc_npc_attribute = found_ugc_npc.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {owner.toBasicString()}"); if (false == MetaData.Instance.Meta.BeaconNpcMetaTable.BeaconNpcMetaDataListbyId.TryGetValue((Int32)ugc_npc_attribute.BodyItemMetaId, out var found_beacon_npc_meta)) { err_msg = $"Not found BeaconNpcMetaData !!! : bodyItemMetaId:{ugc_npc_attribute.BodyItemMetaId} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcMetaDataNotFound, err_msg); return result; } var check_item = ShopHelper.checkItemIdFromTableData(found_beacon_npc_meta.BeaconItemID); if (check_item.result.isFail() || null == check_item.item_data) { Log.getLogger().error(check_item.result.ResultString); return check_item.result; } var money_action = owner.getEntityAction(); NullReferenceCheckHelper.throwIfNull(money_action); var check_currency_type = ShopHelper.checkCurrencyTypeFromCurrencyId(check_item.item_data.SellId); if (check_currency_type.result.isFail()) { return check_currency_type.result; } result = await money_action.earnMoney(check_currency_type.currencyType, check_item.item_data.SellPrice); if (result.isFail()) { return result; } (result, _) = await ugc_npc_action.tryDelete(); if (result.isFail()) { return result; } return result; } public async Task<(Result, FarmingAction?)> selectFarmingAction(FarmingSummonedEntityType entityType, OWNER_GUID ownerGuid) { var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var result = new Result(); var err_msg = string.Empty; FarmingAction? seleted_farming_action = null; switch (entityType) { case FarmingSummonedEntityType.User: { if(player.getUserGuid() == ownerGuid) { seleted_farming_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(seleted_farming_action, () => $"seleted_farming_action is null !!! - {player.toBasicString()}"); } } break; case FarmingSummonedEntityType.Beacon: { var player_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {player.toBasicString()}"); var found_ugc_npc = player_action.findUgcNpc(ownerGuid); if(null == found_ugc_npc) { err_msg = $"Not found UgcNpc !!! : ugcNpcGuid:{ownerGuid} - {player.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); return (result, null); } seleted_farming_action = found_ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(seleted_farming_action, () => $"seleted_farming_action is null !!! - {player.toBasicString()}"); } break; default: err_msg = $"Invalid FarmingSummonedEntityType !!! : FarmingSummonedEntityType:{entityType} - {player.toBasicString()}"; result.setFail(ServerErrorCode.FarmingSummonedEntityTypeInvalid, err_msg); return (result, null); } return await Task.FromResult<(Result, FarmingAction?)>((result, seleted_farming_action)); } public async Task tryLoadCharacter(Character toLoadCharacter, CharacterBaseDoc characterBaseDoc) { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); ArgumentNullReferenceCheckHelper.throwIfNull(characterBaseDoc, () => $"characterBaseDoc is null !!! - {owner.toBasicString()}"); var result = new Result(); var err_msg = string.Empty; var character_base_doc_attrib = characterBaseDoc.getAttrib(); NullReferenceCheckHelper.throwIfNull(character_base_doc_attrib, () => $"character_base_doc_attrib is null !!! - {owner.toBasicString()}"); var character_guid = character_base_doc_attrib.CharacterGuid; using (m_characters_lock.Lock()) { var found_duplicated_character = findCharacter(character_guid); if (null != found_duplicated_character) { err_msg = $"Found duplicated Character from CharacterBaseDoc !!! : duplicatedItem:{found_duplicated_character.toBasicString()} - {characterBaseDoc.toBasicString()}, {owner.toBasicString()}"; result.setFail(ServerErrorCode.CharacterBaseDocLoadDuplicatedCharacter, err_msg); Log.getLogger().error(result.toBasicString()); return result; } result = await toLoadCharacter.createByCharacterBaseDoc(characterBaseDoc); if (result.isFail()) { return result; } if (false == m_characters.TryAdd(character_guid, toLoadCharacter)) { err_msg = $"Failed to TryAdd() !!! : {toLoadCharacter.toBasicString()} - {owner.toBasicString()}"; result.setFail(ServerErrorCode.CharacterBaseDocLoadDuplicatedCharacter, err_msg); Log.getLogger().error(result.toBasicString()); return result; } } var user_attribute = owner.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!! - {owner.toBasicString()}"); if (user_attribute.SelectedCharacterGuid == character_guid) { setSelectedCharacter(toLoadCharacter); } return result; } public Character? findCharacter(CHARACTER_GUID characterGuid) { if(false == m_characters.TryGetValue(characterGuid, out var found_character)) { return null; } return found_character; } public Int32 getHadUgcNpcCount() { return m_ugc_npcs.Count(); } public ConcurrentDictionary getHadUgcNpcs() { return m_ugc_npcs; } public bool hasSelectedCharacter() { return 0 < m_characters.Count; } public Character? getSelectedCharacter() { return m_selected_character_nullable; } public void setSelectedCharacter(Character character) { m_selected_character_nullable = character; } public GameCharacter toSelectedPlayerInfo() { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var server_logic = GameServerApp.getServerLogic(); NullReferenceCheckHelper.throwIfNull(server_logic, () => $"owner is null !!! - {owner.toBasicString()}"); var user_craete_or_load_action = owner.getEntityAction(); NullReferenceCheckHelper.throwIfNull(user_craete_or_load_action, () => $"user_craete_or_load_action is null !!! - {owner.toBasicString()}"); var character_info = new GameCharacter(); try { var account_attribute = owner.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(account_attribute); character_info.CharInfo = new(); character_info.CharInfo.LanguageInfo = (Int32)account_attribute.LanguageType; character_info.CharInfo.Usergroup = account_attribute.AuthAdminLevelType.ToString(); character_info.CharInfo.Operator = (Int32)account_attribute.AuthAdminLevelType; var channel_no = server_logic.getChannelNo(); var connected_count = server_logic.getProudNetListener().getEntityWithSessions().Count(); var reserved_count = server_logic.getReservationManager().getReservedUserCount(); var return_count = server_logic.getReturnManager().getReturnUserCount(); character_info.ChannelInfo = new(); character_info.ChannelInfo.Channel = (Int32)channel_no; character_info.ChannelInfo.Trafficlevel = server_logic.getChannelManager().getTrafficLevel( connected_count + reserved_count + return_count + UgcNpcCountManager.Instance.calculateNpcCount() , server_logic.getProudNetListener().getMaxConnectionCount() ); var user_attribute = owner.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(user_attribute); character_info.CharInfo.IsIntroComplete = user_attribute.IsIntroCompleted == true ? 1 : 0; if (false == user_craete_or_load_action.hasUserCreateTrigger()) { var nickname_attribute = owner.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(nickname_attribute); character_info.CharInfo.DisplayName = nickname_attribute.Nickname; var level_attribute = owner.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(level_attribute); character_info.CharInfo.Level = (Int32)level_attribute.Level; character_info.CharInfo.Exp = (Int32)level_attribute.Exp; var money_attribute = owner.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(money_attribute); character_info.CharInfo.Gold = money_attribute.Gold; character_info.CharInfo.Sapphire = money_attribute.Sapphire; character_info.CharInfo.Calium = money_attribute.Calium; character_info.CharInfo.Ruby = money_attribute.Ruby; character_info.CharPos = new(); var location_action = owner.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action); character_info.CharPos.Pos = location_action.getCurrentPos(); character_info.CharPos.MapId = location_action.getCurrentMapMId(); var inventory_action = owner.getEntityAction(); NullReferenceCheckHelper.throwIfNull(inventory_action); character_info.Inventory = inventory_action.toBagInven4Client(); character_info.ClothInfo = inventory_action.toClothInven4Client(); character_info.ToolSlot.AddRange(inventory_action.toToolSlotInven4Client()); character_info.TattooInfoList.AddRange(inventory_action.toTattooSimple4Client()); character_info.SlotCount.AddRange(inventory_action.toSlotMaxCountOfBagAll4Client()); var item_tool_action = owner.getEntityAction(); NullReferenceCheckHelper.throwIfNull(item_tool_action, () => $"item_tool_action is null !!! - {owner.toBasicString()}"); character_info.EquipInfo = item_tool_action.toToolAction4Client(); } else { user_craete_or_load_action.fillUpUserInfo4Client(character_info.CharInfo); character_info.CharPos = new(); var location_action = owner.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action); character_info.CharPos.Pos = location_action.getCurrentPos(); var inventory_action = owner.getEntityAction(); NullReferenceCheckHelper.throwIfNull(inventory_action); character_info.ToolSlot.AddRange(inventory_action.toToolSlotInven4Client()); character_info.TattooInfoList.AddRange(inventory_action.toTattooSimple4Client()); character_info.SlotCount.AddRange(inventory_action.toSlotMaxCountOfBagAll4Client()); } if (true == user_craete_or_load_action.hasCharacterCreateTrigger()) { var reserved_character = user_craete_or_load_action.getReservedCharacterForCreation(); NullReferenceCheckHelper.throwIfNull(reserved_character); var character_attribute = reserved_character.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute); character_info.Guid = owner.getUserGuid(); // 클라이언트는 USER_GUID를 사용 한다. character_info.AvatarInfo = user_craete_or_load_action.toSelectedCharacterAppearanceProfile4Client(); } { var selected_character = getSelectedCharacter(); if (null != selected_character) { var character_attribute = selected_character.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute); character_info.Guid = owner.getUserGuid(); // 클라이언트는 USER_GUID를 사용 한다. character_info.AvatarInfo = character_attribute.AppearanceProfileValue.toCharacterAppearanceProfile4Client(); } } } catch(Exception e) { var err_msg = $"Exception !!!, Failed to perfom in toSelectedPlayerInfo() !!! : exception:{e} - {owner.toBasicString()}"; Log.getLogger().error(err_msg); } return character_info; } public Dictionary toUgcNpcSummaryAll4Client() { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var ugc_npc_summaries = new Dictionary(); foreach (var each in m_ugc_npcs) { var ugc_npc_meta_guid = each.Key; var ugc_npc = each.Value; ArgumentNullReferenceCheckHelper.throwIfNull(ugc_npc, () => $"ugc_npc is null !!! : ugcNpcMetaGuid:{ugc_npc_meta_guid} - {owner.toBasicString()}"); var ugc_npc_action = ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {ugc_npc.toBasicString()}, {owner.toBasicString()}"); if (false == ugc_npc_summaries.TryAdd(ugc_npc_meta_guid, ugc_npc_action.toUgcNpcSummary())) { var err_msg = $"Already added UgcNpc !!! : ugcNpcMetaGuid:{ugc_npc_meta_guid} - {owner.toBasicString()}"; Log.getLogger().error(err_msg); continue; } } return ugc_npc_summaries; } public Dictionary toUgcNpcItemsAll4Client() { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var ugc_npc_items = new Dictionary(); foreach (var each in m_ugc_npcs) { var ugc_npc_meta_guid = each.Key; var ugc_npc = each.Value; ArgumentNullReferenceCheckHelper.throwIfNull(ugc_npc, () => $"ugc_npc is null !!! : ugcNpcMetaGuid:{ugc_npc_meta_guid} - {owner.toBasicString()}"); var ugc_npc_action = ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {ugc_npc.toBasicString()}, {owner.toBasicString()}"); if (false == ugc_npc_items.TryAdd(ugc_npc_meta_guid, ugc_npc_action.toUgcNpcItems())) { var err_msg = $"Already added UgcNpcItems !!! : ugcNpcMetaGuid:{ugc_npc_meta_guid} - {owner.toBasicString()}"; Log.getLogger().error(err_msg); continue; } } return ugc_npc_items; } public async Task tryRegisterFailedNpcToAiChatServer() { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var result = new Result(); foreach (var each in m_ugc_npcs) { var ugc_npc_attribute = each.Value.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute); if(ugc_npc_attribute.IsRegisteredAiChatServer == true) continue; var ugc_npc_action = each.Value.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action); result = await ugc_npc_action.tryRegisterCharacterWithAiChatServer(owner); if (result.isFail()) { return result; } } return result; } }