using System; using System.Collections.Concurrent; using System.Collections.Generic; using Amazon.DynamoDBv2.Model; using Newtonsoft.Json; using ServerCommon; using ServerCore; using ServerBase; namespace GameServer; public class BattleInstanceSnapshotPlayModePodCombat { //Respawn 정보 [JsonProperty] public ConcurrentDictionary m_respawns {get; set;} = new (); [JsonProperty] public ConcurrentDictionary m_pod_storages {get; set;} = new (); [JsonProperty] public BattleObjectPodCombat m_pod_combat { get; set; } = new(); [JsonProperty] public ConcurrentDictionary m_pickup_pods {get; set;} = new (); [JsonProperty] public ConcurrentDictionary<(Int32, Int32) /*(group_id, idx)*/, PickupPodGeneratedInfo> m_pickup_pod_generated_info { get; set; } = new(); [JsonProperty] public ConcurrentDictionary m_weapons {get; set;} = new (); [JsonProperty] public ConcurrentDictionary m_buffs {get; set;} = new (); [JsonProperty] public BattleRoundStateType m_round_state_type { get; set; } = BattleRoundStateType.Rounding; [JsonProperty] public int m_current_round { get; set; } = 1; [JsonProperty] public DateTime m_current_state_start_time { get; set; } = DateTimeHelper.Current; [JsonProperty] public int m_charged_step { get; set; } = 0; [JsonProperty] public int m_rewarded_step { get; set; } = 0; [JsonProperty] public ConcurrentDictionary m_tactical_board = new(); //결과 표시에서 보여줄것 /* m_respawns m_pod_storages m_pod_combat m_pickup_pods m_pickup_pod_reward_max_count m_pickup_pod_generated_info m_weapons m_buffs m_round_state_type m_current_round m_current_state_start_time m_charged_step m_rewarded_step m_max_step m_tactical_board */ public void clear() { m_respawns.Clear(); m_pod_storages.Clear(); m_pod_combat.setDeactive(); m_pickup_pods.Clear(); m_pickup_pod_generated_info.Clear(); m_weapons.Clear(); m_buffs.Clear(); m_round_state_type = BattleRoundStateType.None; m_current_round = 1; m_current_state_start_time = DateTimeHelper.Current; m_charged_step = 0; m_rewarded_step = 0; m_tactical_board.Clear(); } } public class BattleInstanceSnapshotAttribute : EntityAttributeBase, ICopyEntityAttributeFromDoc, IMergeWithEntityAttribute { [JsonProperty] public string m_room_id { get; set; } = string.Empty; //아래 데이터들은 일반화 혹은 모드별로 관리 필요 //public BattlePlayMode m_play_mode = BattlePlayMode.PodCombat; //public DateTime m_create_time { get; set; } = DateTimeHelper.Current; //public DateTime m_destroy_time { get; set; } = DateTimeHelper.MaxTime; //todo : 이 코드 들어간 부분은 전부 리펙토링 대상 public BattleInstanceSnapshotPlayModePodCombat m_combat_pod_mode { get; set; } = new(); public BattleInstanceSnapshotAttribute(EntityBase owner) : base(owner) { } public override void onClear() { m_room_id = string.Empty; m_combat_pod_mode.clear(); getAttributeState().reset(); } public override async Task<(Result, DynamoDbDocBase?)> toDocBase(bool isForQuery = true) { var owner = getOwner(); var result = new Result(); //===================================================================================== // Attribute => try pending Doc //===================================================================================== var try_pending_doc = getTryPendingDocBase() as BattleInstanceSnapshotDoc; if (null == try_pending_doc) { var to_copy_doc = new BattleInstanceSnapshotDoc(m_room_id); var origin_doc = getOriginDocBase(); if (null != origin_doc) { to_copy_doc.copyTimestampsFromOriginDocBase(origin_doc); } try_pending_doc = to_copy_doc; setTryPendingDocBase(try_pending_doc); } var to_copy_battle_instance_snapshot_attrib = try_pending_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(to_copy_battle_instance_snapshot_attrib, () => $"to_copy_battle_instance_snapshot_attrib is null !!!"); to_copy_battle_instance_snapshot_attrib.m_room_id = m_room_id; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_respawns = m_combat_pod_mode.m_respawns; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_pod_storages = m_combat_pod_mode.m_pod_storages; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_pod_combat = m_combat_pod_mode.m_pod_combat; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_pickup_pods = m_combat_pod_mode.m_pickup_pods; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_pickup_pod_generated_info.AddRange(m_combat_pod_mode.m_pickup_pod_generated_info.Values); to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_weapons = m_combat_pod_mode.m_weapons; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_buffs = m_combat_pod_mode.m_buffs; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_round_state_type = m_combat_pod_mode.m_round_state_type; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_current_round = m_combat_pod_mode.m_current_round; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_current_state_start_time = m_combat_pod_mode.m_current_state_start_time; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_charged_step = m_combat_pod_mode.m_charged_step; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_rewarded_step = m_combat_pod_mode.m_rewarded_step; to_copy_battle_instance_snapshot_attrib.m_combat_pod_attrib.m_tactical_board = m_combat_pod_mode.m_tactical_board; if (false == isForQuery) { return (result, try_pending_doc); } //===================================================================================== // Doc QueryType 반영 //===================================================================================== (result, var to_query_doc) = await applyDoc4Query(try_pending_doc); if (result.isFail()) { return (result, null); } return (result, to_query_doc); } public override EntityAttributeBase onCloned() { var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!! - {toBasicString()}"); var cloned = new BattleInstanceSnapshotAttribute(owner); cloned.deepCopyFromBase(this); cloned.m_room_id = m_room_id; // Respawn 처리 foreach (var respawn in m_combat_pod_mode.m_respawns) { var key = respawn.Key; var val = respawn.Value; cloned.m_combat_pod_mode.m_respawns.TryAdd(key, val); } // PodStorage 처리 foreach (var storage in m_combat_pod_mode.m_pod_storages) { var key = storage.Key; BattleObjectPodStorage battle_object_pod_storage = storage.Value; BattleObjectPodStorage new_storage = new(key); new_storage.m_is_active = battle_object_pod_storage.m_is_active; new_storage.m_type = battle_object_pod_storage.m_type; new_storage.m_anchor_guid = battle_object_pod_storage.m_anchor_guid; new_storage.m_active_time = battle_object_pod_storage.m_active_time; new_storage.m_reward_cnt = battle_object_pod_storage.m_reward_cnt; cloned.m_combat_pod_mode.m_pod_storages.TryAdd(key, new_storage); } // Combat Pod 처리 cloned.m_combat_pod_mode.m_pod_combat = new(); cloned.m_combat_pod_mode.m_pod_combat.m_type = m_combat_pod_mode.m_pod_combat.m_type; cloned.m_combat_pod_mode.m_pod_combat.m_anchor_guid = m_combat_pod_mode.m_pod_combat.m_anchor_guid; cloned.m_combat_pod_mode.m_pod_combat.m_active_time = m_combat_pod_mode.m_pod_combat.m_active_time; cloned.m_combat_pod_mode.m_pod_combat.m_is_active = m_combat_pod_mode.m_pod_combat.m_is_active; cloned.m_combat_pod_mode.m_pod_combat.m_source_storage_anchor_guid = m_combat_pod_mode.m_pod_combat.m_source_storage_anchor_guid; cloned.m_combat_pod_mode.m_pod_combat.m_state = m_combat_pod_mode.m_pod_combat.m_state; cloned.m_combat_pod_mode.m_pod_combat.m_state_change_time = m_combat_pod_mode.m_pod_combat.m_state_change_time; cloned.m_combat_pod_mode.m_pod_combat.m_currenct_Pos = m_combat_pod_mode.m_pod_combat.m_currenct_Pos.Clone(); cloned.m_combat_pod_mode.m_pod_combat.m_current_occupier_guid = m_combat_pod_mode.m_pod_combat.m_current_occupier_guid; cloned.m_combat_pod_mode.m_pod_combat.m_occupied_time = m_combat_pod_mode.m_pod_combat.m_occupied_time; //Pickup pod 처리 foreach (var pickup_pod in m_combat_pod_mode.m_pickup_pods) { var key = pickup_pod.Key; cloned.m_combat_pod_mode.m_pickup_pods.TryAdd(key, pickup_pod.Value.clone()); } foreach (var generation_info in m_combat_pod_mode.m_pickup_pod_generated_info) { var key = generation_info.Key; cloned.m_combat_pod_mode.m_pickup_pod_generated_info.TryAdd((key.Item1, key.Item2), generation_info.Value.clone()); } //Weapon 처리 foreach (var weapon in m_combat_pod_mode.m_weapons) { var key = weapon.Key; cloned.m_combat_pod_mode.m_weapons.TryAdd(key, weapon.Value.clone()); } //Buff 처리 foreach (var buff in m_combat_pod_mode.m_buffs) { var key = buff.Key; cloned.m_combat_pod_mode.m_buffs.TryAdd(key, buff.Value.clone()); } //기타 진행 상황 cloned.m_combat_pod_mode.m_round_state_type = m_combat_pod_mode.m_round_state_type; cloned.m_combat_pod_mode.m_current_round = m_combat_pod_mode.m_current_round; cloned.m_combat_pod_mode.m_current_state_start_time = m_combat_pod_mode.m_current_state_start_time; cloned.m_combat_pod_mode.m_charged_step = m_combat_pod_mode.m_charged_step; cloned.m_combat_pod_mode.m_rewarded_step = m_combat_pod_mode.m_rewarded_step; //택틱컬 보드 정보 foreach (var board in m_combat_pod_mode.m_tactical_board) { var key = board.Key; cloned.m_combat_pod_mode.m_tactical_board.TryAdd(key, board.Value.clone()); } return cloned; } public Result onMerge(EntityAttributeBase otherEntityAttribute) { var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!! - {toBasicString()}"); var result = new Result(); var err_msg = string.Empty; if (null == otherEntityAttribute) { err_msg = $"Invalid Param !!!, otherEntityAttribute is null"; result.setFail(ServerErrorCode.FunctionParamNull, err_msg); Log.getLogger().error(result.toBasicString()); return result; } var other_attribute = otherEntityAttribute as BattleInstanceSnapshotAttribute; if (null == other_attribute) { err_msg = $"Failed to cast BattleInstanceSnapshotAttribute !!!, other_attribute is null"; result.setFail(ServerErrorCode.ClassTypeCastIsNull, err_msg); Log.getLogger().error(result.toBasicString()); return result; } //===================================================================================== // OtherAttribute => Attribute //===================================================================================== m_room_id = other_attribute.m_room_id; m_combat_pod_mode.m_respawns = other_attribute.m_combat_pod_mode.m_respawns; m_combat_pod_mode.m_pod_storages = other_attribute.m_combat_pod_mode.m_pod_storages; m_combat_pod_mode.m_pod_combat = other_attribute.m_combat_pod_mode.m_pod_combat; m_combat_pod_mode.m_pickup_pods = other_attribute.m_combat_pod_mode.m_pickup_pods; m_combat_pod_mode.m_pickup_pod_generated_info = other_attribute.m_combat_pod_mode.m_pickup_pod_generated_info; m_combat_pod_mode.m_weapons = other_attribute.m_combat_pod_mode.m_weapons; m_combat_pod_mode.m_buffs = other_attribute.m_combat_pod_mode.m_buffs; m_combat_pod_mode.m_round_state_type = other_attribute.m_combat_pod_mode.m_round_state_type; m_combat_pod_mode.m_current_round = other_attribute.m_combat_pod_mode.m_current_round; m_combat_pod_mode.m_current_state_start_time = other_attribute.m_combat_pod_mode.m_current_state_start_time; m_combat_pod_mode.m_charged_step = other_attribute.m_combat_pod_mode.m_charged_step; m_combat_pod_mode.m_rewarded_step = other_attribute.m_combat_pod_mode.m_rewarded_step; m_combat_pod_mode.m_tactical_board = other_attribute.m_combat_pod_mode.m_tactical_board; //===================================================================================== // Attribute Try Pending Doc => Origin Doc //===================================================================================== var try_pending_doc = other_attribute.getTryPendingDocBase() as BattleInstanceSnapshotDoc; if (null != try_pending_doc) { other_attribute.resetTryPendingDocBase(); syncOriginDocBaseWithNewDoc(try_pending_doc); } var origin_doc_base = getOriginDocBase(); if (null == origin_doc_base) { // DB 에 저장되어 있지 않는 경우 OriginDoc은 null 이다 !!! return result; } var battle_instance_snapshot_attrib = origin_doc_base.getAttrib(); NullReferenceCheckHelper.throwIfNull(battle_instance_snapshot_attrib, () => $"battle_instance_snapshot_attrib is null !!! - {owner.toBasicString()}"); battle_instance_snapshot_attrib.m_room_id = m_room_id; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_respawns = m_combat_pod_mode.m_respawns; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_pod_storages = m_combat_pod_mode.m_pod_storages; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_pod_combat = m_combat_pod_mode.m_pod_combat; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_pickup_pods = m_combat_pod_mode.m_pickup_pods; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_pickup_pod_generated_info.AddRange(m_combat_pod_mode.m_pickup_pod_generated_info.Values); battle_instance_snapshot_attrib.m_combat_pod_attrib.m_weapons = m_combat_pod_mode.m_weapons; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_buffs = m_combat_pod_mode.m_buffs; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_round_state_type = m_combat_pod_mode.m_round_state_type; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_current_round = m_combat_pod_mode.m_current_round; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_current_state_start_time = m_combat_pod_mode.m_current_state_start_time; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_charged_step = m_combat_pod_mode.m_charged_step; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_rewarded_step = m_combat_pod_mode.m_rewarded_step; battle_instance_snapshot_attrib.m_combat_pod_attrib.m_tactical_board = m_combat_pod_mode.m_tactical_board; return result; } public bool copyEntityAttributeFromDoc(DynamoDbDocBase? docBase) { var battle_instance_snapshot_doc_base = docBase as BattleInstanceSnapshotDoc; if (null == battle_instance_snapshot_doc_base) { var to_cast_string = typeof(BattleInstanceSnapshotDoc).Name; var err_msg = $"Failed to copyEntityAttributeFromDoc() !!!, item_doc_base is null :{to_cast_string}"; Log.getLogger().error(err_msg); return false; } //===================================================================================== // New Doc => Origin Doc //===================================================================================== syncOriginDocBaseWithNewDoc(battle_instance_snapshot_doc_base); //===================================================================================== // Doc => Attribute //===================================================================================== var doc_attrib = battle_instance_snapshot_doc_base.getAttrib(); NullReferenceCheckHelper.throwIfNull(doc_attrib, () => $"doc_attrib is null !!! - {toBasicString()}"); m_room_id = doc_attrib.m_room_id; m_combat_pod_mode.m_respawns = doc_attrib.m_combat_pod_attrib.m_respawns; m_combat_pod_mode.m_pod_storages = doc_attrib.m_combat_pod_attrib.m_pod_storages; m_combat_pod_mode.m_pod_combat = doc_attrib.m_combat_pod_attrib.m_pod_combat; m_combat_pod_mode.m_pickup_pods = doc_attrib.m_combat_pod_attrib.m_pickup_pods; foreach (var generated_info in doc_attrib.m_combat_pod_attrib.m_pickup_pod_generated_info) { m_combat_pod_mode.m_pickup_pod_generated_info.AddOrUpdate((generated_info.m_group_id, generated_info.m_idx), generated_info, (key, old) => generated_info); } m_combat_pod_mode.m_weapons = doc_attrib.m_combat_pod_attrib.m_weapons; m_combat_pod_mode.m_buffs = doc_attrib.m_combat_pod_attrib.m_buffs; m_combat_pod_mode.m_round_state_type = doc_attrib.m_combat_pod_attrib.m_round_state_type; m_combat_pod_mode.m_current_round = doc_attrib.m_combat_pod_attrib.m_current_round; m_combat_pod_mode.m_current_state_start_time = doc_attrib.m_combat_pod_attrib.m_current_state_start_time; m_combat_pod_mode.m_charged_step = doc_attrib.m_combat_pod_attrib.m_charged_step; m_combat_pod_mode.m_rewarded_step = doc_attrib.m_combat_pod_attrib.m_rewarded_step; m_combat_pod_mode.m_tactical_board = doc_attrib.m_combat_pod_attrib.m_tactical_board; return true; } public override IEntityAttributeTransactor onNewEntityAttributeTransactor() { return new BattleInstanceSnapshotAttributeTransactor(getOwner()); } public class BattleInstanceSnapshotAttributeTransactor : EntityAttributeTransactorBase, ICopyEntityAttributeTransactorFromEntityAttribute { public BattleInstanceSnapshotAttributeTransactor(EntityBase owner) : base(owner) { } public bool copyEntityAttributeTransactorFromEntityAttribute(EntityAttributeBase entityAttributeBase) { var err_msg = string.Empty; var copy_from_attribute = entityAttributeBase as BattleInstanceSnapshotAttribute; if (null == copy_from_attribute) { err_msg = $"Failed to copyEntityAttributeTransactorFromEntityAttribute() !!!, copy_from_craft_attribute is null : BattleInstanceSnapshotAttribute"; Log.getLogger().error(err_msg); return false; } var copy_to_attribute = getClonedEntityAttribute() as BattleInstanceSnapshotAttribute; if (null == copy_to_attribute) { err_msg = $"Failed to copyEntityAttributeTransactorFromEntityAttribute() !!!, copy_to_craft_attribute is null : BattleInstanceSnapshotAttribute"; Log.getLogger().error(err_msg); return false; } copy_to_attribute.m_room_id = copy_from_attribute.m_room_id; copy_to_attribute.m_combat_pod_mode.m_respawns = copy_from_attribute.m_combat_pod_mode.m_respawns; copy_to_attribute.m_combat_pod_mode.m_pod_storages = copy_from_attribute.m_combat_pod_mode.m_pod_storages; copy_to_attribute.m_combat_pod_mode.m_pod_combat = copy_from_attribute.m_combat_pod_mode.m_pod_combat; copy_to_attribute.m_combat_pod_mode.m_pickup_pods = copy_from_attribute.m_combat_pod_mode.m_pickup_pods; copy_to_attribute.m_combat_pod_mode.m_pickup_pod_generated_info = copy_from_attribute.m_combat_pod_mode.m_pickup_pod_generated_info; copy_to_attribute.m_combat_pod_mode.m_weapons = copy_from_attribute.m_combat_pod_mode.m_weapons; copy_to_attribute.m_combat_pod_mode.m_buffs = copy_from_attribute.m_combat_pod_mode.m_buffs; copy_to_attribute.m_combat_pod_mode.m_round_state_type = copy_from_attribute.m_combat_pod_mode.m_round_state_type; copy_to_attribute.m_combat_pod_mode.m_current_round = copy_from_attribute.m_combat_pod_mode.m_current_round; copy_to_attribute.m_combat_pod_mode.m_current_state_start_time = copy_from_attribute.m_combat_pod_mode.m_current_state_start_time; copy_to_attribute.m_combat_pod_mode.m_charged_step = copy_from_attribute.m_combat_pod_mode.m_charged_step; copy_to_attribute.m_combat_pod_mode.m_rewarded_step = copy_from_attribute.m_combat_pod_mode.m_rewarded_step; copy_to_attribute.m_combat_pod_mode.m_tactical_board = copy_from_attribute.m_combat_pod_mode.m_tactical_board; return true; } } }