초기커밋
This commit is contained in:
258
GameServer/Entity/Player/Action/AbilityAction.cs
Normal file
258
GameServer/Entity/Player/Action/AbilityAction.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
969
GameServer/Entity/Player/Action/PlayerAction.cs
Normal file
969
GameServer/Entity/Player/Action/PlayerAction.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
445
GameServer/Entity/Player/Helper/PlayerHelper.cs
Normal file
445
GameServer/Entity/Player/Helper/PlayerHelper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
97
GameServer/Entity/Player/Manager/PlayerManager.cs
Normal file
97
GameServer/Entity/Player/Manager/PlayerManager.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
423
GameServer/Entity/Player/Player.cs
Normal file
423
GameServer/Entity/Player/Player.cs
Normal 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()}";
|
||||
}
|
||||
}
|
||||
92
GameServer/Entity/Player/PlayerCheat.cs
Normal file
92
GameServer/Entity/Player/PlayerCheat.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user