250501 커밋

This commit is contained in:
2025-05-01 07:23:28 +09:00
parent 98bb2e3c5c
commit 23176551b7
353 changed files with 9972 additions and 6652 deletions

View File

@@ -0,0 +1,512 @@
using GameServer.Contents.GameMode.Mode_Battle.Manage;
using MetaAssets;
using Newtonsoft.Json;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using ServerCore;
namespace GameServer;
public partial class BattleInstanceUpdateAction
{
private async Task<Result> battleInstanceStateUpdate(GameModeTPSFreeForAll<GameModeTPSFreeForAllData> battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
var result = new Result();
var round_state = attribute.m_combat_pod_mode.m_round_state_type;
switch (round_state)
{
case BattleRoundStateType.Rounding:
//라운드가 끝났을때 Wait 혹은 End 처리
result = await battleInstanceRoundingStateUpdate(battleInstanceRoom, attribute);
break;
case BattleRoundStateType.RoundWait:
//시간 됐을때 Rounding 처리
result = await battleInstanceWaitStateUpdate(battleInstanceRoom, attribute);
break;
case BattleRoundStateType.RoundEndAll:
//시간 지났을때 kick 처리
result = await battleInstanceEndStateUpdate(battleInstanceRoom, attribute);
break;
case BattleRoundStateType.Destroyed:
break;
default:
Log.getLogger().error($"BattleRoundStateType None error room_id : {battleInstanceRoom.getRoomId()}");
return result;
}
return result;
}
private async Task<Result> battleInstanceWaitStateUpdate(GameModeTPSFreeForAll<GameModeTPSFreeForAllData> battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
var result = new Result();
await Task.CompletedTask;
var now = DateTimeHelper.Current;
var state_start_time = attribute.m_combat_pod_mode.m_current_state_start_time;
var wait_end_time = state_start_time.AddSeconds(battleInstanceRoom.m_ffa_config_meta.NextRoundWaitTime);
//시간이 지났을 경우 state 바꿔주는 처리 필요
if (now < wait_end_time) return result;
using (var releaser = await battleInstanceRoom.getAsyncLock())
{
attribute.m_combat_pod_mode.m_round_state_type = BattleRoundStateType.Rounding;
attribute.m_combat_pod_mode.m_current_state_start_time = wait_end_time;
attribute.m_combat_pod_mode.m_current_round += 1;
attribute.m_combat_pod_mode.m_charged_step = 0;
attribute.m_combat_pod_mode.m_rewarded_step = 0;
attribute.m_combat_pod_mode.m_pod_combat.setActive(now);
(result, var anchor_guid) = BattleRoomHelper.getRandomCombatPodAnchorGuid(attribute, battleInstanceRoom);
if (result.isFail())
{
Log.getLogger().Error("get Random pod combat anchor guid faile !!! ");
return result;
}
attribute.m_combat_pod_mode.m_pod_combat.m_source_storage_anchor_guid = anchor_guid;
}
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_INSTANCE_STATE(battleInstanceRoom);
BattleRoomNotifyHelper.broadcast_GS2C_NTF_POD_COMBAT_STATE(battleInstanceRoom);
battleObjectStateInitAndNotify(battleInstanceRoom, attribute);
//로그 추가
var invokers = new List<ILogInvoker>();
var log_action = new LogAction(LogActionType.BattleRoundStateUpdate.ToString());
var room_id = battleInstanceRoom.getRoomId();
var ended_round = attribute.m_combat_pod_mode.m_current_round;
var round_state = attribute.m_combat_pod_mode.m_round_state_type;
var users = battleInstanceRoom.getInstanceRoom().tryGetInstanceExistUserForLog();
BattleRoundUpdateBusinessLog business_log = new(room_id, ended_round, round_state, users);
invokers.Add(business_log);
//BusinessLogger.collectLogs(log_action, battleInstanceRoom, invokers); //kihoon todo : 이거 수정해야된다.
return result;
}
private async Task<Result> battleInstanceRoundingStateUpdate(GameModeTPSFreeForAll<GameModeTPSFreeForAllData> battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
var result = new Result();
var now = DateTimeHelper.Current;
var round_start_time = attribute.m_combat_pod_mode.m_current_state_start_time;
var round_end_time = round_start_time.AddSeconds(battleInstanceRoom.m_ffa_config_meta.RoundTime);
//라운드에 대한 시간이 지났을 경우 state 바꿔주는 처리 필요
if (round_end_time <= now)
{
await roundingUpdate(battleInstanceRoom, round_end_time);
}
else
{
await podCombatRewardUpdate(battleInstanceRoom, attribute, now);
await stepUpdate(battleInstanceRoom, attribute, now);
}
return result;
}
private async Task roundingUpdate(GameModeTPSFreeForAll<GameModeTPSFreeForAllData> battleInstanceRoom, DateTime roundEndTime)
{
var result = new Result();
string occupier_guid = string.Empty;
using (var releaser = await battleInstanceRoom.getAsyncLock())
{
var attribute = battleInstanceRoom.getEntityAttribute<BattleInstanceSnapshotAttribute>();
NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!! - {battleInstanceRoom.toBasicString()}");
occupier_guid = attribute.m_combat_pod_mode.m_pod_combat.m_current_occupier_guid;
Player? rewarded_player = null;
if (!occupier_guid.Equals(string.Empty))
{
if (false == battleInstanceRoom.getInstanceRoom().tryGetInstanceMember(occupier_guid, out rewarded_player))
{
//보상은 안되더라도 라운드는 진행 가능하게 처리해야할듯...
var err_msg = $"not exist user in instance_room !!! user_guid : {occupier_guid}";
Log.getLogger().error(err_msg);
}
}
if (rewarded_player is null)
{
result = await roundingUpdateWithoutReward(battleInstanceRoom, roundEndTime);
}
else
{
result = await roundingUpdateWithReward(battleInstanceRoom, roundEndTime, rewarded_player);
}
if (result.isFail())
{
Log.getLogger().error(result.toBasicString());
}
}
}
private async Task<Result> roundingUpdateWithReward(GameModeTPSFreeForAll<GameModeTPSFreeForAllData> battleInstanceRoom, DateTime roundEndTime, Player player)
{
var result = new Result();
//bool need_battle_end_result_noti = false;
var server_logic = GameServerApp.getServerLogic();
List<BattleObjectInfo> infos = new();
CommonResult common_result = new();
var fn_battle_round_update = async delegate()
{
var attribute = battleInstanceRoom.getEntityAttribute<BattleInstanceSnapshotAttribute>();
NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!! - {battleInstanceRoom.toBasicString()}");
if (battleInstanceRoom.m_round_count <= attribute.m_combat_pod_mode.m_current_round)
{
attribute.m_combat_pod_mode.m_round_state_type = BattleRoundStateType.RoundEndAll;
//배틍 종료에 대한 정보를 알려줄지 말지에 대한 noti
//need_battle_end_result_noti = true;
}
else
{
attribute.m_combat_pod_mode.m_round_state_type = BattleRoundStateType.RoundWait;
}
attribute.m_combat_pod_mode.m_current_state_start_time = roundEndTime;
(result, var rewards, var reward_start_step, var reward_end_step) = await podCombatUpdateIfHasOccupier(battleInstanceRoom, attribute, player);
if (result.isFail()) return result;
//모든 픽업포드 비활성화, 모든 스토리지 비활성화
infos.AddRange(battleObjectPickupPodsDeactive(attribute));
infos.AddRange(battleObjectPodStoragesDeactive(attribute));
attribute.m_combat_pod_mode.m_pod_combat.setDeactive();
attribute.modifiedEntityAttribute(true);
Log.getLogger().debug($"roundingUpdateWithReward attribute info : {JsonConvert.SerializeObject(attribute)}");
(result, var doc) = await attribute.toDocBase();
if (result.isFail()) return result;
//batch 처리
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.BattleRoundStateUpdate, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
if (doc is not null)
{
batch.addQuery(new DBQEntityWrite(doc));
}
}
//로그 추가
var room_id = battleInstanceRoom.getRoomId();
var ended_round = attribute.m_combat_pod_mode.m_current_round;
var round_state = attribute.m_combat_pod_mode.m_round_state_type;
var users = battleInstanceRoom.getInstanceRoom().tryGetInstanceExistUserForLog();
BattleRoundUpdateBusinessLog business_log = new(room_id, ended_round, round_state, users);
batch.appendBusinessLog(business_log);
BattlePodCombatRewardBusinessLog combat_business_log = new(room_id, ended_round, round_state
, player.getUserGuid(), player.getUserNickname()
, reward_start_step, reward_end_step, rewards);
batch.appendBusinessLog(combat_business_log);
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail()) return result;
//보상 내용 가져올것
var found_transaction_runner = player.findTransactionRunner(TransactionIdType.PrivateContents);
NullReferenceCheckHelper.throwIfNull(found_transaction_runner, () => $"found_transaction_runner is null !!! - {battleInstanceRoom.toBasicString()}");
common_result = found_transaction_runner.getCommonResult();
return result;
};
result = await player.runTransactionRunnerSafelyWithTransGuid(player.getUserGuid(), TransactionIdType.PrivateContents, BattleConstant.BATTLE_INSTANCE_TRANSACTION_NAME, fn_battle_round_update);
if (result.isFail())
{
var err_msg = $"Failed to runTransactionRunnerSafelyWithTransGuid() !!! : {result.toBasicString()}, {battleInstanceRoom.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_INSTANCE_STATE(battleInstanceRoom);
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_OBJECT_STATE_INFO(battleInstanceRoom, infos);
BattleRoomNotifyHelper.broadcast_GS2C_NTF_POD_COMBAT_STATE(battleInstanceRoom);
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_REWARD(battleInstanceRoom, player.getUserGuid(), common_result);
return result;
}
private async Task<Result> roundingUpdateWithoutReward(GameModeTPSFreeForAll<GameModeTPSFreeForAllData> battleInstanceRoom, DateTime roundEndTime)
{
var result = new Result();
bool need_battle_end_result_noti = false;
var server_logic = GameServerApp.getServerLogic();
List<BattleObjectInfo> infos = new();
var fn_battle_round_update = async delegate()
{
var attribute = battleInstanceRoom.getEntityAttribute<BattleInstanceSnapshotAttribute>();
NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!! - {battleInstanceRoom.toBasicString()}");
if (battleInstanceRoom.m_round_count <= attribute.m_combat_pod_mode.m_current_round)
{
attribute.m_combat_pod_mode.m_round_state_type = BattleRoundStateType.RoundEndAll;
//배틍 종료에 대한 정보를 알려줄지 말지에 대한 noti
need_battle_end_result_noti = true;
}
else
{
attribute.m_combat_pod_mode.m_round_state_type = BattleRoundStateType.RoundWait;
}
attribute.m_combat_pod_mode.m_current_state_start_time = roundEndTime;
//모든 픽업포드 비활성화, 모든 스토리지 비활성화
infos.AddRange(battleObjectPickupPodsDeactive(attribute));
infos.AddRange(battleObjectPodStoragesDeactive(attribute));
attribute.m_combat_pod_mode.m_pod_combat.setDeactive();
attribute.modifiedEntityAttribute(true);
//batch 처리
// var batch = new QueryBatch<QueryRunnerWithDocument>(battleInstanceRoom, LogActionType.BattleRoundStateUpdate, server_logic.getDynamoDbClient());
// {
// batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
// }
//로그 추가
var room_id = battleInstanceRoom.getRoomId();
var ended_round = attribute.m_combat_pod_mode.m_current_round;
var round_state = attribute.m_combat_pod_mode.m_round_state_type;
var users = battleInstanceRoom.getInstanceRoom().tryGetInstanceExistUserForLog();
BattleRoundUpdateBusinessLog business_log = new(room_id, ended_round, round_state, users);
//batch.appendBusinessLog(business_log); //kihoon todo : 로그랑 배치 수정해서 올려야 된다.
//result = await QueryHelper.sendQueryAndBusinessLog(batch);
await Task.CompletedTask;
if (result.isFail()) return result;
return result;
};
result = await battleInstanceRoom.runTransactionRunnerSafelyWithTransGuid(battleInstanceRoom.getRoomId(),
TransactionIdType.PrivateContents, BattleConstant.BATTLE_INSTANCE_TRANSACTION_NAME, fn_battle_round_update);
if (result.isFail())
{
var err_msg = $"Failed to runTransactionRunnerSafelyWithTransGuid() !!! : {result.toBasicString()}, {battleInstanceRoom.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_INSTANCE_STATE(battleInstanceRoom);
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_OBJECT_STATE_INFO(battleInstanceRoom, infos);
BattleRoomNotifyHelper.broadcast_GS2C_NTF_POD_COMBAT_STATE(battleInstanceRoom);
if (need_battle_end_result_noti)
{
}
return result;
}
private async Task stepUpdate(GameModeTPSFreeForAll<GameModeTPSFreeForAllData> battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, DateTime now)
{
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();
//최대 스텝이면 알려줄것 없다.
if (max_charge_level <= attribute.m_combat_pod_mode.m_charged_step) return;
//시간이 아직 안지났을 경우는 m_charged_step 시간을 체크 해줘야 된다...
var round_start_time = attribute.m_combat_pod_mode.m_current_state_start_time;
var current_charge_level = attribute.m_combat_pod_mode.m_charged_step;
var next_charge_level = current_charge_level + 1;
//다음 충전까지 필요한 시간의 합
var next_charge_time_total = battleInstanceRoom.m_ffa_reward_meta
.Where(kvp => kvp.Key <= next_charge_level)
.Sum(kvp => kvp.Value.ChargeTime);
//여기도 using만 사용 로그만 남길것...
using (var releaser = await battleInstanceRoom.getAsyncLock())
{
var next_step_active_time = round_start_time.AddSeconds(next_charge_time_total);
if (next_step_active_time <= now)
{
attribute.m_combat_pod_mode.m_charged_step = next_charge_level;
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_INSTANCE_STATE(battleInstanceRoom);
}
}
}
private async Task podCombatRewardUpdate(GameModeTPSFreeForAll<GameModeTPSFreeForAllData> battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, DateTime now)
{
var occupier_guid = string.Empty;
CommonResult common_result = new();
bool need_pod_combat_noti = false;
using (var releaser = await battleInstanceRoom.getAsyncLock())
{
occupier_guid = attribute.m_combat_pod_mode.m_pod_combat.m_current_occupier_guid;
if (occupier_guid.Equals(string.Empty)) return;
if (false == battleInstanceRoom.getInstanceRoom().tryGetInstanceMember(occupier_guid, out var player))
{
Log.getLogger().error($"Not Exist Player in battle instance room occupier_guid : {occupier_guid}");
return;
}
var charged_step = attribute.m_combat_pod_mode.m_charged_step;
var rewarded_step = attribute.m_combat_pod_mode.m_rewarded_step;
if (charged_step <= rewarded_step) return;
var accupied_time = attribute.m_combat_pod_mode.m_pod_combat.m_occupied_time;
var rewadable_time = accupied_time.AddSeconds(battleInstanceRoom.m_ffa_config_meta.GetRewardTime);
if (rewadable_time > now) return;
var result = new Result();
var fn_pod_combat_reward_update = async delegate()
{
//여기서 보상처리 가능하다.
var rewards = makePodCombatOccupyReward(rewarded_step, charged_step, battleInstanceRoom);
result = await addPodCommbatOccupyReward(player, battleInstanceRoom, rewards);
if (result.isFail())
{
string err_msg = $"addPodCommbatOccupyReward return fail.. error : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
attribute.m_combat_pod_mode.m_rewarded_step = charged_step;
attribute.m_combat_pod_mode.m_pod_combat.m_occupied_time = rewadable_time;
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();
if (max_charge_level <= charged_step)
{
attribute.m_combat_pod_mode.m_pod_combat.setDeactive();
need_pod_combat_noti = true;
}
attribute.modifiedEntityAttribute(true);
(result, var doc) = await attribute.toDocBase();
if (result.isFail())
{
Log.getLogger().error(result.toBasicString());
}
var server_logic = GameServerApp.getServerLogic();
//batch 처리
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.BattlePodCombatOccupyReward, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
if (doc is not null)
{
batch.addQuery(new DBQEntityWrite(doc));
}
}
BattleObjectLogInfo info = new();
info.m_battle_object_type = EBattleObjectType.Pod_Combat;
List<BattleObjectLogInfo> log_infos = new();
var room_id = battleInstanceRoom.getRoomId();
var current_round = attribute.m_combat_pod_mode.m_current_round;
var round_state_type = attribute.m_combat_pod_mode.m_round_state_type;
var business_log = new BattlePodCombatRewardBusinessLog(room_id, current_round, round_state_type
, player.getUserGuid(), player.getUserNickname(), charged_step, rewarded_step, rewards);
batch.appendBusinessLog(business_log);
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail()) return result;
//보상 내용 가져올것
var found_transaction_runner = player.findTransactionRunner(TransactionIdType.PrivateContents);
NullReferenceCheckHelper.throwIfNull(found_transaction_runner, () => $"found_transaction_runner is null !!! - {player.toBasicString()}");
common_result = found_transaction_runner.getCommonResult();
return result;
};
result = await player.runTransactionRunnerSafelyWithTransGuid(player.getUserGuid(),
TransactionIdType.PrivateContents, BattleConstant.BATTLE_INSTANCE_TRANSACTION_NAME, fn_pod_combat_reward_update);
if (result.isFail())
{
var err_msg = $"Failed to runTransactionRunnerSafelyWithTransGuid() !!! : {result.toBasicString()}, {battleInstanceRoom.toBasicString()}";
Log.getLogger().error(err_msg);
return;
}
}
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_INSTANCE_STATE(battleInstanceRoom);
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_REWARD(battleInstanceRoom, occupier_guid, common_result);
if (need_pod_combat_noti)
{
BattleRoomNotifyHelper.broadcast_GS2C_NTF_POD_COMBAT_STATE(battleInstanceRoom);
}
}
private async Task<Result> battleInstanceEndStateUpdate(GameModeTPSFreeForAll<GameModeTPSFreeForAllData> battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
var result = new Result();
await Task.CompletedTask;
var all_round_end_time = attribute.m_combat_pod_mode.m_current_state_start_time;
var end_time = all_round_end_time.AddSeconds(battleInstanceRoom.m_ffa_config_meta.ResultUIWaitTime);
var now = DateTimeHelper.Current;
if (now < end_time) return result;
using (var releaser = await battleInstanceRoom.getAsyncLock())
{
attribute.m_combat_pod_mode.m_round_state_type = BattleRoundStateType.Destroyed;
attribute.m_combat_pod_mode.m_current_state_start_time = end_time;
}
var users = battleInstanceRoom.getInstanceRoom().tryGetInstanceExistUserForLog();
//여기서 배틀 인스턴스가 완전히 shutdown 됐다는 Noti 전달
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_INSTANCE_STATE(battleInstanceRoom);
//log 추가
var invokers = new List<ILogInvoker>();
var log_action = new LogAction(LogActionType.BattleRoundStateUpdate.ToString());
var room_id = battleInstanceRoom.getRoomId();
var ended_round = attribute.m_combat_pod_mode.m_current_round;
var round_state = attribute.m_combat_pod_mode.m_round_state_type;
BattleRoundUpdateBusinessLog business_log = new(room_id, ended_round, round_state, users);
invokers.Add(business_log);
//BusinessLogger.collectLogs(log_action, battleInstanceRoom, invokers);// kihoon todo : 이거 수정해야된다.
return result;
}
}