Files
caliverse_server/ServerBase/Entity/Transaction/TransactionRunner.cs
2025-05-01 07:20:41 +09:00

848 lines
31 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.ConstrainedExecution;
using NLog;
using Amazon.DynamoDBv2.Model;
using Newtonsoft.Json;
using Pipelines.Sockets.Unofficial.Buffers;
using StackExchange.Redis;
using Google.Protobuf.Collections;
using ServerControlCenter;
using Amazon.S3.Model;
using ServerCore; using ServerBase;
using SESSION_ID = System.Int32;
using WORLD_ID = System.UInt32;
using META_ID = System.UInt32;
using TRANSACTION_NAME = System.String;
using TRANSACTION_GUID = System.String;
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 ServerBase;
public class ReservedSlotOnInven
{
public class ReservedSlot
{
private Int16 m_reserved_count = 0;
private EntityBase? m_equip_entity_nullable;
private EntityBase? m_unequip_entity_nullable;
public ReservedSlot()
{ }
public void incReservedCount(Int16 reservedItemCount)
{
m_reserved_count += reservedItemCount;
}
public void decReservedCount(Int16 reservedItemCount)
{
m_reserved_count -= reservedItemCount;
}
public Int16 getReservedCount() => m_reserved_count;
public void setEquipEntity(EntityBase? entityBase) => m_equip_entity_nullable = entityBase;
public EntityBase? getEquipEntity() => m_equip_entity_nullable;
public void setUnequipEntity(EntityBase? entityBase) => m_unequip_entity_nullable = entityBase;
public EntityBase? getUnequipEntity() => m_unequip_entity_nullable;
}
private EntityType m_entity_inven_type = EntityType.None;
private readonly Dictionary<string, ReservedSlot> m_reserved_slots = new();
public ReservedSlotOnInven(EntityType entityInvenType)
{
m_entity_inven_type = entityInvenType;
}
public void addOrInc(string slotKey, Int16 incReservedCount)
{
if(false == m_reserved_slots.TryGetValue(slotKey, out var found_reserved_slot))
{
found_reserved_slot = new ReservedSlot();
m_reserved_slots.Add(slotKey, found_reserved_slot);
}
found_reserved_slot.incReservedCount(incReservedCount);
}
public void addOrDec(string slotKey, Int16 decReservedCount)
{
if (false == m_reserved_slots.TryGetValue(slotKey, out var found_reserved_slot))
{
found_reserved_slot = new ReservedSlot();
m_reserved_slots.Add(slotKey, found_reserved_slot);
}
found_reserved_slot.decReservedCount(decReservedCount);
}
public Dictionary<string, ReservedSlot> getReservedSlots() => m_reserved_slots;
public EntityType getEntityType() => m_entity_inven_type;
}
public partial class TransactionRunner : IDisposable
{
private readonly EntityBase m_owner;
private readonly string m_trans_id = string.Empty;
private readonly TransactionIdType m_transaction_id_type = TransactionIdType.None;
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<ENTITY_GUID, IEntityAttributeTransactor>> m_entity_attribute_transactors = new();
private readonly ConcurrentQueue<IEntityAttributeTransactor> m_to_db_query_transactors = new(); // Db Query용 (순서 보장 중요)
private readonly ConcurrentDictionary<EntityBase, ConcurrentDictionary<EntityType, ReservedSlotOnInven>> m_reserved_inven_slots_of_owners = new();
private readonly ConcurrentDictionary<string, EntityCommonResult> m_entity_common_results = new();
//IRemoteTransaction
private readonly List<Func<Task>> m_remote_transaction_funcs = new();
private string m_transaction_name;
private bool m_is_binding = false;
public TransactionRunner(EntityBase owner, TransactionIdType idType, string transactionName)
{
m_owner = owner;
m_trans_id = System.Guid.NewGuid().ToString("N");
m_transaction_id_type = idType;
m_transaction_name = transactionName;
}
public TransactionRunner(EntityBase owner, string transId, TransactionIdType idType, string transactionName)
{
m_owner = owner;
m_trans_id = transId;
m_transaction_id_type = idType;
m_transaction_name = transactionName;
}
public Result beginTransaction()
{
var result = new Result();
var err_msg = string.Empty;
result = m_owner.bindTransactionRunner(this);
if(result.isFail())
{
return result;
}
setBinding();
return result;
}
public void clearTransaction()
{
m_entity_attribute_transactors.Clear();
m_reserved_inven_slots_of_owners.Clear();
m_to_db_query_transactors.Clear();
}
// override IDisposable.Dispose
public void Dispose()
{
var err_msg = string.Empty;
if (false == isBinding())
{
return;
}
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
if (false == m_owner.unbindTransactionRunner(this))
{
err_msg = $"Failed to unbindTransactionRunner() !!! : {toBasicString()} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
return;
}
}
public void resetTransaction(string transactionName)
{
clearTransaction();
m_transaction_name = transactionName;
}
public async Task<Result> onCommitResults(QueryBatchBase? queryBatch = null)
{
await Task.CompletedTask;
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var result = new Result();
var err_msg = string.Empty;
var transactors = getEntityAttributeTransactorAll();
// 메모리를 동기화 한다.
foreach (var to_sync_merge in transactors)
{
var origin_entity_attribute = to_sync_merge.getOriginEntityAttribute();
NullReferenceCheckHelper.throwIfNull(origin_entity_attribute, () => $"origin_entity_attribute is null !!! - {owner.toBasicString()}");
var to_merge_attribute = origin_entity_attribute as IMergeWithEntityAttribute;
if (null == to_merge_attribute)
{
err_msg = $"Failed to cast IMergeWithEntityAttribute !!! : OriginEntityAttribute:{origin_entity_attribute.toBasicString()} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
continue;
}
var cloned_entity_attribute = to_sync_merge.getClonedEntityAttribute();
if (null == cloned_entity_attribute)
{
err_msg = $"getClonedEntityAttribute() is null !!! : OriginEntityAttribute:{origin_entity_attribute.toBasicString()} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
continue;
}
var comon_result_filler = cloned_entity_attribute as IWithCommonResultFiller;
if (null != comon_result_filler)
{
(result, var entity_common_result) = getOrNewEntityCommonResult(cloned_entity_attribute);
if (result.isFail())
{
Log.getLogger().fatal(result.toBasicString());
}
else
{
NullReferenceCheckHelper.throwIfNull(entity_common_result, () => $"entity_common_result is null !!! - {owner.toBasicString()}");
comon_result_filler.onFillCommonResult(entity_common_result, origin_entity_attribute, queryBatch);
}
}
result = to_merge_attribute.onMerge(cloned_entity_attribute);
if (result.isFail())
{
err_msg = $"Failed to onMerge() !!! : {result.toBasicString()} - {owner.toBasicString()}";
Log.getLogger().debug(err_msg);
continue;
}
}
var reserved_iven_slots_of_owners = getReservedInvenSlotAllOfOwners();
foreach(var each in reserved_iven_slots_of_owners)
{
var inven_owner = each.Key;
var reserved_inven_slots = each.Value;
var to_merge_inventory = inven_owner as IMergeWithInventory;
if (null != to_merge_inventory)
{
result = await to_merge_inventory.onMerge(reserved_inven_slots.Values.ToList<ReservedSlotOnInven>(), this);
if (result.isFail())
{
err_msg = $"Failed to IMergeWithInventory.onMerge() !!! : {result.toBasicString()} - {inven_owner.toBasicString()}, {owner.toBasicString()}";
Log.getLogger().fatal(err_msg);
continue;
}
}
}
reserved_iven_slots_of_owners.Clear();
await tryStartRemoteTransaction();
return result;
}
public async Task<Result> onCommitResults4DbQuery(List<IEntityAttributeTransactor> dbQueriedTransactors, QueryBatchBase? queryBatch = null)
{
await Task.CompletedTask;
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
NullReferenceCheckHelper.throwIfNull(dbQueriedTransactors, () => $"dbQueriedTransactors is null !!! - {owner.toBasicString()}");
var result = new Result();
var err_msg = string.Empty;
foreach (var to_sync_merge in dbQueriedTransactors)
{
var origin_entity_attribute = to_sync_merge.getOriginEntityAttribute();
NullReferenceCheckHelper.throwIfNull(origin_entity_attribute, () => $"origin_entity_attribute is null !!! - {owner.toBasicString()}");
var to_merge_attribute = origin_entity_attribute as IMergeWithEntityAttribute;
if (null == to_merge_attribute)
{
err_msg = $"Failed to cast IMergeWithEntityAttribute !!! : OriginEntityAttribute:{origin_entity_attribute.toBasicString()} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
continue;
}
var cloned_entity_attribute = to_sync_merge.getClonedEntityAttribute();
if (null == cloned_entity_attribute)
{
err_msg = $"getClonedEntityAttribute() is null !!! : OriginEntityAttribute:{origin_entity_attribute.toBasicString()} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
continue;
}
if(true == m_entity_attribute_transactors.TryGetValue(origin_entity_attribute.GetType(), out var found_transactors))
{
// DB 처리후 여기서 origin_entity_attribute Merge를 하므로
// onCommitResults() 함수로 중복된 Merge를 시도할 수 있으므로 m_entity_attribute_transactors 에서 제거 한다. - kangms
found_transactors.Remove(origin_entity_attribute.getOwner().getEntityGuid(), out _);
}
var comon_result_filler = cloned_entity_attribute as IWithCommonResultFiller;
if (null != comon_result_filler)
{
(result, var entity_common_result) = getOrNewEntityCommonResult(cloned_entity_attribute);
if (result.isFail())
{
Log.getLogger().fatal(result.toBasicString());
}
else
{
NullReferenceCheckHelper.throwIfNull(entity_common_result, () => $"entity_common_result is null !!! - {owner.toBasicString()}");
comon_result_filler.onFillCommonResult(entity_common_result, origin_entity_attribute, queryBatch);
}
}
result = to_merge_attribute.onMerge(cloned_entity_attribute);
if (result.isFail())
{
err_msg = $"Failed to onMerge() !!! : {result.toBasicString()} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
}
var reserved_iven_slots_of_owners = getReservedInvenSlotAllOfOwners();
foreach (var each in reserved_iven_slots_of_owners)
{
var inven_owner = each.Key;
var reserved_inven_slots = each.Value;
var to_merge_inventory = inven_owner as IMergeWithInventory;
if (null != to_merge_inventory)
{
result = await to_merge_inventory.onMerge(reserved_inven_slots.Values.ToList<ReservedSlotOnInven>(), this);
if (result.isFail())
{
err_msg = $"Failed to IMergeWithInventory.onMerge() !!! : {result.toBasicString()} - {inven_owner.toBasicString()}, {owner.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
}
}
reserved_iven_slots_of_owners.Clear();
await tryStartRemoteTransaction();
return result;
}
public ConcurrentDictionary<ENTITY_GUID, IEntityAttributeTransactor> getEntityAttributeTransactorAll(Type targetEntityAttribute)
{
var err_msg = string.Empty;
var entity_attribute_transactors = new List<IEntityAttributeTransactor>();
if(false == m_entity_attribute_transactors.TryGetValue(targetEntityAttribute, out var found_transactors))
{
return new ConcurrentDictionary<ENTITY_GUID, IEntityAttributeTransactor>();
}
return found_transactors;
}
public ConcurrentDictionary<ENTITY_GUID, IEntityAttributeTransactor> getEntityAttributeTransactorAll<TEntityAttributeType>()
where TEntityAttributeType : EntityAttributeBase
{
var err_msg = string.Empty;
var entity_attribute_transactors = new List<IEntityAttributeTransactor>();
var target_type = typeof(TEntityAttributeType);
if(false == m_entity_attribute_transactors.TryGetValue(target_type, out var found_transactors))
{
return new ConcurrentDictionary<ENTITY_GUID, IEntityAttributeTransactor>();
}
return found_transactors;
}
public List<IEntityAttributeTransactor> getEntityAttributeTransactorAll()
{
var err_msg = string.Empty;
var entity_attribute_transactors = new List<IEntityAttributeTransactor>();
foreach (var each_attribute_type in m_entity_attribute_transactors)
{
foreach (var each_attribute_transactor in each_attribute_type.Value)
{
var transactor_entity_guid = each_attribute_transactor.Key;
var transactor = each_attribute_transactor.Value;
if (null == transactor)
{
continue;
}
entity_attribute_transactors.Add(transactor);
}
}
return entity_attribute_transactors;
}
public List<IEntityAttributeTransactor> getEntityAttributeTransactorAll4DbQuery()
{
var err_msg = string.Empty;
var transactors = new List<IEntityAttributeTransactor>();
while (false == m_to_db_query_transactors.IsEmpty)
{
if (true == m_to_db_query_transactors.TryDequeue(out var transactor))
{
transactors.Add(transactor);
}
}
return transactors;
}
public TEntityAttribute? getEntityAttribute<TEntityAttribute>(TEntityAttribute fromOriginEntityAttributeBase)
where TEntityAttribute : EntityAttributeBase
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
ArgumentNullReferenceCheckHelper.throwIfNull(fromOriginEntityAttributeBase, () => $"fromOriginEntityAttributeBase is null !!! - {owner.toBasicString()}");
var to_add_type = fromOriginEntityAttributeBase.GetType();
var entity_guid = fromOriginEntityAttributeBase.getOwner().getEntityGuid();
ConcurrentDictionary<ENTITY_GUID, IEntityAttributeTransactor>? found_transactors;
lock (m_entity_attribute_transactors)
{
if (false == m_entity_attribute_transactors.TryGetValue(to_add_type, out found_transactors))
{
found_transactors = new();
m_entity_attribute_transactors[to_add_type] = found_transactors;
}
}
IEntityAttributeTransactor found_transactor;
var add_transactor = delegate (ENTITY_GUID entityGuid)
{
found_transactor = fromOriginEntityAttributeBase.onNewEntityAttributeTransactor();
if (false == found_transactor.cloneFromOriginEntityAttribute(fromOriginEntityAttributeBase))
{
var err_msg = $"Failed to cloneFromOriginEntityAttribute() !!! - {toBasicString()}, {owner.toBasicString()}";
Log.getLogger().error(err_msg);
return null;
}
m_to_db_query_transactors.Enqueue(found_transactor);
return found_transactor;
};
found_transactor = found_transactors.GetOrAdd(entity_guid, add_transactor!);
if (null == found_transactor)
{
var err_msg = $"Failed to GetOrAdd() !!! : {fromOriginEntityAttributeBase.toBasicString()} - {toBasicString()}, {owner.toBasicString()}";
Log.getLogger().error(err_msg);
}
else
{
return found_transactor.getClonedEntityAttribute() as TEntityAttribute;
}
return fromOriginEntityAttributeBase as TEntityAttribute;
}
public TEntityAttribute? getEntityAttributeWithReadOnly<TEntityAttribute>(TEntityAttribute fromOriginEntityAttributeBase)
where TEntityAttribute : EntityAttributeBase
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
ArgumentNullReferenceCheckHelper.throwIfNull(fromOriginEntityAttributeBase, () => $"fromOriginEntityAttributeBase is null !!! - {owner.toBasicString()}");
var to_add_type = fromOriginEntityAttributeBase.GetType();
var entity_guid = fromOriginEntityAttributeBase.getOwner().getEntityGuid();
ConcurrentDictionary<ENTITY_GUID, IEntityAttributeTransactor>? found_transactors;
lock (m_entity_attribute_transactors)
{
m_entity_attribute_transactors.TryGetValue(to_add_type, out found_transactors);
IEntityAttributeTransactor? found_transactor = null;
if (null != found_transactors)
{
found_transactors.TryGetValue(entity_guid, out found_transactor);
}
if (null != found_transactor)
{
return found_transactor.getClonedEntityAttribute() as TEntityAttribute;
}
return fromOriginEntityAttributeBase as TEntityAttribute;
}
}
public Result tryIncReserveSlotCount(EntityBase invenOwner, EntityType entityInvenType, string slotType)
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
ArgumentNullReferenceCheckHelper.throwIfNull(invenOwner, () => $"invenOwner is null !!! - {owner.toBasicString()}");
var result = new Result();
ConcurrentDictionary<EntityType, ReservedSlotOnInven>? found_reserved_inven_slots;
lock (m_reserved_inven_slots_of_owners)
{
if (false == m_reserved_inven_slots_of_owners.TryGetValue(invenOwner, out found_reserved_inven_slots))
{
found_reserved_inven_slots = new ConcurrentDictionary<EntityType, ReservedSlotOnInven>();
m_reserved_inven_slots_of_owners[invenOwner] = found_reserved_inven_slots;
}
}
var add_recorder = delegate (EntityType invenType)
{
var reserved_slot = new ReservedSlotOnInven(entityInvenType);
reserved_slot.addOrInc(slotType, 1);
return reserved_slot;
};
var update_recorder = delegate (EntityType invenType, ReservedSlotOnInven currValue)
{
if (false == currValue.getReservedSlots().TryGetValue(slotType, out var found_reserved_slot))
{
found_reserved_slot = new ReservedSlotOnInven.ReservedSlot();
currValue.getReservedSlots().Add(slotType, found_reserved_slot);
}
found_reserved_slot.incReservedCount(1);
return currValue;
};
found_reserved_inven_slots.AddOrUpdate(entityInvenType, add_recorder, update_recorder);
return result;
}
public Result tryDecToReserveSlotCount(EntityBase invenOwner, EntityType entityInvenType, string slotType)
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
ArgumentNullReferenceCheckHelper.throwIfNull(invenOwner, () => $"invenOwner is null !!! - {owner.toBasicString()}");
var result = new Result();
ConcurrentDictionary<EntityType, ReservedSlotOnInven>? found_reserved_inven_slots;
lock (m_reserved_inven_slots_of_owners)
{
if (false == m_reserved_inven_slots_of_owners.TryGetValue(invenOwner, out found_reserved_inven_slots))
{
found_reserved_inven_slots = new ConcurrentDictionary<EntityType, ReservedSlotOnInven>();
m_reserved_inven_slots_of_owners[invenOwner] = found_reserved_inven_slots;
}
}
var add_recorder = delegate (EntityType invenType)
{
var reserved_slot = new ReservedSlotOnInven(entityInvenType);
reserved_slot.addOrDec(slotType, 1);
return reserved_slot;
};
var update_recorder = delegate (EntityType invenType, ReservedSlotOnInven currValue)
{
if (false == currValue.getReservedSlots().TryGetValue(slotType, out var found_reserved_slot))
{
found_reserved_slot = new ReservedSlotOnInven.ReservedSlot();
currValue.getReservedSlots().Add(slotType, found_reserved_slot);
}
found_reserved_slot.decReservedCount(1);
return currValue;
};
found_reserved_inven_slots.AddOrUpdate(entityInvenType, add_recorder, update_recorder);
return result;
}
public Result tryEquipToReserveSlotWithEntityBase(EntityBase invenOwner, EntityType entityInvenType, string slotType, EntityBase? entityBase)
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
ArgumentNullReferenceCheckHelper.throwIfNull(invenOwner, () => $"invenOwner is null !!! - {owner.toBasicString()}");
var result = new Result();
var err_msg = string.Empty;
ConcurrentDictionary<EntityType, ReservedSlotOnInven>? found_reserved_inven_slots;
lock (m_reserved_inven_slots_of_owners)
{
if (false == m_reserved_inven_slots_of_owners.TryGetValue(invenOwner, out found_reserved_inven_slots))
{
found_reserved_inven_slots = new ConcurrentDictionary<EntityType, ReservedSlotOnInven>();
m_reserved_inven_slots_of_owners[invenOwner] = found_reserved_inven_slots;
}
}
var slot_key = slotType;
var add_recorder = delegate (EntityType invenType)
{
var reserved_slot_on_inven = new ReservedSlotOnInven(entityInvenType);
reserved_slot_on_inven.addOrInc(slot_key, 1);
reserved_slot_on_inven.getReservedSlots()[slot_key].setEquipEntity(entityBase);
return reserved_slot_on_inven;
};
var update_recorder = delegate (EntityType invenType, ReservedSlotOnInven currValue)
{
if (false == currValue.getReservedSlots().TryGetValue(slot_key, out var found_reserved_slot))
{
found_reserved_slot = new ReservedSlotOnInven.ReservedSlot();
currValue.getReservedSlots()[slot_key] = found_reserved_slot;
}
var equip_entity = found_reserved_slot.getEquipEntity();
if (null != equip_entity)
{
err_msg = $"Already reserved equip item !!! : reservedEquipItem:{equip_entity.toBasicString()} - {entityBase?.toBasicString()}, {toBasicString()}, {owner.toBasicString()}";
result.setFail(ServerErrorCode.SlotsAlreadyReservedEquip, err_msg);
Log.getLogger().warn(result.toBasicString());
return currValue;
}
found_reserved_slot.incReservedCount(1);
found_reserved_slot.setEquipEntity(entityBase);
return currValue;
};
found_reserved_inven_slots.AddOrUpdate(entityInvenType, add_recorder, update_recorder);
return result;
}
public Result tryUnequipToReserveSlotWithEntityBase(EntityBase invenOwner, EntityType entityInvenType, string slotType, EntityBase? entityBase)
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
ArgumentNullReferenceCheckHelper.throwIfNull(invenOwner, () => $"invenOwner is null !!! - {owner.toBasicString()}");
var result = new Result();
var err_msg = string.Empty;
var slot_key = slotType;
ConcurrentDictionary<EntityType, ReservedSlotOnInven>? found_reserved_inven_slots = null;
lock (m_reserved_inven_slots_of_owners)
{
if (false == m_reserved_inven_slots_of_owners.TryGetValue(invenOwner, out found_reserved_inven_slots))
{
found_reserved_inven_slots = new ConcurrentDictionary<EntityType, ReservedSlotOnInven>();
m_reserved_inven_slots_of_owners[invenOwner] = found_reserved_inven_slots;
}
}
var add_recorder = delegate (EntityType invenType)
{
var reserved_slot_on_inven = new ReservedSlotOnInven(entityInvenType);
reserved_slot_on_inven.addOrDec(slot_key, 1);
reserved_slot_on_inven.getReservedSlots()[slot_key].setUnequipEntity(entityBase);
return reserved_slot_on_inven;
};
var update_recorder = delegate (EntityType invenType, ReservedSlotOnInven currValue)
{
if (false == currValue.getReservedSlots().TryGetValue(slot_key, out var found_reserved_slot))
{
found_reserved_slot = new ReservedSlotOnInven.ReservedSlot();
currValue.getReservedSlots()[slot_key] = found_reserved_slot;
}
var unequip_entity = found_reserved_slot.getUnequipEntity();
if (null != unequip_entity)
{
err_msg = $"Already reserved unequip item !!! : reservedUnequipItem:{unequip_entity.toBasicString()} - {entityBase?.toBasicString()}, {toBasicString()}, {owner.toBasicString()}";
result.setFail(ServerErrorCode.SlotsAlreadyReservedUnequip, err_msg);
Log.getLogger().warn(result.toBasicString());
return currValue;
}
found_reserved_slot.decReservedCount(1);
found_reserved_slot.setUnequipEntity(entityBase);
return currValue;
};
found_reserved_inven_slots.AddOrUpdate(entityInvenType, add_recorder, update_recorder);
return result;
}
public Result tryEquipToReserveSlot(EntityBase invenOwner, EntityType entityInvenType, string slotType)
{
return tryEquipToReserveSlotWithEntityBase(invenOwner, entityInvenType, slotType, null);
}
public Result tryUnequipToReserveSlot(EntityBase invenOwner, EntityType entityInvenType, string slotType)
{
return tryUnequipToReserveSlotWithEntityBase(invenOwner, entityInvenType, slotType, null);
}
public ReservedSlotOnInven.ReservedSlot? findReservedSlot(EntityBase invenOwner, EntityType entityInvenType, string slotType)
{
if(false == m_reserved_inven_slots_of_owners.TryGetValue(invenOwner, out var found_reserved_inven_slots))
{
return null;
}
if (true == found_reserved_inven_slots.TryGetValue(entityInvenType, out var found_reserved_slot_on_inven))
{
if(found_reserved_slot_on_inven.getReservedSlots().TryGetValue(slotType, out var found_reserved_slot))
{
return found_reserved_slot;
}
}
return null;
}
public (Result, EntityCommonResult?) getOrNewEntityCommonResult(EntityAttributeBase entityAttribute)
{
var owner = getOwner();
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
ArgumentNullReferenceCheckHelper.throwIfNull(entityAttribute, () => $"entityAttribute is null !!! - {owner.toBasicString()}");
var entity_of_owner_entity_type = entityAttribute.getEntityOfOwnerEntityType();
NullReferenceCheckHelper.throwIfNull(entity_of_owner_entity_type, () => $"entity_of_owner_entity_type is null !!! - {owner.toBasicString()}");
var result = new Result();
var err_msg = string.Empty;
var owner_guid = entity_of_owner_entity_type.onGetDbGuid();
if(owner_guid.isNullOrWhiteSpace())
{
err_msg = $"Invlid OwnerGuid of onGetDbGuid() !!! : entityAttribute:{entityAttribute.toBasicString()} - {owner.toBasicString()}";
result.setFail(ServerErrorCode.OwnerGuidInvalid, err_msg);
Log.getLogger().fatal(result.toBasicString());
return (result, null);
}
if (false == m_entity_common_results.TryGetValue(owner_guid, out var found_entity_common_result))
{
found_entity_common_result = new EntityCommonResult();
found_entity_common_result.EntityType = entity_of_owner_entity_type.getEntityType();
found_entity_common_result.EntityGuid = owner_guid;
found_entity_common_result.Money = new MoneyResult();
found_entity_common_result.Exp = new ExpResult();
found_entity_common_result.Item = new ItemResult();
m_entity_common_results[owner_guid] = found_entity_common_result;
}
return (result, found_entity_common_result);
}
public CommonResult getCommonResult()
{
var common_result = new CommonResult();
foreach(var each in m_entity_common_results)
{
common_result.EntityCommonResults.Add(each.Value);
}
return common_result;
}
public void addRemoteChargeAIPoint(IRemoteTransaction remoteTransaction, double beamDelta)
{
var fn_buy_cart = new Func<Task>(() =>
{
return remoteTransaction.callRemoteChargeAIPoint(beamDelta);
});
m_remote_transaction_funcs.Add(fn_buy_cart);
}
public void addNotifyCaliumEvent(IRemoteTransaction remoteTransaction, string eventName, CurrencyType currencyType, double delta)
{
var fn = new Func<Task>(() => remoteTransaction.callNotifyCaliumEvent(eventName, currencyType, delta));
m_remote_transaction_funcs.Add(fn);
}
public async Task tryStartRemoteTransaction()
{
foreach(var remote_transaction_funcs in m_remote_transaction_funcs)
{
await remote_transaction_funcs();
}
}
public string toBasicString()
{
return $"TransactionRunnger - transId:{m_trans_id}, transactionIdType:{m_transaction_id_type}, transactionName:{m_transaction_name}";
}
}