Files
2025-05-01 07:20:41 +09:00

970 lines
42 KiB
C#

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<CHARACTER_GUID, Character> m_characters = new();
private AsyncLock m_characters_lock = new();
private Character? m_selected_character_nullable = null;
private ConcurrentDictionary<UGC_NPC_META_GUID, UgcNpc> m_ugc_npcs = new();
private AsyncLock m_ugc_npc_lock = new();
public PlayerAction(Player owner)
: base(owner)
{
}
public override async Task<Result> 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<Result> 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<UgcNpcAttribute>();
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<string, EntityBase> 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<UserAttribute>();
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<MyhomeAgentAction>();
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<MyhomeAttribute>();
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<Result> 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<UgcNpcAttrib>();
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<UgcNpcAction>();
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<Result> 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<UgcNpcAttribute>();
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<UgcNpcAttribute>();
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<GameZoneAction>();
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<UgcNpcAction>();
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<GameZoneAction>();
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<UgcNpcAction>();
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<UgcNpcAttribute>();
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<UgcNpcAttribute>();
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<GameZoneAction>();
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<UgcNpcAction>();
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<Result> 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<UgcNpcAction>();
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<QueryRunnerWithDocument>( 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<Result> 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<UgcNpcAction>();
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<UgcNpcAttribute>();
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<MoneyAction>();
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<FarmingAction>();
NullReferenceCheckHelper.throwIfNull(seleted_farming_action, () => $"seleted_farming_action is null !!! - {player.toBasicString()}");
}
} break;
case FarmingSummonedEntityType.Beacon:
{
var player_action = player.getEntityAction<PlayerAction>();
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<FarmingAction>();
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<Result> 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<CharacterBaseAttrib>();
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<UserAttribute>();
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<UGC_NPC_META_GUID, UgcNpc> 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<UserCreateOrLoadAction>();
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<AccountAttribute>();
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<UserAttribute>();
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<NicknameAttribute>();
NullReferenceCheckHelper.throwIfNull(nickname_attribute);
character_info.CharInfo.DisplayName = nickname_attribute.Nickname;
var level_attribute = owner.getEntityAttribute<LevelAttribute>();
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<MoneyAttribute>();
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<LocationAction>();
NullReferenceCheckHelper.throwIfNull(location_action);
character_info.CharPos.Pos = location_action.getCurrentPos();
character_info.CharPos.MapId = location_action.getCurrentMapMId();
var inventory_action = owner.getEntityAction<InventoryActionBase>();
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<ItemToolAction>();
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<LocationAction>();
NullReferenceCheckHelper.throwIfNull(location_action);
character_info.CharPos.Pos = location_action.getCurrentPos();
var inventory_action = owner.getEntityAction<InventoryActionBase>();
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<CharacterAttribute>();
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<CharacterAttribute>();
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<UGC_NPC_META_GUID, UgcNpcSummary> toUgcNpcSummaryAll4Client()
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var ugc_npc_summaries = new Dictionary<UGC_NPC_META_GUID, UgcNpcSummary>();
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<UgcNpcAction>();
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<UGC_NPC_META_GUID, UgcNpcItems> toUgcNpcItemsAll4Client()
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var ugc_npc_items = new Dictionary<UGC_NPC_META_GUID, UgcNpcItems>();
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<UgcNpcAction>();
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<Result> 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<UgcNpcAttribute>();
NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute);
if(ugc_npc_attribute.IsRegisteredAiChatServer == true) continue;
var ugc_npc_action = each.Value.getEntityAction<UgcNpcAction>();
NullReferenceCheckHelper.throwIfNull(ugc_npc_action);
result = await ugc_npc_action.tryRegisterCharacterWithAiChatServer(owner);
if (result.isFail())
{
return result;
}
}
return result;
}
}