초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,417 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class BattleInstanceAction : EntityActionBase
{
public BattleInstanceAction(EntityBase owner) : base(owner)
{
}
public override Task<Result> onInit()
{
var result = new Result();
return Task.FromResult(result);
}
public override void onClear() { }
public async Task<Result> loadOrCreateSnapshot()
{
var result = new Result();
var battle_instance_room = getOwner() as BattleInstanceRoom;
NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room_owner is null !!!");
var server_logic = GameServerApp.getServerLogic();
var dynamodb_client = server_logic.getDynamoDbClient();
string room_id = battle_instance_room.m_instance_room.getMap().m_room_id;
var config = dynamodb_client.makeQueryConfigForReadByPKSK(BattleInstanceSnapshotDoc.pk, room_id);
(result, var read_docs) = await dynamodb_client.simpleQueryDocTypesWithQueryOperationConfig<BattleInstanceSnapshotDoc>(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 = battle_instance_room.getEntityAction<BattleInstanceAction>();
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 : {battle_instance_room.toBasicString()}");
var attribute = battle_instance_room.getEntityAttribute<BattleInstanceSnapshotAttribute>();
NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!!");
var invokers = new List<ILogInvoker>();
var log_action = new LogActionEx(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<Result> createBattleInstanceSnapshot(string roomId)
{
var result = new Result();
await Task.CompletedTask;
BattleInstanceSnapshotDoc doc = new(roomId);
var battle_instance_room = getOwner() as BattleInstanceRoom;
NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!");
var server_logic = GameServerApp.getServerLogic();
var fn_create_battle_instance_snapshot = async delegate()
{
var battle_instance_snaptshot_attribute = battle_instance_room.getEntityAttribute<BattleInstanceSnapshotAttribute>();
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 = battle_instance_room.m_battle_instance_event_start_time;
addRespawnPosInfoFromMeta(battle_instance_room, battle_instance_snaptshot_attribute);
addStorageInfoFromMeta(battle_instance_room, battle_instance_snaptshot_attribute);
addPickupPodInfoFromMeta(battle_instance_room, battle_instance_snaptshot_attribute);
var anchors = battle_instance_room.m_instance_room.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(battle_instance_room, battle_instance_snaptshot_attribute);
if (result.isFail()) return result;
result = await createBattleObjectPickupPodReward(battle_instance_room, battle_instance_snaptshot_attribute);
if (result.isFail()) return result;
battle_instance_snaptshot_attribute.modifiedEntityAttribute(true);
var batch = new QueryBatchEx<QueryRunnerWithDocument>(battle_instance_room, LogActionType.BattleInstanceSnapshotCreate, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
}
result = await QueryHelper.sendQueryAndBusinessLog(batch);
return result;
};
result = await battle_instance_room.runTransactionRunnerSafelyWithTransGuid(battle_instance_room.m_instance_room.getMap().m_room_id,
TransactionIdType.PrivateContents, BattleConstant.BATTLE_INSTANCE_TRANSACTION_NAME, fn_create_battle_instance_snapshot);
if (result.isFail())
{
var err_msg = $"Failed to runTransactionRunnerSafelyWithTransGuid() !!! : {result.toBasicString()} - CreateBattleInstanceSnapshot, {battle_instance_room.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<BattleInstanceSnapshotAttrib>();
NullReferenceCheckHelper.throwIfNull(battle_instance_snapshot_attrib, () => $"battle_instance_snapshot_attrib is null !!!");
var battle_instance_room = getOwner() as BattleInstanceRoom;
NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!");
var attribute = battle_instance_room.getEntityAttribute<BattleInstanceSnapshotAttribute>();
NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!!");
attribute.copyEntityAttributeFromDoc(doc);
attribute.syncOriginDocBaseWithNewDoc<BattleInstanceSnapshotAttribute>(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(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
addRespawnPosInfoFromMeta(battleInstanceRoom, attribute);
addStorageInfoFromMeta(battleInstanceRoom, attribute);
addPickupPodInfoFromMeta(battleInstanceRoom, attribute);
var anchors = battleInstanceRoom.m_instance_room.getMap().getAnchors();
foreach (var anchor in anchors)
{
addBattleObjectWeapon(attribute, anchor.Value);
addBattleObjectBuff(attribute, anchor.Value);
}
}
private void deleteChangedBattleObjectPodStorageAnchor(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib)
{
List<string> delete_keys = new();
foreach (var stand in attrib.m_combat_pod_attrib.m_pod_storages)
{
//기존에 들고 있던 guid 가 map에서 없어지거나 바뀌었을 경우가 있을수 있으므로 예외 처리
if (false == battleInstanceRoom.m_instance_room.getMap().getAnchors().ContainsKey(stand.Key))
{
Log.getLogger().warn($"stand : {stand.Key} is not exist.. so don't add attribute.... roomId : {battleInstanceRoom.m_instance_room.getMap().m_room_id}");
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(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib)
{
List<string> delete_keys = new();
foreach (var box in attrib.m_combat_pod_attrib.m_pickup_pods)
{
//기존에 들고 있던 guid 가 map에서 없어지거나 바뀌었을 경우가 있을수 있으므로 예외 처리
if (false == battleInstanceRoom.m_instance_room.getMap().getAnchors().ContainsKey(box.Key))
{
Log.getLogger().info($"box : {box.Key} is not exist.. so don't add attribute.... roomId : {battleInstanceRoom.m_instance_room.getMap().m_room_id}");
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(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib)
{
List<string> 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.m_instance_room.getMap().m_room_id}");
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(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib)
{
List<string> delete_keys = new();
foreach (var weapon in attrib.m_combat_pod_attrib.m_weapons)
{
//기존에 들고 있던 guid 가 map에서 없어지거나 바뀌었을 경우가 있을수 있으므로 예외 처리
if (false == battleInstanceRoom.m_instance_room.getMap().getAnchors().ContainsKey(weapon.Key))
{
Log.getLogger().warn($"weapon : {weapon.Key} is not exist.. so don't add attribute.... roomId : {battleInstanceRoom.m_instance_room.getMap().m_room_id}");
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(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute, BattleInstanceSnapshotAttrib attrib)
{
List<string> delete_keys = new();
foreach (var buff in attrib.m_combat_pod_attrib.m_buffs)
{
//map에 respawn pos가 없어지거나 바뀌었을 경우가 있을수 있으므로 예외 처리
if (false == battleInstanceRoom.m_instance_room.getMap().getAnchors().ContainsKey(buff.Key))
{
Log.getLogger().warn($"buff : {buff.Key} is not exist.. so don't add attribute.... roomId : {battleInstanceRoom.m_instance_room.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(BattleInstanceRoom 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(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
foreach (var storage_group in battleInstanceRoom.m_battle_pod_storage_guid_group.Values)
{
foreach (var anchor_guid in storage_group)
{
addBattleObjectPodStorage(attribute, anchor_guid);
}
}
}
private void addPickupPodInfoFromMeta(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
foreach (var pickup_pod_group in battleInstanceRoom.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<Result> createBattleObjectPickupPodReward(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
var result = new Result();
var battle_update_action = battleInstanceRoom.getEntityAction<BattleInstanceUpdateAction>();
NullReferenceCheckHelper.throwIfNull(battle_update_action, () => $"battle_update_action is null !!!");
await battle_update_action.createPickupPodReward(battleInstanceRoom, attribute);
return result;
}
private async Task<Result> createBattleObjectCombatPod(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
var battle_update_action = battleInstanceRoom.getEntityAction<BattleInstanceUpdateAction>();
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);
// }
// }
}

View File

@@ -0,0 +1,516 @@
using Newtonsoft.Json;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public partial class BattleInstanceUpdateAction
{
private async Task<Result> battleInstanceStateUpdate(BattleInstanceRoom 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.m_instance_room.getMap().m_room_id}");
return result;
}
return result;
}
private async Task<Result> battleInstanceWaitStateUpdate(BattleInstanceRoom 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 LogActionEx(LogActionType.BattleRoundStateUpdate);
var room_id = battleInstanceRoom.m_instance_room.getMap().m_room_id;
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.m_instance_room.tryGetInstanceExistUserForLog();
BattleRoundUpdateBusinessLog business_log = new(room_id, ended_round, round_state, users);
invokers.Add(business_log);
BusinessLogger.collectLogs(log_action, battleInstanceRoom, invokers);
return result;
}
private async Task<Result> battleInstanceRoundingStateUpdate(BattleInstanceRoom 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(BattleInstanceRoom 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.m_instance_room.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(BattleInstanceRoom 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.m_instance_room.getMap().m_room_id;
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.m_instance_room.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(BattleInstanceRoom 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 QueryBatchEx<QueryRunnerWithDocument>(battleInstanceRoom, LogActionType.BattleRoundStateUpdate, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
}
//로그 추가
var room_id = battleInstanceRoom.m_instance_room.getMap().m_room_id;
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.m_instance_room.tryGetInstanceExistUserForLog();
BattleRoundUpdateBusinessLog business_log = new(room_id, ended_round, round_state, users);
batch.appendBusinessLog(business_log);
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail()) return result;
return result;
};
result = await battleInstanceRoom.runTransactionRunnerSafelyWithTransGuid(battleInstanceRoom.m_instance_room.getMap().m_room_id,
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(BattleInstanceRoom 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(BattleInstanceRoom 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.m_instance_room.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.m_instance_room.getMap().m_room_id;
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(BattleInstanceRoom 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.m_instance_room.tryGetInstanceExistUserForLog();
//여기서 배틀 인스턴스가 완전히 shutdown 됐다는 Noti 전달
BattleRoomNotifyHelper.broadcast_GS2C_NTF_BATTLE_INSTANCE_STATE(battleInstanceRoom);
//log 추가
var invokers = new List<ILogInvoker>();
var log_action = new LogActionEx(LogActionType.BattleRoundStateUpdate);
var room_id = battleInstanceRoom.m_instance_room.getMap().m_room_id;
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);
return result;
}
}

View File

@@ -0,0 +1,492 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using Nettention.Proud;
using Newtonsoft.Json;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public partial class BattleInstanceUpdateAction : EntityActionBase
{
public BattleInstanceUpdateAction(EntityBase owner) : base(owner)
{
}
public override async Task<Result> onInit()
{
await Task.CompletedTask;
var result = new Result();
return result;
}
public override void onClear()
{
}
public async Task<Result> update()
{
var battle_instance_room = getOwner() as BattleInstanceRoom;
NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!");
var attribute = battle_instance_room.getEntityAttribute<BattleInstanceSnapshotAttribute>();
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<Result> battleInstancHostUpdate(BattleInstanceRoom battleInstanceRoom)
{
var result = new Result();
string host_user_guid = string.Empty;
var is_migrated = false;
using (var releaser = await battleInstanceRoom.getAsyncLock())
{
//이미 host 지정이 끝났으면 리턴
//kihoon todo : 일단 계속 체크해서 호스트가 얼마나 바뀌는지 확인 해보고 적절한 주기 찾아볼것
//if (!battleInstanceRoom.m_host_migrator.getHostUserGuid().Equals(string.Empty)) return result;
var host_migrator = battleInstanceRoom.m_host_migrator;
// TODO : 인터페이스 변경 예정
(result, is_migrated) = host_migrator.migrateCheck();
if (result.isFail()) return result;
if (is_migrated)
{
host_user_guid = host_migrator.getHostUserGuid();
}
}
if (is_migrated)
{
Log.getLogger().info($"battleInstancHost set complete host_user_guid : {host_user_guid}");
BattleRoomNotifyHelper.broadcast_GS2C_NTF_P2P_HOST_UPDATE(battleInstanceRoom.m_instance_room, host_user_guid);
}
return result;
}
private async Task<Result> battleObjectStateUpdate(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
var result = new Result();
await Task.CompletedTask;
var now = DateTimeHelper.Current;
List<BattleObjectInfo> infos = new();
List<BattleObjectLogInfo> 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<ILogInvoker>();
var log_action = new LogActionEx(LogActionType.BattleObjectStateUpdate);
var business_log = new BattleObjectStateUpdateBusinessLog(battleInstanceRoom.m_instance_room.getMap().m_room_id, log_infos);
invokers.Add(business_log);
BusinessLogger.collectLogs(log_action, battleInstanceRoom, invokers);
}
return result;
}
private (List<BattleObjectInfo>, List<BattleObjectLogInfo>) 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<BattleObjectInfo> infos = new();
List<BattleObjectLogInfo> log_infos = new();
var battle_instance_room = getOwner() as BattleInstanceRoom;
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.m_instance_room.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.m_instance_room.getMap().m_room_id}";
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<BattleObjectInfo>, List<BattleObjectLogInfo>) battleObjectBuffStateUpdate(BattleInstanceSnapshotAttribute attribute, DateTime now)
{
List<BattleObjectInfo> infos = new();
List<BattleObjectLogInfo> 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<BattleObjectInfo>, List<BattleObjectLogInfo>) battleObjectWeaponStateUpdate(BattleInstanceSnapshotAttribute attribute, DateTime now)
{
List<BattleObjectInfo> infos = new();
List<BattleObjectLogInfo> 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(BattleInstanceRoom battleInstanceRoom, BattleInstanceSnapshotAttribute attribute)
{
var infos = new List<BattleObjectInfo>();
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<Result> createCombatPod(BattleInstanceRoom 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<Result> createPickupPodReward(BattleInstanceRoom 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.m_instance_room.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<Result> createPickupPodRewardByGroup(BattleInstanceRoom 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<MetaAssets.Reward>, int, int)> podCombatUpdateIfHasOccupier(BattleInstanceRoom 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<Result> addPodCommbatOccupyReward(Player player, BattleInstanceRoom battleInstanceRoom, List<MetaAssets.Reward> 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<MetaAssets.Reward> makePodCombatOccupyReward(int start, int end, BattleInstanceRoom battleInstanceRoom)
{
List<MetaAssets.Reward> 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<BattleObjectInfo> battleObjectPickupPodsDeactive(BattleInstanceSnapshotAttribute attribute)
{
List<BattleObjectInfo> 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<BattleObjectInfo> battleObjectPodStoragesDeactive(BattleInstanceSnapshotAttribute attribute)
{
List<BattleObjectInfo> 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;
}
}

View File

@@ -0,0 +1,90 @@
using Newtonsoft.Json;
using ServerCommon;
using ServerCore; using ServerBase;
namespace GameServer;
internal partial class LocationAction
{
public async Task<Result> tryMoveToBattleIndun(InstanceRoomInfo instanceRoomInfo, Pos? enterPos = null, bool isReturn = false)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var location_attribute = player.getEntityAttribute<LocationAttribute>();
NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"location_attribute is null !!! - {player.toBasicString()}");
NullReferenceCheckHelper.throwIfNull(m_current_loaction, () => $"m_current_loaction is null !!! - {player.toBasicString()}");
NullReferenceCheckHelper.throwIfNull(m_location_cache_request_nullable, () => "Current Location Cache is null !!");
if (!MetaData.Instance._IndunTable.TryGetValue(instanceRoomInfo.InstanceId, out var indun_data))
{
err_msg = $"Failed to MetaData.TryGetValue() !!! : instanceMetaId:{instanceRoomInfo.InstanceId} - {player.toBasicString()}";
result.setFail(ServerErrorCode.InstanceMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (server_logic.getServerType().toServerType() == ServerType.Channel)
{
location_attribute.LastestChannelServerLocation.ServerName = server_logic.getServerName();
location_attribute.LastestChannelServerLocation.WorldMetaId = (int)server_logic.getWorldId();
location_attribute.LastestChannelServerLocation.SpawnPos = m_current_loaction.SpawnPos;
location_attribute.LastestChannelServerLocation.ForwardAngle = m_current_loaction.ForwardAngle;
server_logic.getReturnManager().addReturnUser(player.getUserGuid());
}
else if (isReturn == false)
{
IndunLocation indun_location = new();
indun_location.InstanceRoomId = location_attribute.CurrentIndunLocation.InstanceRoomId;
indun_location.InstanceMetaId = location_attribute.CurrentIndunLocation.InstanceMetaId;
indun_location.SpawnPos = m_current_loaction.SpawnPos;
indun_location.ForwardAngle = m_current_loaction.ForwardAngle;
location_attribute.ReturnIndunLocations.Add(indun_location);
server_logic.getReturnManager().addReturnUser(player.getUserGuid());
}
if (enterPos != null)
{
enterPos.Z += 100;
}
location_attribute.EnterIndunLocation.InstanceRoomId = instanceRoomInfo.roomId;
location_attribute.EnterIndunLocation.InstanceMetaId = instanceRoomInfo.InstanceId;
location_attribute.EnterIndunLocation.fromPos(enterPos == null ? MapManager.Instance.GetStartPos(indun_data.RoomFile) : enterPos);
location_attribute.modifiedEntityAttribute();
var location_cache = m_location_cache_request_nullable.getLocationCache();
NullReferenceCheckHelper.throwIfNull(location_cache, () => $"location_cache is null !!! - {player.toBasicString()}");
location_cache.copyCacheFromEntityAttribute(location_attribute);
result = await m_location_cache_request_nullable.upsertLocation();
if (result.isFail())
{
err_msg = $"Failed to upsertLocation() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
return result;
}
public LocationCacheRequest? getBattleLocationCacheRequestNullable()
{
return m_location_cache_request_nullable;
}
}

View File

@@ -0,0 +1,171 @@
using MetaAssets;
using ServerCommon;
using ServerCore; using ServerBase;
namespace GameServer;
public class BattleObjectInteractAction : EntityActionBase
{
public BattleObjectInteractAction(EntityBase owner) : base(owner)
{
}
public override async Task<Result> onInit()
{
await Task.CompletedTask;
var result = new Result();
return result;
}
public override void onClear()
{
}
public async Task<Result> interactCommonBattleObject(BattleObjectInteractionLogicHandler handler, Player player)
{
await Task.CompletedTask;
var result = new Result();
updateBattleObjectActiveInfo(handler);
return result;
}
public async Task<Result> interactPickupPod(BattleObjectInteractionLogicHandler handler, Player player)
{
await Task.CompletedTask;
var result = new Result();
updateBattleObjectActiveInfo(handler);
Log.getLogger().info($"interaction pickup pod player : {player.toBasicString()}, guid : {handler.m_interaction_anchor_guid}, next active time : {handler.m_battle_object.m_active_time}");
var battle_instance_room = getOwner() as BattleInstanceRoom;
NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!");
var attribute = battle_instance_room.getEntityAttribute<BattleInstanceSnapshotAttribute>();
NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!!");
//보상처리
var reward_action = battle_instance_room.getEntityAction<BattleObjectRewardAction>();
NullReferenceCheckHelper.throwIfNull(reward_action, () => $"handler.m_pod_combat is null !!!");
result = await reward_action.pickupPodReward(player, attribute, handler);
return result;
}
public async Task<Result> interactPodStorage(BattleObjectInteractionLogicHandler handler, Player player)
{
await Task.CompletedTask;
var result = new Result();
var battle_instance_room = getOwner() as BattleInstanceRoom;
NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!");
var attribute = battle_instance_room.getEntityAttribute<BattleInstanceSnapshotAttribute>();
NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!!");
bool has_pod_combat = hasPodCombat(handler.m_interaction_anchor_guid, attribute, handler);
handler.m_interaction_log_info.m_has_pod_combat = has_pod_combat;
handler.m_interaction_log_info.m_pod_type = ECombatPodType.Storage;
var now = DateTimeHelper.Current;
if (has_pod_combat)
{
NullReferenceCheckHelper.throwIfNull(handler.m_pod_combat, () => $"handler.m_pod_combat is null !!!");
var pod_combat = handler.m_pod_combat;
handler.m_is_need_combat_pod_noti = true;
pod_combat.m_state = PodCombatStateType.Possesion;
pod_combat.m_currenct_Pos = player.getCurrentPositionInfo().Pos;
pod_combat.m_state_change_time = now;
pod_combat.m_active_time = now;
pod_combat.m_current_occupier_guid = player.getUserGuid();
pod_combat.m_occupied_time = now;
foreach (var stand in attribute.m_combat_pod_mode.m_pod_storages.Values)
{
stand.m_is_active = false;
handler.m_need_noti_objects.Add(stand);
}
handler.m_interaction_log_info.m_pod_combat_pos = pod_combat.m_currenct_Pos;
handler.m_interaction_log_info.m_pod_combat_state = pod_combat.m_state;
}
else
{
//보상 줘야되면 보상 처리
var reward_action = battle_instance_room.getEntityAction<BattleObjectRewardAction>();
NullReferenceCheckHelper.throwIfNull(reward_action, () => $"handler.m_pod_combat is null !!!");
result = await reward_action.podStorageReward(player, attribute, handler);
}
return result;
}
public void updateBattleObjectActiveInfo(BattleObjectInteractionLogicHandler handler)
{
var now = DateTimeHelper.Current;
var next_active_time = now.AddSeconds(handler.m_battle_object_meta.RespawnTime);
handler.m_object_active_time = handler.m_interaction_log_info.m_object_next_active_time = handler.m_battle_object.m_active_time = next_active_time;
handler.m_battle_object.m_is_active = handler.m_interaction_log_info.m_is_active = false;
}
public async Task<Result> interactPodCombat(BattleObjectInteractionLogicHandler handler, Player player)
{
await Task.CompletedTask;
var result = new Result();
var battle_instance_room = getOwner() as BattleInstanceRoom;
NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!");
string err_msg = string.Empty;
var attribute = battle_instance_room.getEntityAttribute<BattleInstanceSnapshotAttribute>();
NullReferenceCheckHelper.throwIfNull(attribute, () => $"battle_instance_attribute is null !!!");
var combat_pod = handler.m_pod_combat = attribute.m_combat_pod_mode.m_pod_combat;
if (false == combat_pod.m_current_occupier_guid.Equals(string.Empty) && false == combat_pod.m_state.Equals(PodCombatStateType.Dropped))
{
//다른 유저가 소유중일때는 상호 작용 할수 없다.
err_msg = $"Pod Combat Already accupied Player : {player.toBasicString()}, possessioned user : {combat_pod.m_current_occupier_guid}";
result.setFail(ServerErrorCode.BattleInstancePodCombatAlreadyOccupy, err_msg);
Log.getLogger().error(err_msg);
return result;
}
handler.m_is_need_combat_pod_noti = true;
var now = DateTimeHelper.Current;
combat_pod.m_state = PodCombatStateType.Possesion;
combat_pod.m_currenct_Pos = player.getCurrentPositionInfo().Pos;
combat_pod.m_state_change_time = now;
combat_pod.m_current_occupier_guid = player.getUserGuid();
combat_pod.m_occupied_time = now;
handler.m_interaction_log_info.m_battle_object_type = EBattleObjectType.Pod_Combat;
handler.m_interaction_log_info.m_pod_type = ECombatPodType.Pod;
handler.m_interaction_log_info.m_pod_combat_pos = combat_pod.m_currenct_Pos;
handler.m_interaction_log_info.m_pod_combat_state = combat_pod.m_state;
return result;
}
private bool hasPodCombat(string anchorGuid, BattleInstanceSnapshotAttribute attribute, BattleObjectInteractionLogicHandler handler)
{
var pod_combat = attribute.m_combat_pod_mode.m_pod_combat;
if (pod_combat.m_source_storage_anchor_guid.Equals(anchorGuid) && pod_combat.m_state.Equals(PodCombatStateType.Active))
{
handler.m_pod_combat = pod_combat;
return true;
}
return false;
}
}

View File

@@ -0,0 +1,147 @@
using GameServer.Contents.Battle.Reward;
using MetaAssets;
using Newtonsoft.Json;
using ServerCommon;
using ServerCore; using ServerBase;
namespace GameServer;
public class BattleObjectRewardAction : EntityActionBase
{
public BattleObjectRewardAction(EntityBase owner) : base(owner)
{
}
public override Task<Result> onInit()
{
var result = new Result();
return Task.FromResult(result);
}
public override void onClear() { }
public async Task<Result> podStorageReward(Player player, BattleInstanceSnapshotAttribute attribute, BattleObjectInteractionLogicHandler handler)
{
var result = new Result();
if (false == attribute.m_combat_pod_mode.m_pod_storages.TryGetValue(handler.m_interaction_anchor_guid, out var podStorage))
{
Log.getLogger().error($"Not exist pod storage anchor : {handler.m_interaction_anchor_guid}, player : {player.toBasicString()}");
result.setFail(ServerErrorCode.BattleInstanceObjectMetaNotExist, result.toBasicString());
return result;
}
if (1 <= podStorage.m_reward_cnt)
{
return result; //이건 에러는 아니다.
}
podStorage.m_reward_cnt++;
var pod_storage_meta = MetaData.Instance._BattlePodStorageMeta;
var reward_id = pod_storage_meta.TypeID;
var reward_count = pod_storage_meta.ObjectValue;
var battle_instance_room = getOwner() as BattleInstanceRoom;
NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!");
RewardMutable reward_metable = new();
reward_metable.Item = new();
reward_metable.Item.Id = reward_id;
reward_metable.Item.Count = reward_count * battle_instance_room.m_hot_time_reward;
MetaAssets.Reward reward = new MetaAssets.Reward(reward_metable);
List<MetaAssets.Reward> rewards = new(){reward};
IReward reward_proc = new RewardPodStorage(player, player.getUserGuid(), rewards);
result = await RewardManager.It.proceedRewardProcess(reward_proc);
if (result.isFail())
{
return result;
}
handler.m_interaction_log_info.m_rewards.AddRange(rewards);
return result;
}
public async Task<Result> pickupPodReward(Player player, BattleInstanceSnapshotAttribute attribute, BattleObjectInteractionLogicHandler handler)
{
var result = new Result();
string err_msg = string.Empty;
if (false == attribute.m_combat_pod_mode.m_pickup_pods.TryGetValue(handler.m_interaction_anchor_guid, out var pickupPod))
{
err_msg = $"Not exist pickup pod anchor : {handler.m_interaction_anchor_guid}, player : {player.toBasicString()}";
Log.getLogger().error(err_msg);
result.setFail(ServerErrorCode.BattleInstanceObjectMetaNotExist, err_msg);
return result;
}
var battle_instance_room = getOwner() as BattleInstanceRoom;
NullReferenceCheckHelper.throwIfNull(battle_instance_room, () => $"battle_instance_room is null !!!");
Int32 idx = Int32.MinValue;
Int32 group_id = 0;
string rewarded_anchor_guid = String.Empty;
foreach (var generated_info in attribute.m_combat_pod_mode.m_pickup_pod_generated_info)
{
var generated_info_tuple = generated_info.Value;
if (false == handler.m_interaction_anchor_guid.Equals(generated_info_tuple.m_anchor_guid))
{
Log.getLogger().info($"m_pickup_pod_generated_info data interaction anchor_guid : {handler.m_interaction_anchor_guid}, reward setted anchor_guid : {generated_info_tuple.m_anchor_guid} ");
continue;
}
(group_id, idx) = generated_info.Key;
rewarded_anchor_guid = generated_info_tuple.m_anchor_guid;
Log.getLogger().info($"rewarded_anchor_guid rewarded_anchor_guid : {rewarded_anchor_guid}, groupId : {group_id}, idx : {idx}");
break;
}
if (idx == Int32.MinValue) return result; //보상줄게 없다는 얘기이므로 그량 리턴
if(false == battle_instance_room.m_instance_room.getMap().getAnchors().TryGetValue(handler.m_interaction_anchor_guid, out var anchorInfo))
{
err_msg = $"not exist anchor anchor_guid : {handler.m_interaction_anchor_guid}";
Log.getLogger().error(err_msg);
result.setFail(ServerErrorCode.BattleInstanceNotExistAnchors, err_msg);
return result;
}
var table_id = anchorInfo.AnchorProp.TableId;
if (false == MetaData.Instance._BattleObjectSpawnGroupMetaTable.TryGetValue(table_id, out var battle_object_spawn_group))
{
err_msg = $"not exist _BattleObjectSpawnGroupMetaTable anchor_guid : {handler.m_interaction_anchor_guid}, tableid : {table_id}";
Log.getLogger().error(err_msg);
result.setFail(ServerErrorCode.BattleInstanceObjectMetaNotExist, err_msg);
return result;
}
var now = DateTimeHelper.Current;
var next_gen_time = now.AddSeconds(battle_object_spawn_group.RespawnTime);
PickupPodGeneratedInfo assigned_generated_info = new(group_id, idx, string.Empty, rewarded_anchor_guid, next_gen_time);
attribute.m_combat_pod_mode.m_pickup_pod_generated_info.AddOrUpdate((group_id, idx), assigned_generated_info, (key, existingValue) => assigned_generated_info);
var pickup_pod_meta = MetaData.Instance._BattlePickupPodMeta;
RewardMutable reward_metable = new();
reward_metable.Item = new();
reward_metable.Item.Id = pickup_pod_meta.TypeID;
reward_metable.Item.Count = pickup_pod_meta.ObjectValue * battle_instance_room.m_hot_time_reward;
MetaAssets.Reward reward = new MetaAssets.Reward(reward_metable);
List<MetaAssets.Reward> rewards = new(){reward};
Log.getLogger().info($"pickup pods reward : {JsonConvert.SerializeObject(rewards)}");
IReward reward_proc = new RewardPickupPod(player, player.getUserGuid(), rewards);
result = await RewardManager.It.proceedRewardProcess(reward_proc);
if (result.isFail())
{
return result;
}
handler.m_interaction_log_info.m_rewards.AddRange(rewards);
return result;
}
}

View File

@@ -0,0 +1,188 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
using USER_GUID = System.String;
namespace GameServer;
public partial class GameZoneMoveAction
{
public async Task<(Result, ServerConnectInfo?, List<ILogInvoker>)> tryJoinBattleInstance(USER_GUID userGuid, Int32 eventId, Timestamp eventStartTS, InstanceMetaData instanceMetaData)
{
var result = new Result();
var err_msg = string.Empty;
var server_connect_info = new ServerConnectInfo();
var business_logs = new List<ILogInvoker>();
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
var server_logic = GameServerApp.getServerLogic();
//아이템 혹은 재화 사용해서 입장하는건지, 퍼블릭인지 그에 맞게 조건을 체크하는 함수. 아직 기획적인 내용은 없어서 주석처리..
// result = player.checkInstanceAccess(instanceMetaId);
// if (result.isFail())
// {
// err_msg = $"Failed to checkInstanceAccess() !!! : {result.toBasicString()}";
// Log.getLogger().error(err_msg);
//
// return (result, null, business_logs);
// }
//현재 포지션은 departure pos 가 된다. 관련한 로그 처리
var departure_position_info = player.getCurrentPositionInfo();
var departure_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Departure, departure_position_info);
var departure_position_business_log = new PositionBusinessLog(departure_position_log_info);
business_logs.Add(departure_position_business_log);
BattleInstanceRoomHandler battle_instance_room_handler = new(player.getUserGuid(), instanceMetaData);
//적절한 인스턴스 가져오고, 없으면 생성해서 Join처리
(result, var instance_room_id) = await battle_instance_room_handler.joinBattleInstance(player.getUserGuid(), eventId, eventStartTS, instanceMetaData.Id);
if (result.isFail())
{
err_msg = $"Failed to joinInstance() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
return (result, null, business_logs);
}
var instance_room_storage = new InstanceRoomStorage();
instance_room_storage.Init(server_logic.getRedisDb(), "");
var instance_room_info = await instance_room_storage.GetInstanceRoomInfo(instance_room_id);
if (instance_room_info == null)
{
err_msg = $"Failed to GetInstanceRoomInfo() !!! : instanceRoomId:{instance_room_id} - {player.toBasicString()}";
result.setFail(ServerErrorCode.NotExistRoomInfoForEnter, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null, business_logs);
}
var server_name = ServerType.Indun.toServerName(instance_room_info.InstanceAddress, (ushort)instance_room_info.InstancePort);
// 이동 예약 걸기
var message = new ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER();
message.MoveType = ServerMoveType.Force;
message.RequestUserGuid = userGuid;
message.RequestServerName = server_logic.getServerName();
var reserved = await server_logic.getReservationManager().registerReservationEnterToServer(message, server_name);
// 예약 실패 체크
if (null == reserved)
{
err_msg = $"Failed to Reservation Enter to server !!! : {server_name} - {player.toBasicString()}";
result.setFail(ServerErrorCode.FailedToReservationEnter, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null, business_logs);
}
var location_action = player.getEntityAction<LocationAction>();
NullReferenceCheckHelper.throwIfNull(location_action, () => $"location_action is null !!! - {player.toBasicString()}");
result = await location_action.tryMoveToBattleIndun(instance_room_info);
if (result.isFail())
{
err_msg = $"Failed to tryMoveToIndun() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return (result, null, business_logs);
}
var buff_action = player.getEntityAction<BuffAction>();
NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff_action is null !!! - {player.toBasicString()}");
result = await buff_action.MoveServer(instanceMetaData.placeType());
if (result.isFail())
{
err_msg = $"Failed to MoveServer() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return (result, null, business_logs);
}
(result, var reserved_to_switch_server) = await ServerConnectionSwitchHelper.startServerSwitch(player, server_logic.getRedisConnector(), server_name);
if (result.isFail() || null == reserved_to_switch_server)
{
err_msg = $"Failed to startServerSwitch() !!! : {result.toBasicString()}";
Log.getLogger().error(err_msg);
return (result, null, business_logs);
}
var game_login_action = player.getEntityAction<GameLoginAction>();
NullReferenceCheckHelper.throwIfNull(game_login_action, () => $"game_login_action is null !!! - {player.toBasicString()}");
var login_cache = game_login_action.getLoginCacheRequest()?.getLoginCache();
NullReferenceCheckHelper.throwIfNull(login_cache, () => $"login_cache is null !! player: {player.toBasicString()}");
login_cache.ReservedToSwitchServer = reserved_to_switch_server;
server_connect_info.ServerAddr = instance_room_info.InstanceAddress;
server_connect_info.ServerPort = instance_room_info.InstancePort;
server_connect_info.Otp = reserved_to_switch_server.OneTimeKey;
server_connect_info.RoomId = instance_room_info.roomId;
//배틀 인스턴스 같은 경우는 실제 인스턴스 진입시에 Pos를 정해야 하기 때문에 여기서는 빈값으로 처리
//var start_pos = MapManager.Instance.GetBattleInstnaceStartPos(indun_meta_data.RoomFile, instance_room_id);
var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, server_name, instance_room_info.roomId, MapFileType.Instance, instance_room_info.InstanceId, new());
var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info);
business_logs.Add(arrival_position_business_log);
Log.getLogger().debug($"tryJoinBattleInstance server connect info : {JsonConvert.SerializeObject(server_connect_info)}");
return (result, server_connect_info, business_logs);
}
public async Task<(Result, ClientToGameRes.Types.GS2C_ACK_LEAVE_BATTLE_INSTANCE)> tryLeaveBattleInstanceRoom()
{
var result = new Result();
var err_msg = string.Empty;
var res = new ClientToGameRes.Types.GS2C_ACK_LEAVE_BATTLE_INSTANCE();
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
var user_attribute = player.getEntityAttribute<UserAttribute>();
NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!! - {player.toBasicString()}");
var farming_action = player.getEntityAction<FarmingAction>();
NullReferenceCheckHelper.throwIfNull(user_attribute, () => $"user_attribute is null !!! - {player.toBasicString()}");
var location_action = player.getEntityAction<LocationAction>();
NullReferenceCheckHelper.throwIfNull(location_action, () => $"location_action is null !!! - {player.toBasicString()}");
var current_indun_location = location_action.getCurrentLocation() as IndunLocation;
NullReferenceCheckHelper.throwIfNull(current_indun_location, () => $"current_indun_location is null !!! - {player.toBasicString()}");
var instance_room_Id = current_indun_location.InstanceRoomId;
if (instance_room_Id == string.Empty)
return (result, res);
if (!await BattleInstanceManager.It.LeaveBattleRoom(player, instance_room_Id))
{
err_msg = $"Fail to LeaveBattleRoom() !!! : instanceRoomId:{instance_room_Id}";
result.setFail(ServerErrorCode.NotExistInstanceRoom, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, res);
}
Log.getLogger().debug($"try leave battle instancr room done instance_room_Id : {instance_room_Id}");
return (result, res);
}
}