using System.Net; using GameServer.Contents.Battle.Log; using GameServer.Contents.GameMode.Manage.PlayManage; using GameServer.Contents.GameMode.Mode_Battle.Manage; using MetaAssets; using ServerBase; using ServerCommon; using ServerCore; namespace GameServer; public class BattleInstanceAction : EntityActionBase { public BattleInstanceAction(EntityBase owner) : base(owner) { } public override Task onInit() { var result = new Result(); return Task.FromResult(result); } public override void onClear() { } public async Task loadOrCreateSnapshot() { var result = new Result(); var game_mode_base = getOwner() as GameModeBase; NullReferenceCheckHelper.throwIfNull(game_mode_base, () => $"game_mode_base is null !!!"); var server_logic = GameServerApp.getServerLogic(); var dynamodb_client = server_logic.getDynamoDbClient(); string room_id = game_mode_base.getRoomId(); var config = dynamodb_client.makeQueryConfigForReadByPKSK(BattleInstanceSnapshotDoc.pk, room_id); (result, var read_docs) = await dynamodb_client.simpleQueryDocTypesWithQueryOperationConfig(config); if(result.isFail()) { return result; } var event_id = BattleRoomHelper.getBattleEventIdFromRoomId(room_id); BattleInstanceSnapshotDoc doc = new(room_id); //string snapshot_load_type = "LOAD"; if (read_docs.Count == 0 || event_id == 0) { //데이터가 없으므로 생성 처리 result = await createBattleInstanceSnapshot(room_id); if (result.isFail()) return result; // snapshot_load_type = "CREATE"; } else if (read_docs.Count > 0) { doc = read_docs[0]; var battle_instance_action = game_mode_base.getEntityAction(); NullReferenceCheckHelper.throwIfNull(battle_instance_action, () => $"battle_instance_action is null !!!"); result = battle_instance_action.setSnapshotFromDoc(doc); } if (result.isFail()) return result; Log.getLogger().debug($"loadOrCreateSnapshot room_id : {game_mode_base.toBasicString()}"); var attribute = game_mode_base.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!!"); //kihoon todo : 이거 Base쪽으로 올려야 된다. //var invokers = new List(); //var log_action = new LogAction(LogActionType.BattleInstanceSnapshotCreate); //BattleSnapShotBusinessLog business_log = new(battle_instance_room, snapshot_load_type); //invokers.Add(business_log); //BusinessLogger.collectLogs(log_action, battle_instance_room, invokers); return result; } private async Task createBattleInstanceSnapshot(string roomId) { var result = new Result(); await Task.CompletedTask; BattleInstanceSnapshotDoc doc = new(roomId); var game_mode_base = getOwner() as GameModeBase; NullReferenceCheckHelper.throwIfNull(game_mode_base, () => $"battle_instance_room is null !!!"); var game_mode_ffa = getOwner() as GameModeTPSFreeForAll; NullReferenceCheckHelper.throwIfNull(game_mode_ffa, () => $"battle_instance_room is null !!!"); var server_logic = GameServerApp.getServerLogic(); var fn_create_battle_instance_snapshot = async delegate() { var battle_instance_snaptshot_attribute = game_mode_base.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(battle_instance_snaptshot_attribute, () => $"battle_instance_snaptshot_attribute is null !!!"); battle_instance_snaptshot_attribute.m_room_id = roomId; battle_instance_snaptshot_attribute.m_combat_pod_mode.m_current_state_start_time = game_mode_ffa.m_battle_instance_event_start_time; //kihoon 이거다 수정해야된다. addRespawnPosInfoFromMeta(game_mode_ffa, battle_instance_snaptshot_attribute); addStorageInfoFromMeta(game_mode_ffa, battle_instance_snaptshot_attribute); addPickupPodInfoFromMeta(game_mode_ffa, battle_instance_snaptshot_attribute); var anchors = game_mode_base.getInstanceRoom().getMap().getAnchors(); foreach (var anchor in anchors) { addBattleObjectWeapon(battle_instance_snaptshot_attribute, anchor.Value); addBattleObjectBuff(battle_instance_snaptshot_attribute, anchor.Value); } var result = await createBattleObjectCombatPod(game_mode_ffa, battle_instance_snaptshot_attribute); if (result.isFail()) return result; result = await createBattleObjectPickupPodReward(game_mode_ffa, battle_instance_snaptshot_attribute); if (result.isFail()) return result; battle_instance_snaptshot_attribute.modifiedEntityAttribute(true); //kihoon todo : 이거 수정해야된다. var batch = new QueryBatchEx(game_mode_base, LogActionType.BattleInstanceSnapshotCreate, server_logic.getDynamoDbClient()); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); } result = await QueryHelper.sendQueryAndBusinessLog(batch); return result; }; result = await game_mode_base.runTransactionRunnerSafelyWithTransGuid(game_mode_base.getRoomId(), TransactionIdType.PrivateContents, BattleConstant.BATTLE_INSTANCE_TRANSACTION_NAME, fn_create_battle_instance_snapshot); if (result.isFail()) { var err_msg = $"Failed to runTransactionRunnerSafelyWithTransGuid() !!! : {result.toBasicString()} - CreateBattleInstanceSnapshot, {game_mode_base.toBasicString()}"; Log.getLogger().error(err_msg); return result; } return result; } private Result setSnapshotFromDoc(BattleInstanceSnapshotDoc doc) { var result = new Result(); var battle_instance_snapshot_attrib = doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(battle_instance_snapshot_attrib, () => $"battle_instance_snapshot_attrib is null !!!"); var battle_instance_room = getOwner() as GameModeBase; NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!"); var attribute = battle_instance_room.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!!"); attribute.copyEntityAttributeFromDoc(doc); attribute.syncOriginDocBaseWithNewDoc(doc); return result; } // private void deleteChangedGuidAnchor(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib) // { // deleteChangedBattleObjectPodStorageAnchor(battleInstanceRoom, attribute, attrib); // deleteChangedBattleObjectPickupPodAnchor(battleInstanceRoom, attribute, attrib); // deleteChangedRespawnAnchor(battleInstanceRoom, attribute, attrib); // deleteChangedBattleObjectWeaponAnchor(battleInstanceRoom, attribute, attrib); // deleteChangedBattleObjectBuffAnchor(battleInstanceRoom, attribute, attrib); // // //pod combat은 timer에서 처리해준다. // } private void setNewGuidAnchor(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute) { addRespawnPosInfoFromMeta(battleInstanceRoom, attribute); addStorageInfoFromMeta(battleInstanceRoom, attribute); addPickupPodInfoFromMeta(battleInstanceRoom, attribute); var anchors = battleInstanceRoom.getInstanceRoom().getMap().getAnchors(); foreach (var anchor in anchors) { addBattleObjectWeapon(attribute, anchor.Value); addBattleObjectBuff(attribute, anchor.Value); } } private void deleteChangedBattleObjectPodStorageAnchor(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib) { List delete_keys = new(); foreach (var stand in attrib.m_combat_pod_attrib.m_pod_storages) { //기존에 들고 있던 guid 가 map에서 없어지거나 바뀌었을 경우가 있을수 있으므로 예외 처리 if (false == battleInstanceRoom.getInstanceRoom().getMap().getAnchors().ContainsKey(stand.Key)) { Log.getLogger().warn($"stand : {stand.Key} is not exist.. so don't add attribute.... roomId : {battleInstanceRoom.getRoomId()}"); delete_keys.Add(stand.Key); continue; } attribute.m_combat_pod_mode.m_pod_storages.TryAdd(stand.Key, stand.Value); } foreach (var delete_key in delete_keys) { attribute.m_combat_pod_mode.m_pod_storages.TryRemove(delete_key, out _); } } private void deleteChangedBattleObjectPickupPodAnchor(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib) { List delete_keys = new(); foreach (var box in attrib.m_combat_pod_attrib.m_pickup_pods) { //기존에 들고 있던 guid 가 map에서 없어지거나 바뀌었을 경우가 있을수 있으므로 예외 처리 if (false == battleInstanceRoom.getInstanceRoom().getMap().getAnchors().ContainsKey(box.Key)) { Log.getLogger().info($"box : {box.Key} is not exist.. so don't add attribute.... roomId : {battleInstanceRoom.getRoomId()}"); delete_keys.Add(box.Key); continue; } attribute.m_combat_pod_mode.m_pickup_pods.TryAdd(box.Key, box.Value); } foreach (var delete_key in delete_keys) { attribute.m_combat_pod_mode.m_pickup_pods.TryRemove(delete_key, out _); } } private void deleteChangedRespawnAnchor(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib) { List delete_keys = new(); foreach (var each in attrib.m_combat_pod_attrib.m_respawns) { //map에 respawn pos가 없어지거나 바뀌었을 경우가 있을수 있으므로 예외 처리 if (false == battleInstanceRoom.m_respawn_pos_anchors_meta.Contains(each.Key)) { Log.getLogger().warn($"spawn idx : {each.Key} is not exist.. so don't add attribute.... roomId : {battleInstanceRoom.getRoomId()}"); delete_keys.Add(each.Key); continue; } attribute.m_combat_pod_mode.m_respawns.TryAdd(each.Key, each.Value); } foreach (var delete_key in delete_keys) { attribute.m_combat_pod_mode.m_respawns.TryRemove(delete_key, out _); } } private void deleteChangedBattleObjectWeaponAnchor(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib) { List delete_keys = new(); foreach (var weapon in attrib.m_combat_pod_attrib.m_weapons) { //기존에 들고 있던 guid 가 map에서 없어지거나 바뀌었을 경우가 있을수 있으므로 예외 처리 if (false == battleInstanceRoom.getInstanceRoom().getMap().getAnchors().ContainsKey(weapon.Key)) { Log.getLogger().warn($"weapon : {weapon.Key} is not exist.. so don't add attribute.... roomId : {battleInstanceRoom.getRoomId()}"); delete_keys.Add(weapon.Key); continue; } attribute.m_combat_pod_mode.m_weapons.TryAdd(weapon.Key, weapon.Value); } foreach (var delete_key in delete_keys) { attribute.m_combat_pod_mode.m_weapons.TryRemove(delete_key, out _); } } private void deleteChangedBattleObjectBuffAnchor(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib) { List delete_keys = new(); foreach (var buff in attrib.m_combat_pod_attrib.m_buffs) { //map에 respawn pos가 없어지거나 바뀌었을 경우가 있을수 있으므로 예외 처리 if (false == battleInstanceRoom.getInstanceRoom().getMap().getAnchors().ContainsKey(buff.Key)) { Log.getLogger().warn($"buff : {buff.Key} is not exist.. so don't add attribute.... roomId : {battleInstanceRoom.getInstanceRoom().getMap().m_room_id}"); delete_keys.Add(buff.Key); continue; } attribute.m_combat_pod_mode.m_buffs.TryAdd(buff.Key, buff.Value); } foreach (var delete_key in delete_keys) { attribute.m_combat_pod_mode.m_buffs.TryRemove(delete_key, out _); } } private void addRespawnPosInfoFromMeta(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute) { var now = DateTimeHelper.Current; foreach (var anchor_guid in battleInstanceRoom.m_respawn_pos_anchors_meta) { if (attribute.m_combat_pod_mode.m_respawns.ContainsKey(anchor_guid)) continue; attribute.m_combat_pod_mode.m_respawns.TryAdd(anchor_guid, now); } } private void addStorageInfoFromMeta(GameModeTPSFreeForAll ffa, BattleInstanceSnapshotAttribute attribute) { foreach (var storage_group in ffa.m_battle_pod_storage_guid_group.Values) { foreach (var anchor_guid in storage_group) { addBattleObjectPodStorage(attribute, anchor_guid); } } } private void addPickupPodInfoFromMeta(GameModeTPSFreeForAll ffa, BattleInstanceSnapshotAttribute attribute) { foreach (var pickup_pod_group in ffa.m_battle_pickup_pod_guid_group.Values) { foreach (var anchor_guid in pickup_pod_group) { addBattleObjectPickupPod(attribute, anchor_guid); } } } private void addBattleObjectWeapon(BattleInstanceSnapshotAttribute attribute, AnchorInfo anchorInfo) { if (attribute.m_combat_pod_mode.m_weapons.ContainsKey(anchorInfo.AnchorGuid)) return; var talbe_id = anchorInfo.AnchorProp.TableId; if (false == MetaData.Instance._BattleObjectMetaTable.TryGetValue(talbe_id, out var battle_object)) return; if (false == battle_object.ObjectType.Equals(EBattleObjectType.Weapon)) return; BattleObjectWeapon weapon = new(anchorInfo.AnchorGuid); attribute.m_combat_pod_mode.m_weapons.TryAdd(anchorInfo.AnchorGuid, weapon); } private void addBattleObjectBuff(BattleInstanceSnapshotAttribute attribute, AnchorInfo anchorInfo) { if (attribute.m_combat_pod_mode.m_buffs.ContainsKey(anchorInfo.AnchorGuid)) return; var talbe_id = anchorInfo.AnchorProp.TableId; if (false == MetaData.Instance._BattleObjectMetaTable.TryGetValue(talbe_id, out var battle_object)) return; if (false == battle_object.ObjectType.Equals(EBattleObjectType.Buff)) return; BattleObjectBuff buff = new(anchorInfo.AnchorGuid); attribute.m_combat_pod_mode.m_buffs.TryAdd(anchorInfo.AnchorGuid, buff); } private void addBattleObjectPodStorage(BattleInstanceSnapshotAttribute attribute, string anchorGuid) { if (attribute.m_combat_pod_mode.m_pod_storages.ContainsKey(anchorGuid)) return; BattleObjectPodStorage storage = new(anchorGuid); attribute.m_combat_pod_mode.m_pod_storages.TryAdd(anchorGuid, storage); } private void addBattleObjectPickupPod(BattleInstanceSnapshotAttribute attribute, string anchorGuid) { if (attribute.m_combat_pod_mode.m_pickup_pods.ContainsKey(anchorGuid)) return; //신규 생성이라 false로 BattleObjectPickupPod pickup = new(anchorGuid); pickup.m_is_active = false; attribute.m_combat_pod_mode.m_pickup_pods.TryAdd(anchorGuid, pickup); } private async Task createBattleObjectPickupPodReward(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute) { var result = new Result(); var battle_update_action = battleInstanceRoom.getEntityAction(); NullReferenceCheckHelper.throwIfNull(battle_update_action, () => $"battle_update_action is null !!!"); await battle_update_action.createPickupPodReward(battleInstanceRoom, attribute); return result; } private async Task createBattleObjectCombatPod(GameModeTPSFreeForAll battleInstanceRoom, BattleInstanceSnapshotAttribute attribute) { var battle_update_action = battleInstanceRoom.getEntityAction(); NullReferenceCheckHelper.throwIfNull(battle_update_action, () => $"battle_update_action is null !!!"); var result = await battle_update_action.createCombatPod(battleInstanceRoom, attribute); if (result.isFail()) return result; //여기서 PodCombatState 패킷전송 //BattleRoomNotifyHelper.send_GS2C_NTF_POD_COMBAT_STATE(); return result; } // private void setBattleObjectPodCombat(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib) // { // // foreach (var pod_combat in attrib.m_combat_pod_attrib.m_combat_pods) // { // //var pod_combat_guid = pod_combat.Key; // //attribute.m_pod_combat_mode.m_pod_combats.AddOrUpdate(pod_combat.Key, pod_combat.Value, (key, old) => pod_combat.Value); // } // } }