using GameServer.Contents.Battle.Reward; using GameServer.Contents.GameMode.Mode_Battle.Manage; using MetaAssets; using Nettention.Proud; using Newtonsoft.Json; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using ServerCore; namespace GameServer; public partial class BattleInstanceUpdateAction : EntityActionBase { public BattleInstanceUpdateAction(EntityBase owner) : base(owner) { } public override async Task onInit() { await Task.CompletedTask; var result = new Result(); return result; } public override void onClear() { } public async Task update() { var battle_instance_room = getOwner() as GameModeTPSFreeForAll; NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!"); var attribute = battle_instance_room.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!!"); var result = await battleObjectStateUpdate(battle_instance_room, attribute); if (result.isFail()) { Log.getLogger().error($"battleObjectStateUpdate result error !!! result : {result.toBasicString()}"); return result; } result = await battleInstanceStateUpdate(battle_instance_room, attribute); if (result.isFail()) { Log.getLogger().error($"battleInstanceStateUpdate result error !!! result : {result.toBasicString()}"); return result; } result = await battleInstancHostUpdate(battle_instance_room); if (result.isFail()) { Log.getLogger().error($"battleInstancHostUpdate result error !!! result : {result.toBasicString()}"); return result; } return result; } private async Task battleInstancHostUpdate(GameModeTPSFreeForAll battleInstanceRoom) { var result = new Result(); string host_user_guid = string.Empty; using (var releaser = await battleInstanceRoom.getAsyncLock()) { //이미 host 지정이 끝났으면 리턴 //kihoon todo : 일단 계속 체크해서 호스트가 얼마나 바뀌는지 확인 해보고 적절한 주기 찾아볼것 if (!battleInstanceRoom.m_host_migrator.getHostUserGuid().Equals(string.Empty)) return result; var p2p_group_id = battleInstanceRoom.getInstanceRoom().getMap().getP2PGroupId(); result = battleInstanceRoom.m_host_migrator.defineHost(p2p_group_id, new SuperPeerSelectionPolicy(), new HostID[1]); if (result.isFail()) return result; host_user_guid = battleInstanceRoom.m_host_migrator.getHostUserGuid(); Log.getLogger().info($"battleInstancHost set complete host_user_guid : {host_user_guid}"); } BattleRoomNotifyHelper.broadcast_GS2C_NTF_P2P_HOST_UPDATE(battleInstanceRoom.getInstanceRoom(), host_user_guid); return result; } private async Task battleObjectStateUpdate(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute) { var result = new Result(); await Task.CompletedTask; var now = DateTimeHelper.Current; List infos = new(); List log_infos = new(); using (var releaser = await battleInstanceRoom.getAsyncLock()) { (var weapon_info, var weapon_log_info) = battleObjectWeaponStateUpdate(attribute, now); infos.AddRange(weapon_info); log_infos.AddRange(weapon_log_info); (var buff_info, var buff_log_info) = battleObjectBuffStateUpdate(attribute, now); infos.AddRange(buff_info); log_infos.AddRange(buff_log_info); (var pickup_pod_info, var pickup_pod_log_info) = battleObjectPickupPodUpdate(attribute, now); infos.AddRange(pickup_pod_info); log_infos.AddRange(pickup_pod_log_info); } if (infos.Count > 0) { BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_OBJECT_STATE_INFO(battleInstanceRoom, infos); var invokers = new List(); var log_action = new LogAction(LogActionType.BattleObjectStateUpdate.ToString()); var business_log = new BattleObjectStateUpdateBusinessLog(battleInstanceRoom.getInstanceRoom().getMap().m_room_id, log_infos); invokers.Add(business_log); BusinessLogger.collectLogs(log_action, battleInstanceRoom, invokers); //kihoon todo : 이거 수정해야된다. } return result; } private (List, List) battleObjectPickupPodUpdate(BattleInstanceSnapshotAttribute attribute, DateTime now) { // if (attribute.m_combat_pod_mode.m_round_state_type.Equals(BattleRoundStateType.RoundEndAll) || // attribute.m_combat_pod_mode.m_round_state_type.Equals(BattleRoundStateType.Destroyed)) return new(); List infos = new(); List log_infos = new(); var battle_instance_room = getOwner() as GameModeTPSFreeForAll; NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!"); foreach (var generated_info in attribute.m_combat_pod_mode.m_pickup_pod_generated_info) { var group_id = generated_info.Key.Item1; var idx = generated_info.Key.Item2; if (false == attribute.m_combat_pod_mode.m_pickup_pod_generated_info.TryGetValue(generated_info.Key, out var generatedInfo)) { Log.getLogger().error($"m_pickup_pod_generated_info i : {idx} not exist!!!"); continue; } var anchor_guid = generatedInfo.m_anchor_guid; var next_generated_time = generatedInfo.m_next_generate_time; //아직 시간이 안됐거나, 할당된게 있으면 continue; if (now < next_generated_time || anchor_guid.Equals(string.Empty) == false) continue; //비어 있으면 할당 해준다. 시간체크는 보상 받았을때 해준다. (var result, var allocated_anchor_guid) = BattleRoomHelper.getRandomPickupPod(group_id, idx, battle_instance_room, attribute); if (result.isFail()) { Log.getLogger(result.toBasicString()); continue; } if(false == battle_instance_room.getInstanceRoom().getMap().getAnchors().TryGetValue(allocated_anchor_guid, out var anchorInfo)) { Log.getLogger().error($"not exist anchor anchor_guid : {allocated_anchor_guid}"); continue; } var table_id = anchorInfo.AnchorProp.TableId; if (false == MetaData.Instance._BattleObjectSpawnGroupMetaTable.TryGetValue(table_id, out var battle_object_spawn_group)) { Log.getLogger().error($"not exist _BattleObjectSpawnGroupMetaTable anchor_guid : {allocated_anchor_guid}, tableid : {table_id}"); continue; } PickupPodGeneratedInfo new_generated_info = new(generated_info.Key.Item1, generated_info.Key.Item2, allocated_anchor_guid, generatedInfo.m_anchor_guid, generatedInfo.m_next_generate_time); attribute.m_combat_pod_mode.m_pickup_pod_generated_info.AddOrUpdate(generated_info.Key, new_generated_info, (i, tuple) => new_generated_info); if (false == attribute.m_combat_pod_mode.m_pickup_pods.TryGetValue(allocated_anchor_guid, out var pickupPod)) { var err_msg = $"pickup pod date not exist !! allocated_anchor_guid : {allocated_anchor_guid}, roomId : {battle_instance_room.getRoomId()}"; Log.getLogger().error(err_msg); continue; } pickupPod.m_is_active = true; BattleObjectInfo info = new(); info.AnchorGuid = allocated_anchor_guid; info.IsActive = pickupPod.m_is_active ? BoolType.True : BoolType.False; infos.Add(info); BattleObjectLogInfo log_info = new(); log_info.m_anchor_guid = pickupPod.m_anchor_guid; log_info.m_battle_object_type = pickupPod.m_type; log_info.m_active_time = pickupPod.m_active_time; log_infos.Add(log_info); } return (infos, log_infos); } private (List, List) battleObjectBuffStateUpdate(BattleInstanceSnapshotAttribute attribute, DateTime now) { List infos = new(); List log_infos = new(); foreach (BattleObjectBuff buff in attribute.m_combat_pod_mode.m_buffs.Values) { if (buff.m_active_time <= now && buff.m_is_active == false) { buff.m_is_active = true; BattleObjectInfo info = new(); info.AnchorGuid = buff.m_anchor_guid; info.IsActive = BoolType.True; infos.Add(info); BattleObjectLogInfo log_info = new(); log_info.m_anchor_guid = buff.m_anchor_guid; log_info.m_battle_object_type = buff.m_type; log_info.m_active_time = buff.m_active_time; log_infos.Add(log_info); } } return (infos, log_infos); } private (List, List) battleObjectWeaponStateUpdate(BattleInstanceSnapshotAttribute attribute, DateTime now) { List infos = new(); List log_infos = new(); foreach (BattleObjectWeapon weapon in attribute.m_combat_pod_mode.m_weapons.Values) { if (weapon.m_active_time <= now && weapon.m_is_active == false) { weapon.m_is_active = true; BattleObjectInfo info = new(); info.AnchorGuid = weapon.m_anchor_guid; info.IsActive = BoolType.True; infos.Add(info); BattleObjectLogInfo log_info = new(); log_info.m_anchor_guid = weapon.m_anchor_guid; log_info.m_battle_object_type = weapon.m_type; log_info.m_active_time = weapon.m_active_time; log_infos.Add(log_info); } } return (infos, log_infos); } public Result battleObjectStateInitAndNotify(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute) { var infos = new List(); var result = new Result(); foreach (BattleObjectPodStorage storage in attribute.m_combat_pod_mode.m_pod_storages.Values) { storage.m_reward_cnt = 0; storage.m_is_active = true; BattleObjectInfo info = new(); info.AnchorGuid = storage.m_anchor_guid; info.IsActive = BoolType.True; infos.Add(info); } BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_OBJECT_STATE_INFO(battleInstanceRoom, infos); return result; } public async Task createCombatPod(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute) { await Task.CompletedTask; var result = new Result(); var combat_pod_guid = System.Guid.NewGuid().ToString("N"); (result, var anchor_guid) = BattleRoomHelper.getRandomCombatPodAnchorGuid(attribute, battleInstanceRoom); if (result.isFail()) return result; attribute.m_combat_pod_mode.m_pod_combat = new BattleObjectPodCombat(combat_pod_guid, anchor_guid, DateTimeHelper.Current); return result; } public async Task createPickupPodReward(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute) { await Task.CompletedTask; var result = new Result(); var max_reward_count = 0; foreach (var pickup_pod_group in battleInstanceRoom.m_battle_pickup_pod_guid_group) { var group_id = pickup_pod_group.Key; var pickup_pod_guids = pickup_pod_group.Value; foreach (var guid in pickup_pod_guids) { if (false == battleInstanceRoom.getInstanceRoom().getMap().getAnchors().TryGetValue(guid, out var anchorInfo)) { var err_msg = $"Not exitst anchorInfo guid : {guid}"; result.setFail(ServerErrorCode.BattleInstanceNotExistAnchors, err_msg); Log.getLogger(result.toBasicString()); continue; } var table_id = anchorInfo.AnchorProp.TableId; if (false == MetaData.Instance._BattleObjectSpawnGroupMetaTable.TryGetValue(table_id, out var objectSpawnGroupMetaData)) { var err_msg = $"Not exitst objectSpawnGroupMetaData guid : {guid}, tableId : {table_id}"; result.setFail(ServerErrorCode.BattleInstanceObjectMetaNotExist, err_msg); Log.getLogger(result.toBasicString()); continue; } max_reward_count = objectSpawnGroupMetaData.MaxSpawnQuantity; break; } await createPickupPodRewardByGroup(battleInstanceRoom, attribute, group_id, max_reward_count); } return result; } public async Task createPickupPodRewardByGroup(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, Int32 groupId, Int32 maxRewardCount) { await Task.CompletedTask; var result = new Result(); for (int i = 0; i < maxRewardCount; i++) { (result, var anchor_guid) = BattleRoomHelper.getRandomPickupPod(groupId, i, battleInstanceRoom, attribute); if (result.isFail()) { return result; } PickupPodGeneratedInfo new_generated_info = new(groupId, i, anchor_guid, string.Empty, DateTimeHelper.Current); if(false == attribute.m_combat_pod_mode.m_pickup_pod_generated_info.TryGetValue((groupId, i), out var generatedInfo)) { attribute.m_combat_pod_mode.m_pickup_pod_generated_info.TryAdd((groupId, i), new_generated_info); } if (generatedInfo is not null) { new_generated_info.m_before_anchor_guid = generatedInfo.m_anchor_guid; } Log.getLogger().info($"create pickup pod generation info new_generated_info : {JsonConvert.SerializeObject(new_generated_info)}"); attribute.m_combat_pod_mode.m_pickup_pod_generated_info.AddOrUpdate((groupId, i), new_generated_info, (key, tuple) => new_generated_info); if (false == attribute.m_combat_pod_mode.m_pickup_pods.TryGetValue(anchor_guid, out var pickupPod)) { Log.getLogger().error($"create pickup pod reward not exista anchor guid : {anchor_guid} origin keys : {JsonConvert.SerializeObject(attribute.m_combat_pod_mode.m_pickup_pods.Keys)}"); continue; } pickupPod.m_is_active = true; } return result; } public async Task<(Result, List, int, int)> podCombatUpdateIfHasOccupier(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, Player player) { var result = new Result(); var occupier_guid = attribute.m_combat_pod_mode.m_pod_combat.m_current_occupier_guid; if (occupier_guid.Equals(string.Empty)) return (result, new(), 0, 0); var max_charge_level = battleInstanceRoom.m_ffa_reward_meta .Where(kvp => kvp.Key == battleInstanceRoom.m_ffa_reward_meta.Keys.Max()) .Select(kvp => kvp.Key) .FirstOrDefault(); var rewardable_step_start = attribute.m_combat_pod_mode.m_rewarded_step; var rewardable_step_end = max_charge_level; var rewards = makePodCombatOccupyReward(rewardable_step_start, rewardable_step_end, battleInstanceRoom); result = await addPodCommbatOccupyReward(player, battleInstanceRoom, rewards); if (result.isFail()) return (result, new(), 0, 0); attribute.m_combat_pod_mode.m_rewarded_step = max_charge_level; attribute.m_combat_pod_mode.m_charged_step = max_charge_level; return (result, rewards, rewardable_step_start, rewardable_step_end); } private async Task addPodCommbatOccupyReward(Player player, GameModeTPSFreeForAll battleInstanceRoom, List rewards) { IReward reward_proc = new RewardPodCombat(player, player.getUserGuid(), rewards); var result = await RewardManager.It.proceedRewardProcess(reward_proc); if (result.isFail()) { return result; } RewardManager.It.postRewardProcess(reward_proc); return result; } private List makePodCombatOccupyReward(int start, int end, GameModeTPSFreeForAll battleInstanceRoom) { List rewards = new(); for (int i = start + 1; i <= end; i++) { if (i == 0) continue; if (false == battleInstanceRoom.m_ffa_reward_meta.TryGetValue(i, out var ffaRewardData)) { Log.getLogger().error($"m_ffa_reward_meta not exist battleInstanceRoom i : {i}, meta : {JsonConvert.SerializeObject(battleInstanceRoom.m_ffa_reward_meta)}"); continue; } var item_id = ffaRewardData.RewardItemID; var item_count = ffaRewardData.RewardCount * battleInstanceRoom.m_hot_time_reward; RewardMutable reward_metable = new(); reward_metable.Item = new(); reward_metable.Item.Id = item_id; reward_metable.Item.Count = item_count; MetaAssets.Reward reward = new MetaAssets.Reward(reward_metable); rewards.Add(reward); Log.getLogger().Debug($"pod Combat reward Added step : {i}, ItemId : {item_id}, itemCount : {item_count}"); } return rewards; } private List battleObjectPickupPodsDeactive(BattleInstanceSnapshotAttribute attribute) { List infos = new(); foreach (var pickup in attribute.m_combat_pod_mode.m_pickup_pods.Values) { pickup.m_is_active = false; BattleObjectInfo info = new(); info.AnchorGuid = pickup.m_anchor_guid; info.IsActive = BoolType.False; infos.Add(info); } var now = DateTimeHelper.Current; foreach(var generated_info in attribute.m_combat_pod_mode.m_pickup_pod_generated_info) { var idx = generated_info.Key; var anchor_guid = generated_info.Value.m_anchor_guid; var next_generated_time = generated_info.Value.m_next_generate_time; PickupPodGeneratedInfo new_info = new(idx.Item1, idx.Item2, string.Empty, string.Empty, now); attribute.m_combat_pod_mode.m_pickup_pod_generated_info.AddOrUpdate(idx, new_info, (i, tuple) => new_info); } return infos; } private List battleObjectPodStoragesDeactive(BattleInstanceSnapshotAttribute attribute) { List infos = new(); foreach (var sotrage in attribute.m_combat_pod_mode.m_pod_storages.Values) { sotrage.m_is_active = false; BattleObjectInfo info = new(); info.AnchorGuid = sotrage.m_anchor_guid; info.IsActive = BoolType.False; infos.Add(info); } return infos; } }