초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,258 @@
using MetaAssets;
using Microsoft.IdentityModel.Tokens;
using ServerCommon;
using ServerCore; using ServerBase;
namespace GameServer
{
public class AbilityAction : EntityActionBase
{
private Dictionary<AttributeType, int> m_abilities { get; set; } = new();
public AbilityAction(EntityBase owner)
: base(owner)
{
}
public override async Task<Result> onInit()
{
await Task.CompletedTask;
var result = new Result();
clearAbility();
return result;
}
public override void onClear()
{
return;
}
public void clearAbility()
{
foreach (var ability in EnumHelper.getValuesWithoutScope<AttributeType>())
{
m_abilities[ability] = 0;
}
}
public int? getAbility(AttributeType abilityId) => m_abilities.TryGetValue(abilityId, out var ability) ? ability : null;
public Dictionary<AttributeType, int> getAbilities() => m_abilities;
public async Task<Result> forceResetAll()
{
clearAbility();
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!! - {toBasicString()}");
var inventory_action_base = owner.getEntityAction<InventoryActionBase>();
NullReferenceCheckHelper.throwIfNull(inventory_action_base, () => $"inventory_action_base is null !!! - {owner.toBasicString()}");
var result = await inventory_action_base.tryResetAttributeByTattoo();
if(result.isFail())
{
return result;
}
var buff_action = owner.getEntityAction<BuffAction>();
NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff_action is null !!! - {owner.toBasicString()}");
result = await buff_action.tryResetAttributeByBuff();
if (result.isFail())
{
return result;
}
return result;
}
public void forceSetAbilityAll(int toSetAbility)
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!! - {toBasicString()}");
var attribute_types = EnumHelper.getValuesWithoutScopeAll<AttributeType>();
foreach (var attribute_type in attribute_types)
{
m_abilities[attribute_type] = toSetAbility;
}
}
public void setAbility(AttributeType abilityId, int ability, bool decrease)
{
var change_value = decrease ? ability * -1 : ability;
m_abilities[abilityId] += change_value;
}
public async Task<Result> setAbilities(ItemBase item, Int16 level, bool decrease)
{
ArgumentNullReferenceCheckHelper.throwIfNull(item, () => $"item is null !!! - {toBasicString()}");
await Task.CompletedTask;
var result = new Result();
string err_msg;
var item_attribute = item.getEntityAttribute<ItemAttributeBase>();
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {toBasicString()}");
var item_meta = item.getItemMeta();
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {toBasicString()}");
var enchant = getEnchantData(level, item_meta);
if (null == enchant)
{
err_msg = $"Fail to get enchant data : {nameof(getEnchantData)}";
result.setFail(ServerErrorCode.ItemEnchantNotFoundInMeta, err_msg);
Log.getLogger().error(err_msg);
return result;
}
// 배열의 위치를 AttributeType으로 활용하다보니 불필요한 예외 처리 코드를 작성해야 한다. !!!
// Key-Value 구조로 바꾸고 싶지만... 간단한 수정 범위는 아니다.
// MetaHelper를 통해 메타 데이터를 가공하는 방법도 있다.... - kangms
for(var i = 0; i < enchant.Count; i++)
{
if (false == EnumHelper.isDefined<AttributeType>(item_attribute.Attributes[i]))
{
Log.getLogger().warn($"Invalid Ability Enum Type : {item_attribute.Attributes[i]}");
continue;
}
if (item_attribute.Attributes.Count <= i)
{
Log.getLogger().warn($"Ability Type outof range !!! : enchantIndex:{i} > itemAttributeIndex:{i}");
item_attribute.Attributes.Add(0);
}
setAbility((AttributeType)item_attribute.Attributes[i], enchant[i], decrease);
}
return result;
}
public async Task<Result> changeAbilities(ItemBase item, Dictionary<int, int> slotWithAttributeIds, bool decrease)
{
await Task.CompletedTask;
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
ArgumentNullReferenceCheckHelper.throwIfNull(item, () => $"item is null !!! - {owner.toBasicString()}");
ArgumentNullReferenceCheckHelper.throwIfNull(slotWithAttributeIds, () => $"slotWithAttributeIds is null !!! - {owner.toBasicString()}");
var result = new Result();
string err_msg;
var item_attribute = item.getEntityAttribute<ItemAttributeBase>();
NullReferenceCheckHelper.throwIfNull(item_attribute, () => $"item_attribute is null !!! - {owner.toBasicString()}");
var item_meta = item.getItemMeta();
NullReferenceCheckHelper.throwIfNull(item_meta, () => $"item_meta is null !!! - {owner.toBasicString()}");
var enchant = getEnchantData(item_attribute.Level, item_meta);
if (null == enchant)
{
err_msg = $"Fail to get enchant data : {nameof(getEnchantData)}";
result.setFail(ServerErrorCode.ItemEnchantNotFoundInMeta, err_msg);
Log.getLogger().error(err_msg);
return result;
}
foreach (var each in slotWithAttributeIds)
{
if (false == EnumHelper.isDefined<AttributeType>(each.Value))
{
Log.getLogger().warn($"Invalid Ability Enum Type : {each.Value}");
continue;
}
// 배열의 위치를 AttributeType으로 활용하다보니 불필요한 예외 처리 코드를 작성해야 한다. !!!
// Key-Value 구조로 바꾸고 싶지만... MetaHelper를 통해 메타 데이터를 가공하는 방법도 있다.... - kangms
if (each.Key >= enchant.Count)
{
Log.getLogger().warn($"Ability Type outof range !!! : enchantCount:{enchant.Count} > slotWithAttributeIndex:{each.Key}");
continue;
}
setAbility((AttributeType)each.Value, enchant[each.Key], decrease);
}
return result;
}
public Result hasAbilities(Dictionary<string, Int32> toCheckAbilities)
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!! - {toBasicString()}");
ArgumentNullReferenceCheckHelper.throwIfNull(toCheckAbilities, () => $"toCheckAbilities is null !!! - {owner.toBasicString()}");
var result = new Result();
var err_msg = string.Empty;
var ability_action = owner.getEntityAction<AbilityAction>();
NullReferenceCheckHelper.throwIfNull(ability_action, () => $"ability_action is null !!! - {toBasicString()}");
foreach (var each in toCheckAbilities)
{
var ability_name = each.Key;
var ability_value = each.Value;
if (false == EnumHelper.tryParse<AttributeType>(ability_name, out var attribute_type))
{
err_msg = $"Invalid Ability Enum Type : {attribute_type} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.ServerTypeInvalid, err_msg);
Log.getLogger().error(err_msg);
return result;
}
var curr_value = ability_action.getAbility(attribute_type);
if (curr_value == null)
{
err_msg = $"Invalid Ability Enum Type : {attribute_type} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.ServerTypeInvalid, err_msg);
Log.getLogger().error(err_msg);
return result;
}
if (curr_value < ability_value)
{
err_msg = $"Not enough Ability !!! : AbilityName:{attribute_type}, currValue:{curr_value} >= reqValue:{ability_value} - {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.AbilityNotEnough, err_msg);
Log.getLogger().info(err_msg);
return result;
}
}
return result;
}
private IReadOnlyList<int>? getEnchantData(int level, MetaAssets.ItemMetaData item)
{
ArgumentNullReferenceCheckHelper.throwIfNull(item, () => $"item is null !!! - {toBasicString()}");
if (false == MetaData.Instance._ItemLevelEnchantMetaTable.TryGetValue(level, out var enchant_by_level))
{
return null;
}
var enchant = enchant_by_level.GetConsumeItem(item.Rarity);
return enchant?.AttributeValues;
}
public AbilityInfo toAbilityInfo()
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var ability_info = new AbilityInfo();
foreach(var each in m_abilities)
{
ability_info.Values.Add((Int16)each.Key, each.Value);
}
return ability_info;
}
}
}

View File

@@ -0,0 +1,969 @@
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;
}
}

View File

@@ -0,0 +1,445 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using Amazon.DynamoDBv2.Model;
using Org.BouncyCastle.Tls.Crypto.Impl.BC;
using ServerCore; using ServerBase;
using ServerCommon;
using UGQDatabase.Models;
using MetaAssets;
using META_ID = System.UInt32;
namespace GameServer
{
internal static class PlayerHelper
{
public static GameActor toGameActor(this Player player)
{
var user_create_or_load_action = player.getEntityAction<UserCreateOrLoadAction>();
ArgumentNullException.ThrowIfNull(user_create_or_load_action);
var player_action = player.getEntityAction<PlayerAction>();
ArgumentNullException.ThrowIfNull(player_action);
var inventory_action = player.getEntityAction<InventoryActionBase>();
ArgumentNullException.ThrowIfNull(inventory_action);
var cloth_info = inventory_action.toClothInven4Client();
NullReferenceCheckHelper.throwIfNull(cloth_info, () => $"cloth_info is null !!!");
var location_action = player.getEntityAction<LocationAction>();
ArgumentNullException.ThrowIfNull(location_action);
var pos = location_action.getCurrentPos();
var buff_attribute = player.getOriginEntityAttribute<BuffAttribute>();
ArgumentNullException.ThrowIfNull(buff_attribute);
var account_attribute = player.getOriginEntityAttribute<AccountAttribute>();
ArgumentNullException.ThrowIfNull(account_attribute);
var user_attribute = player.getEntityAttribute<UserAttribute>();
ArgumentNullException.ThrowIfNull(user_attribute);
var item_tool_action = player.getEntityAction<ItemToolAction>();
ArgumentNullException.ThrowIfNull(item_tool_action);
GameActor game_actor = new();
game_actor.ActorGuid = player.getUserGuid();
game_actor.Name = player.getAccountId();
var selected_character = player_action.getSelectedCharacter();
if (null != selected_character)
{
var character_attribute = selected_character.getEntityAttribute<CharacterAttribute>();
ArgumentNullException.ThrowIfNull(character_attribute, $"character_attribute is null !!!");
game_actor.EntityStateInfo = character_attribute.StateInfo;
game_actor.AvatarInfo = selected_character.getOriginAppearanceProfile().toCharacterAppearanceProfile4Client();
}
else
{
game_actor.AvatarInfo = user_create_or_load_action.toSelectedCharacterAppearanceProfile4Client();
}
game_actor.ClothInfo = cloth_info.toClothInfoOfAnotherUser();
game_actor.Pos = pos;
game_actor.TattooInfoList.AddRange(inventory_action.toTattooInven4Client());
game_actor.BuffInfo = new();
game_actor.BuffInfo.Buff.AddRange(buff_attribute.toBuffData4Client());
game_actor.Usergroup = account_attribute.AuthAdminLevelType.ToString();
game_actor.Operator = (int)account_attribute.AuthAdminLevelType;
game_actor.DisplayName = player.getUserNickname();
game_actor.OccupiedAnchorGuid = user_attribute.OccupiedAnchorGuid;
game_actor.EquipInfo = item_tool_action.toToolAction4Client();
game_actor.State = (int)user_attribute.PlayerState;
game_actor.HostId = (int)player.getHostId();
return game_actor;
}
public static async Task<Result> checkRequirement(this Player player, int requirementMetaId)
{
var result = new Result();
var err_msg = string.Empty;
if (requirementMetaId == 0)
return result;
if (!MetaData.Instance._RequirementMetaTable.TryGetValue(requirementMetaId, out var requirement_meta_data))
{
err_msg = $"Failed to TryGetValue() !!! : requirementMetaId:{requirementMetaId}";
result.setFail(ServerErrorCode.RequirementMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
foreach (var requireAttribute in requirement_meta_data.Attributes)
{
if (EnumHelper.tryParse<AttributeType>(requireAttribute.Type, out var attribute_enum) == false)
{
err_msg = $"Enum Pase Failed. AttributeType : {requireAttribute.Type}";
result.setFail(ServerErrorCode.BuffInvalidAttributeType, err_msg);
Log.getLogger().error(err_msg);
return result;
}
var ability_action = player.getEntityAction<AbilityAction>();
ArgumentNullException.ThrowIfNull(ability_action);
var attribute_value = ability_action.getAbility(attribute_enum);
if (attribute_value < requireAttribute.Value)
{
err_msg = $"Not Requirement Attribute Value:{requireAttribute.Value} : current:{attribute_value}";
result.setFail(ServerErrorCode.NotRequireAttributeValue, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
foreach (var requireItem in requirement_meta_data.Items)
{
var inventory_action = player.getEntityAction<InventoryActionBase>();
ArgumentNullException.ThrowIfNull(inventory_action);
switch (requireItem.Type)
{
case MetaAssets.ERequirementItemType.OWNS:
{
var item_count = inventory_action.getBagInven().getItemStackCountAllByMetaId((uint)requireItem.ID);
if (item_count < requireItem.Value)
{
err_msg = $"Not Requirement Item Owns ItemMetaId:{requireItem.ID} : value:{requireItem.Value} : currnet:{item_count}";
result.setFail(ServerErrorCode.NotRequireAttributeValue, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
break;
case MetaAssets.ERequirementItemType.EQUIP:
{
if (!MetaData.Instance._ItemTable.TryGetValue(requireItem.ID, out var item_meta_data))
{
err_msg = $"Failed to TryGetValue() !!! : itemMetaId:{requireItem.ID}";
result.setFail(ServerErrorCode.ItemMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (item_meta_data.TypeLarge == EItemLargeType.TOOL)
{
var item_tool_action = player.getEntityAction<ItemToolAction>();
ArgumentNullException.ThrowIfNull(inventory_action);
var current_tool_item_meta_Id = item_tool_action.getCurrentToolItemMetaId();
if (current_tool_item_meta_Id != requireItem.ID)
{
err_msg = $"Not Requirement Item Equip ItemMetaId:{requireItem.ID} : currnet:{current_tool_item_meta_Id}";
result.setFail(ServerErrorCode.NotRequireAttributeValue, err_msg);
Log.getLogger().error(err_msg);
return result;
}
break;
}
var item_small_type = item_meta_data.TypeSmall;
var inven_rule = GameServerApp.getServerLogic().findRule<InventoryRule>();
if (null == inven_rule)
{
err_msg = $"Not found InventoryRule !!!";
result.setFail(ServerErrorCode.InventoryRuleNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
var equip_rule_bases = inven_rule.getEquipRuleBasesByItemLargeType(item_meta_data.TypeLarge);
if (null == equip_rule_bases)
{
err_msg = $"Not found EquipRuleBase !!! : ItemMetaId:{requireItem.ID}";
Log.getLogger().warn(err_msg);
continue;
}
foreach (var equip_rule in equip_rule_bases)
{
if (!inventory_action.getEquipInvens().TryGetValue(equip_rule.InvenEquipType, out var equip_inven_base))
{
err_msg = $"Not found EquipInven !!! : invenEquipType:{equip_rule.InvenEquipType}";
result.setFail(ServerErrorCode.EquipInvenNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
var inven_accessor = equip_inven_base as IWithInventoryAccessor;
ArgumentNullException.ThrowIfNull(inven_accessor, $"inven_accessor is null !!! - {player.toBasicString()}");
bool is_equiped = false;
foreach (var item_base in inven_accessor.getHasItemBases())
{
var item = item_base as Item;
ArgumentNullException.ThrowIfNull(item, $"item is null !!! - {player.toBasicString}");
var item_attribute = item.getOriginEntityAttribute<ItemAttributeBase>();
ArgumentNullException.ThrowIfNull(item_attribute, $"item_attribute is null !!! - {player.toBasicString}");
if (item_attribute.ItemMetaId == requireItem.ID)
{
is_equiped = true;
break;
}
}
if (false == is_equiped)
{
err_msg = $"Not found require Item !!! : ItemMetaId:{requireItem.ID} - InvenEquipType:{equip_rule.InvenEquipType}, {player.toBasicString()}";
result.setFail(ServerErrorCode.NotRequireAttributeValue, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
}
break;
case MetaAssets.ERequirementItemType.USE:
{
if (!MetaData.Instance._ItemTable.TryGetValue(requireItem.ID, out var item_meta_data))
{
err_msg = $"Failed to TryGetValue() !!! : itemMetaId:{requireItem.ID}";
result.setFail(ServerErrorCode.ItemMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
(result, var deleted_items) = await inventory_action.tryDeleteItemByMetaId((META_ID)requireItem.ID, (ushort)requireItem.Value);
if (result.isFail())
{
err_msg = $"Failed to tryDeleteItemByMeta() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
}
break;
default:
{
err_msg = $"Requirement Item Type Error !!! : type:{requireItem.Type}";
result.setFail(ServerErrorCode.NotRequireAttributeValue, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
}
foreach (var requireQuest in requirement_meta_data.Quests)
{
var quest_id = requireQuest.Value;
switch (requireQuest.Type)
{
case MetaAssets.ERequirementQuestType.ING:
{
var quest_action = player.getEntityAction<QuestAction>();
ArgumentNullException.ThrowIfNull(quest_action);
(result, var quest_meta_all_base_info) = await QuestMetaManager.It.getQuestMeta(quest_id);
if (result.isFail()) return result;
var quest_base_info = quest_meta_all_base_info.m_quest_base_info;
NullReferenceCheckHelper.throwIfNull(quest_base_info, () => $"quest_base_info is null !!!");
if (!quest_action.checkHasQuest(quest_base_info.QuestType, quest_id))
{
err_msg = $"Not Requirement Quest Ing Value:{requireQuest.Value}";
result.setFail(ServerErrorCode.NotRequireAttributeValue, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
break;
case MetaAssets.ERequirementQuestType.COMPLETED:
{
var end_quest_action = player.getEntityAction<EndQuestAction>();
ArgumentNullException.ThrowIfNull(end_quest_action);
if (!end_quest_action.hasEndQuest(requireQuest.Value))
{
err_msg = $"Not Requirement Quest Complete Value:{requireQuest.Value}";
result.setFail(ServerErrorCode.NotRequireAttributeValue, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
break;
default:
{
err_msg = $"Not Require Attribute Value !!! : type:{requireQuest.Type}";
result.setFail(ServerErrorCode.NotRequireAttributeValue, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
}
return result;
}
public static Result checkInstanceAccess(this Player player, int instanceMetaId)
{
var result = new Result();
var err_msg = string.Empty;
if (!MetaData.Instance._IndunTable.TryGetValue(instanceMetaId, out var instance_meta_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : instanceMetaId:{instanceMetaId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.InstanceMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
switch (instance_meta_data.AccessType)
{
case MetaAssets.AccessType.Public:
break;
case MetaAssets.AccessType.Item:
{
var inventory_action = player.getEntityAction<InventoryActionBase>();
ArgumentNullException.ThrowIfNull(inventory_action, $"inventory_action is null !!! - {player.toBasicString()}");
// todo(sangyeob.kim) : 추후에 아이템 수량 변경 등이 필요한 경우 meta_data 에 AccessCount 항목이 필요함
var item_count = inventory_action.getItemStackCountAllByMetaId((uint)instance_meta_data.AccessId);
if (item_count < 1)
{
err_msg = $"Not Enough Instance Access Item !!! itemMetaId:{instance_meta_data.AccessId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.NotExistInstanceTicket, err_msg);
// result.setFail(ServerErrorCode.InstanceAccessItemNotEnough, err_msg); // Todo(myounghwi) : 추후 에러코드 적용(클라와 이야기 필요)
Log.getLogger().error(err_msg);
return result;
}
}
break;
case MetaAssets.AccessType.Season:
{
var season_action = player.getEntityAction<SeasonPassAction>();
ArgumentNullException.ThrowIfNull(season_action, $"season_action is null !!! - {player.toBasicString()}");
if (season_action.isActivatedSeasonPass() == false)
{
err_msg = $"Not Season Period !!! - {player.toBasicString()}";
result.setFail(ServerErrorCode.SeasonPassNotAblePeriod, err_msg);
Log.getLogger().error(err_msg);
return result;
}
//AccessId가 0이면 시즌중이면 모두가 들어갈 수 있음. 1이면 시즌패스 구매자만 들어갈 수 있음.
if (instance_meta_data.AccessId == 0)
break;
var is_charged_season = season_action.isChargedSeasonPass();
if (false == is_charged_season)
{
err_msg = $"Not Charged SeasonPass Item !!! - {player.toBasicString()}";
result.setFail(ServerErrorCode.NotExistInstanceTicket, err_msg);
// result.setFail(ServerErrorCode.InstanceAccessSeasonPassNotCharged, err_msg); // Todo(myounghwi) : 추후 에러코드 적용(클라와 이야기 필요)
Log.getLogger().error(result.toBasicString());
return result;
}
}
break;
case MetaAssets.AccessType.Belong:
break;
default:
{
err_msg = $"AccessType Invalid !!! : type:{instance_meta_data.AccessType}, instanceMetaId:{instance_meta_data.Id} - {player.toBasicString()}";
result.setFail(ServerErrorCode.InstanceAccessTypeInvalid, err_msg);
Log.getLogger().error(err_msg);
return result;
}
}
return result;
}
public static async Task<Result> changeInstanceRoomIdAtLoginCache(this Player player, string instanceRoomId)
{
var result = new Result();
var err_msg = string.Empty;
var game_login_action = player.getEntityAction<GameLoginAction>();
ArgumentNullException.ThrowIfNull(game_login_action);
var login_cache_request = game_login_action.getLoginCacheRequest();
ArgumentNullException.ThrowIfNull(login_cache_request);
var login_cache = login_cache_request.getLoginCache();
ArgumentNullException.ThrowIfNull(login_cache);
login_cache.InstanceRoomId = instanceRoomId;
result = await login_cache_request.upsertLogin();
if (result.isFail())
{
err_msg = $"Failed to upsertLogin() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
return result;
}
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServerCore; using ServerBase;
using ServerCommon;
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 NICKNAME = System.String;
using CHARACTER_GUID = System.String;
using ITEM_GUID = System.String;
namespace GameServer
{
public class PlayerManager : UserManagerBase<USER_GUID, NICKNAME, Player>
{
public PlayerManager() { }
public async Task logoutUserAllByKick()
{
var users = getUsers().Values.ToList();
foreach (var user in users)
{
await kickUserByUserGuid(user.getUserGuid(), LogoutReasonType.ExitToService);
}
}
public async Task<bool> kickUserByNickname(string name)
{
await Task.CompletedTask;
if (false == tryGetUserBySubKey(name, out var found_user))
{
var err_msg = $"Already dicsonnected User !!! : nickname:{name}";
Log.getLogger().warn(err_msg);
return false;
}
ArgumentNullException.ThrowIfNull(found_user);
await kickUser(found_user);
return true;
}
public async Task<bool> kickUserByUserGuid(USER_GUID userGuid, LogoutReasonType reason = LogoutReasonType.DuplicatedLogin, string reasonDescription = "")
{
await Task.CompletedTask;
if (false == tryGetUserByPrimaryKey(userGuid, out var found_user))
{
var err_msg = $"Already dicsonnected User !!! : userGuid:{userGuid}";
Log.getLogger().warn(err_msg);
return false;
}
ArgumentNullException.ThrowIfNull(found_user);
await kickUser(found_user, reason, reasonDescription);
return true;
}
private async Task kickUser(Player toKickUser, LogoutReasonType reason = LogoutReasonType.DuplicatedLogin, string reasonDescription = "")
{
ArgumentNullException.ThrowIfNull(toKickUser);
sendLogoutNoti(toKickUser, reason, reasonDescription);
var game_logout_action = toKickUser.getEntityAction<GameLogoutAction>();
ArgumentNullException.ThrowIfNull(game_logout_action);
await game_logout_action.logoutUser();
}
public void sendLogoutNoti(Player player, LogoutReasonType reason, string reasonDescription)
{
ClientToGame gs2cMessage = new ClientToGame();
gs2cMessage.Message = new ClientToGameMessage();
gs2cMessage.Message.NtfLogout = new ClientToGameMessage.Types.GS2C_NTF_LOGOUT();
gs2cMessage.Message.NtfLogout.LogoutReason = reason;
gs2cMessage.Message.NtfLogout.ReasonMessage = reasonDescription;
player.sendPacket(gs2cMessage);
}
}
}

View File

@@ -0,0 +1,423 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Numerics;
using Newtonsoft.Json;
using Nettention.Proud;
using StackExchange.Redis;
using Pipelines.Sockets.Unofficial.Buffers;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
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 ITEM_GUID = System.String;
namespace GameServer;
public partial class Player : UserBase, IEntityWithSession, IMergeWithInventory, IInitNotifyPacket
{
private readonly CancellationTokenSource m_cts = new();
private readonly List<(ClientToGame packet, bool isNotifyBroadcast)> notifyPackets = new();
public Player(NetClientInfo netClient)
: base(EntityType.Player, netClient)
{
}
public override async Task<Result> onInit()
{
//=====================================================================================
// User Domain Attribute
//=====================================================================================
addEntityAttribute(new UserAttribute(this));
addEntityAttribute(new NicknameAttribute(this));
addEntityAttribute(new LevelAttribute(this));
addEntityAttribute(new MoneyAttribute(this));
addEntityAttribute(new LocationAttribute(this));
addEntityAttribute(new BuffAttribute(this));
addEntityAttribute(new GameOptionAttribute(this));
addEntityAttribute(new CharacterProfileAttribute(this));
addEntityAttribute(new MailProfileAttribute(this));
addEntityAttribute(new CraftHelpAttribute(this));
addEntityAttribute(new PartyInvitePartyRecvsAttribute(this));
addEntityAttribute(new FriendFolderAttribute(this));
addEntityAttribute(new RepeatQuestAttribute(this));
addEntityAttribute(new EscapePositionAttribute(this));
addEntityAttribute(new SeasonPassAttribute(this));
addEntityAttribute(new UserContentsSettingAttribute(this));
addEntityAttribute(new PackageLastOrderRecodeAttribute(this));
addEntityAttribute(new AiChatAttribute(this));
addEntityAttribute(new UgqDailyRewardCountAttribute(this));
addEntityAttribute(new RentalInstanceVisitAttribute(this));
addEntityAttribute(new DailyQuestCheckAttribute(this));//legacy
addEntityAttribute(new SwitchingPropAttribute(this));
addEntityAttribute(new QuestPeriodRepeatCheckAttribute(this));
//=====================================================================================
// Game Domain Attribute
//=====================================================================================
addEntityAttribute(new CaliumAttribute(this));
//=====================================================================================
// User Domain Action
//=====================================================================================
addEntityAction(new PlayerAction(this));
addEntityAction(new AbilityAction(this));
addEntityAction(new NicknameAction(this));
addEntityAction(new LocationAction(this));
addEntityAction(new MoneyAction(this));
addEntityAction(new UserContentsSettingAction(this));
//=====================================================================================
// Inventory 관련 Action
//=====================================================================================
addEntityAction(new UserInventoryAction(this));
//=====================================================================================
// Item 관리적인 Action
//=====================================================================================
addEntityAction(new ItemBuyAction(this));
addEntityAction(new ItemClothAction(this));
addEntityAction(new ItemToolAction(this));
addEntityAction(new ItemTattooAction(this));
addEntityAction(new RandomBoxItemUseAction(this));
//=====================================================================================
// GameZone Domain Action
//=====================================================================================
addEntityAction(new GameZoneAction(this));
addEntityAction(new GameZoneMoveAction(this));
// room 관련 action
addEntityAction(new RoomAction(this));
// shop 관련 action
addEntityAction(new ShopAction(this));
// Party 관련 action
addEntityAction(new PersonalPartyAction(this));
addEntityAction(new PartyInvitePartyRecvAction(this));
addEntityAction(new FriendAgentAction(this));
addEntityAction(new FriendFolderAction(this));
addEntityAction(new SendFriendRequestAction(this));
addEntityAction(new FriendInviteMyhomeAction(this));
addEntityAction(new FriendReplyInviteMyhomeAction(this));
addEntityAction(new ReplyReceivedFriendRequestAction(this));
addEntityAction(new KickFriendsFromMyHomeAction(this));
addEntityAction(new BlockUserAgentAction(this));
addEntityAction(new QuestAction(this));
addEntityAction(new QuestCheatAction(this));
addEntityAction(new RepeatQuestAction(this));
addEntityAction(new EndQuestAction(this));
addEntityAction(new QuestAcceptAction(this));
addEntityAction(new QuestMailAction(this));
addEntityAction(new QuestRefuseAction(this));
addEntityAction(new QuestAbandonAction(this));
addEntityAction(new QuestTaskUpdateAction(this));
addEntityAction(new QuestRewardAction(this));
addEntityAction(new QuestNPCDialogueAction(this));
addEntityAction(new ClaimAction(this));
addEntityAction(new ClaimRewardAction(this));
addEntityAction(new UgqInfoAction(this));
addEntityAction(new UgqAssignAction(this));
addEntityAction(new UgqTestAction(this));
addEntityAction(new UgqAbortAction(this));
addEntityAction(new UgqRewardAction(this));
addEntityAction(new SwitchingPropAction(this));
addEntityAction(new OwnedBuildingAgentAction(this));
addEntityAction(new OwnedLandAgentAction(this));
addEntityAction(new MyhomeAgentAction(this));
addEntityAction(new RentalAgentAction(this));
addEntityAction(new UserSocialActionExecutorAction(this));
addEntityAction(new MinimapMarkerAgentAction(this));
addEntityAction(new ItemFirstPurchaseHistoryAgentAction(this));
addEntityAction(new SearchNicknameAction(this));
addEntityAction(new ChatAction(this));
addEntityAction(new CharacterProfileAction(this));
addEntityAction(new ChannelAction(this));
addEntityAction(new CartAction(this));
addEntityAction(new BuffAction(this));
addEntityAction(new GameOptionAction(this));
addEntityAction(new LanguageAction(this));
addEntityAction(new MailAction(this));
addEntityAction(new StateAction(this));
addEntityAction(new UserReportAction(this));
addEntityAction(new EscapeAction(this));
addEntityAction(new PackageAction(this));
addEntityAction(new CraftAction(this));
addEntityAction(new CraftHelpAction(this));
addEntityAction(new CraftRecipeAction(this));
addEntityAction(new SeasonPassAction(this));
addEntityAction(new RentalVisitAction(this));
addEntityAction(new P2PDataAction(this));
addEntityAction(new BeaconShopAction(this));
//=====================================================================================
// AI Chat 관련 Action
//=====================================================================================
addEntityAction(new AIChatAction(this));
//=====================================================================================
// Task Reservation 관련 Action
//=====================================================================================
addEntityAction(new TaskReservationAction(this));
//=====================================================================================
// Npc 상호작용 Action
//=====================================================================================
addEntityAction(new NpcInteractionAction(this));
//=====================================================================================
// Ugc Npc 관련 Action
//=====================================================================================
addEntityAction(new UgcNpcCreationOrLoadAction(this));
//=====================================================================================
// Farming 관련 Action
//=====================================================================================
addEntityAction(new FarmingAction(this));
//=====================================================================================
// Game LogInOut 관련 Action
//=====================================================================================
addEntityAction(new GameLoginAction(this));
addEntityAction(new GameLogoutAction(this));
//=====================================================================================
// User Create or Load 관련 Action
//=====================================================================================
addEntityAction(new UserCreateOrLoadAction(this));
//=====================================================================================
// Custom Ui or Data 관련 Action
//=====================================================================================
addEntityAction(new CustomDefinedUiAction(this));
//=====================================================================================
// Calium 관련 Action
//=====================================================================================
addEntityAction(new CaliumConverterAction(this));
addEntityAction(new CaliumExchangerAction(this));
//=====================================================================================
// AI Chat 관련 Action
//=====================================================================================
//=====================================================================================
// 랜드 경매 관련 Action
//=====================================================================================
addEntityAction(new UserLandAuctionAction(this));
return await base.onInit();
}
public async Task onResetUser()
{
foreach(var each in getEntityAttributes())
{
var to_clear_attribute = each.Value;
var account_attribute = to_clear_attribute as AccountAttribute;
if (null != account_attribute) { continue; }
var user_attribute = to_clear_attribute as UserAttribute;
if (null != user_attribute) { continue; }
to_clear_attribute.onClear();
}
foreach (var each in getEntityActions())
{
var to_clear_action = each.Value;
to_clear_action.onClear();
}
await Task.CompletedTask;
}
// override IMergeWithInventory
public async Task<Result> onMerge(List<ReservedSlotOnInven> reservedSlotOnInvens, TransactionRunner transactionRunner)
{
ArgumentNullReferenceCheckHelper.throwIfNull(reservedSlotOnInvens, () => $"reservedSlotOnInvens is null !!! - {toBasicString()}");
ArgumentNullReferenceCheckHelper.throwIfNull(transactionRunner, () => $"transactionRunner is null !!! - {toBasicString()}");
var result = new Result();
var inventory_action = getEntityAction<InventoryActionBase>();
NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!! - {toBasicString()}");
result = await inventory_action.onMergeInventory(reservedSlotOnInvens, transactionRunner);
if(result.isFail())
{
return result;
}
return result;
}
public void addNotifyMessage(ClientToGame message, bool isNotifyBroadcast) { notifyPackets.Add((message, isNotifyBroadcast)); }
public void InitNotifyMessage() { notifyPackets.Clear(); }
public void sendNotifyMessage()
{
foreach ((ClientToGame packet, bool isNotifyBroadcast) notifyInfo in notifyPackets)
{
if (notifyInfo.isNotifyBroadcast == true)
{
var game_zone_action = this.getEntityAction<GameZoneAction>();
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!! - {toBasicString()}");
game_zone_action.broadcast(this, notifyInfo.packet);
}
else
{
if (false == GameServerApp.getServerLogic().onSendPacket(this, notifyInfo.packet))
{
continue;
}
}
}
}
public override TAction getEntityAction<TAction>()
{
if (typeof(TAction) == typeof(InventoryActionBase))
{
var inventory_action = base.getEntityAction<UserInventoryAction>() as TAction;
NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!!");
return inventory_action;
}
else if (typeof(TAction) == typeof(SocialActionLoadAction))
{
var social_action = base.getEntityAction<UserSocialActionExecutorAction>() as TAction;
NullReferenceCheckHelper.throwIfNull(social_action, () => $"social_action is null !!!");
return social_action;
}
var action = base.getEntityAction<TAction>();
NullReferenceCheckHelper.throwIfNull(action, () => $"action is null !!!");
return action;
}
public override Type onGetAvailableItemAttributeType()
{
return typeof(UserItemAttribute);
}
public override OWNER_GUID onGetGuidOfOwnerEntityType()
{
var user_attribute = getEntityAttribute<UserAttribute>();
NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!! - {toBasicString()}");
return user_attribute.UserGuid;
}
public bool sendPacket(ClientToGame msg)
{
return GameServerApp.getServerLogic().onSendPacket(this, msg);
}
public bool hasOtpForServerConnect()
{
var account_attribute = getEntityAttribute<AccountAttribute>();
if (null == account_attribute)
{
return false;
}
if (0 >= account_attribute.OtpForServerConnect.Length)
{
return false;
}
return true;
}
public CancellationTokenSource getCancelToken() => m_cts;
public override string onGetDbGuid()
{
return getUserGuid();
}
public CommonResult? getCommonResult()
{
var err_msg = string.Empty;
var found_transaction_runner = findTransactionRunner(TransactionIdType.PrivateContents);
if (null == found_transaction_runner)
{
err_msg = $"Not found TransactionRunner !!! : {toBasicString()}";
Log.getLogger().error(err_msg);
return null;
}
return found_transaction_runner.getCommonResult();
}
public override ILogActor toLogActor()
{
var user_actor_log = base.toLogActor() as UserActorLog;
ArgumentNullReferenceCheckHelper.throwIfNull(user_actor_log, () => $"user_actor_log is null !!!");
var nickname_attribute = getEntityAttribute<NicknameAttribute>();
if(null != nickname_attribute)
{
user_actor_log.UserNickname = nickname_attribute.Nickname;
}
return user_actor_log;
}
public override string toSummaryString()
{
var server_logic = GameServerApp.getServerLogic();
var public_ip = server_logic.getProudNetListener().getNetServer().getNetClientPublicIp(this.getHostId());
var account_attribute = getOriginEntityAttribute<AccountAttribute>();
return toBasicString() + $"accountCreationType:{account_attribute?.AccountCreationType}, authAdminLevelType:{account_attribute?.AuthAdminLevelType}, publicIp:{public_ip}, {base.toSummaryString()}";
}
}

View File

@@ -0,0 +1,92 @@

using ServerCore; using ServerBase;
using ServerCommon;
namespace GameServer;
//attributechangeall [적용할 속성값]
[ChatCommandAttribute("attributechangeall", typeof(ChatCommandAttributeChangeAll), AuthAdminLevelType.Developer, AuthAdminLevelType.GmNormal, AuthAdminLevelType.GmSuper)]
internal class ChatCommandAttributeChangeAll : ChatCommandBase
{
public override async Task invoke(Player player, string token, string[] args)
{
Log.getLogger().info($"Call attributechangeall !!! - {player.toBasicString()}");
var result = new Result();
var err_msg = string.Empty;
if (args.Length < 1)
{
err_msg = $"Not enough argument !!! : argCount:{args.Length} == 2 - {player.toBasicString()}";
Log.getLogger().error(err_msg);
return;
}
if (false == int.TryParse(args[0], out var to_change_all_value))
{
Log.getLogger().error($"to_change_all_value param parsing Error arg 1 : {args[0]}");
return;
}
if (0 >= to_change_all_value)
{
Log.getLogger().error($"Invalid to change Attribute All value of arg 1 !!! : 0 < toChangeValue:{to_change_all_value} - {player.toBasicString()}");
return;
}
var ability_action = player.getEntityAction<AbilityAction>();
NullReferenceCheckHelper.throwIfNull(ability_action, () => $"ability_action is null !!! - {player.toBasicString()}");
ability_action.forceSetAbilityAll(to_change_all_value);
var ntf_msg = new ClientToGameMessage.Types.GS2C_NTF_ATTRIBUTE_UPDATE();
ntf_msg.OwnerEntityType = OwnerEntityType.User;
ntf_msg.OwnerGuid = player.getUserGuid();
ntf_msg.AttributeInfo = ability_action.toAbilityInfo();
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.NtfAttributeUpdate = ntf_msg;
GameServerApp.getServerLogic().onSendPacket(player, clientToGame);
await Task.CompletedTask;
}
}
//attributeresetall
[ChatCommandAttribute("attributeresetall", typeof(ChatCommandAttributeResetAll), AuthAdminLevelType.Developer, AuthAdminLevelType.GmNormal, AuthAdminLevelType.GmSuper)]
internal class ChatCommandAttributeResetAll : ChatCommandBase
{
public override async Task invoke(Player player, string token, string[] args)
{
Log.getLogger().info($"Call attributeresetall !!! - {player.toBasicString()}");
var result = new Result();
var err_msg = string.Empty;
var ability_action = player.getEntityAction<AbilityAction>();
NullReferenceCheckHelper.throwIfNull(ability_action, () => $"ability_action is null !!! - {player.toBasicString()}");
result = await ability_action.forceResetAll();
if (result.isFail())
{
Log.getLogger().error($"Invalid to forceResetAll() !!! : {result.toBasicString()} - {player.toBasicString()}");
return;
}
var ntf_msg = new ClientToGameMessage.Types.GS2C_NTF_ATTRIBUTE_UPDATE();
ntf_msg.OwnerEntityType = OwnerEntityType.User;
ntf_msg.OwnerGuid = player.getUserGuid();
ntf_msg.AttributeInfo = ability_action.toAbilityInfo();
ClientToGame clientToGame = new ClientToGame();
clientToGame.Message = new ClientToGameMessage();
clientToGame.Message.NtfAttributeUpdate = ntf_msg;
GameServerApp.getServerLogic().onSendPacket(player, clientToGame);
}
}