using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using MetaAssets; using static ClientToGameReq.Types; using static ClientToGameRes.Types; using USER_GUID = System.String; namespace GameServer; public partial class GameZoneMoveAction : EntityActionBase { public GameZoneMoveAction(Player owner) : base(owner) { } public override Task onInit() { var result = new Result(); return Task.FromResult(result); } public override void onClear() { return; } public async Task<(Result, ServerConnectInfo?, List?)> tryLeaveInstance() { var result = new Result(); var err_msg = string.Empty; var server_connect_info = new ServerConnectInfo(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var server_logic = GameServerApp.getServerLogic(); 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); var location_attribute = player.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"location_attribute is null !!! - {player.toBasicString()}"); var channel_server_name = location_attribute.LastestChannelServerLocation.ServerName; var world_meta_id = location_attribute.LastestChannelServerLocation.WorldMetaId; var instance_room_Id = location_attribute.CurrentIndunLocation.InstanceRoomId; Pos lastest_channel_pos = new(); location_attribute.LastestChannelServerLocation.toPos(lastest_channel_pos); var server_info = await server_logic.getReturnToServerInfo(channel_server_name, ServerType.Channel, player, (ushort)world_meta_id); if (server_info == null) { err_msg = $"Failed to get balanced GameServer !!! - {player.toBasicString()}"; result.setFail(ServerErrorCode.NoServerConnectable, err_msg); Log.getLogger().error(err_msg); return (result, null, null); } // 이동 예약 var message = new ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER(); message.MoveType = ServerMoveType.Force; message.RequestUserGuid = player.getUserGuid(); message.RequestServerName = server_logic.getServerName(); var reserved = await server_logic.getReservationManager().registerReservationEnterToServer(message, server_info.Name); // 예약 실패 체크 if (null == reserved) { err_msg = $"Failed to Reservation Enter to server !!! : {server_info.Name} - {player.toBasicString()}"; result.setFail(ServerErrorCode.FailedToReservationEnter, err_msg); Log.getLogger().error(result.toBasicString()); return (result, null, null); } var location_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action, () => $"location action is null !!! - {player.toBasicString()}"); result = await location_action.tryMoveToChannel(); if (result.isFail()) { err_msg = $"Failed to tryMoveToChannel() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } var buff_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff action is null !!! - {player.toBasicString()}"); result = await buff_action.MoveServer(EPlaceType.World); if (result.isFail()) { err_msg = $"Failed to MoveServer() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } (result, var reserved_to_switch_server) = await ServerConnectionSwitchHelper.startServerSwitch(player, server_logic.getRedisConnector(), server_info.Name); if (result.isFail() || null == reserved_to_switch_server) { err_msg = $"Failed to startServerSwitch() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } if (!await InstanceRoomManager.Instance.LeaveRoom(player, instance_room_Id)) { err_msg = $"Failed to LeaveRoom() !!! : instanceRoomId:{instance_room_Id}"; result.setFail(ServerErrorCode.NotExistInstanceRoom, err_msg); Log.getLogger().error(result.toBasicString()); return (result, null, null); } var game_login_action = player.getEntityAction(); 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.toBasicString()}"); login_cache.ReservedToSwitchServer = reserved_to_switch_server; server_connect_info.ServerAddr = server_info.Address; server_connect_info.ServerPort = server_info.Port; server_connect_info.Otp = reserved_to_switch_server.OneTimeKey; var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, server_info.Name, server_info.Channel.ToString(), MapFileType.World, world_meta_id, lastest_channel_pos); var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info); business_logs.Add(arrival_position_business_log); return (result, server_connect_info, business_logs); } public async Task<(Result, ServerConnectInfo?, List?)> tryJoinInstance(USER_GUID userGuid, int instanceMetaId) { var result = new Result(); var err_msg = string.Empty; var server_connect_info = new ServerConnectInfo(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var server_logic = GameServerApp.getServerLogic(); if (!MetaData.Instance._IndunTable.TryGetValue(instanceMetaId, out var indun_meta_data)) { err_msg = $"Failed to MetaData.TryGetValue() !!! : instanceMetaId:{instanceMetaId} - {player.toBasicString()}"; result.setFail(ServerErrorCode.InstanceMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, null, null); } result = player.checkInstanceAccess(instanceMetaId); if (result.isFail()) { err_msg = $"Failed to checkInstanceAccess() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } 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); (result, var instance_room_id) = await InstanceRoomHandler.joinInstance(player.getUserGuid(), instanceMetaId); if (result.isFail()) { err_msg = $"Failed to joinInstance() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } 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, null); } 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, null); } var location_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action, () => $"location_action is null !!! - {player.toBasicString()}"); result = await location_action.tryMoveToIndun(instance_room_info); if (result.isFail()) { err_msg = $"Failed to tryMoveToIndun() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } var buff_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff_action is null !!! - {player.toBasicString()}"); result = await buff_action.MoveServer(indun_meta_data.placeType()); if (result.isFail()) { err_msg = $"Failed to MoveServer() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } (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, null); } var game_login_action = player.getEntityAction(); 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; var start_pos = MapManager.Instance.GetStartPos(indun_meta_data.RoomFile); var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, server_name, instance_room_info.roomId, MapFileType.Instance, instance_room_info.InstanceId, start_pos); var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info); business_logs.Add(arrival_position_business_log); return (result, server_connect_info, business_logs); } public async Task<(Result, ClientToGameRes.Types.WarpRes, List?)> tryWarp(int warpMetaId) { var result = new Result(); var err_msg = string.Empty; var res = new ClientToGameRes.Types.WarpRes(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !"); var server_logic = GameServerApp.getServerLogic(); if (!MetaData.Instance._WarpTable.TryGetValue(warpMetaId, out var warp_meta_data)) { err_msg = $"Failed to MetaData.TryGetValue() !!! : warpMetaId:{warpMetaId} - {player.toBasicString()}"; result.setFail(ServerErrorCode.WarpMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } List? type_of_warp_business_logs; switch (warp_meta_data.TargetType) { case MetaAssets.WarpType.WORLD: { if (warp_meta_data.LandId == 0 && warp_meta_data.FloorId == 0) { (result, res, type_of_warp_business_logs) = await tryWarpToChannel(warp_meta_data); if (result.isFail() || null == type_of_warp_business_logs) { return (result, res, null); } } else { (result, res, type_of_warp_business_logs) = await tryWarpToIndun(player.getUserGuid(), warp_meta_data); if (result.isFail() || null == type_of_warp_business_logs) { return (result, res, null); } } } break; case MetaAssets.WarpType.INSTANCE: { (result, res, type_of_warp_business_logs) = await tryWarpToIndun(player.getUserGuid(), warp_meta_data); if (result.isFail() || null == type_of_warp_business_logs) { return (result, res, null); } } break; case MetaAssets.WarpType.MYHOME: { (result, res, type_of_warp_business_logs) = await tryWarpToMyHome(warp_meta_data); if (result.isFail() || null == type_of_warp_business_logs) { return (result, res, null); } } break; case MetaAssets.WarpType.FITTINGROOM: { (result, res, type_of_warp_business_logs) = await tryWarpToFittingRoom(warp_meta_data); if (result.isFail() || null == type_of_warp_business_logs) { return (result, res, null); } } break; case MetaAssets.WarpType.EDITROOM: { err_msg = $"Not Implemented !!! : warpType:{warp_meta_data.TargetType}, warpMetaId:{warp_meta_data.WarpId} - {player.toBasicString()}"; result.setFail(ServerErrorCode.FunctionNotImplemented, err_msg); Log.getLogger().error(err_msg); return (result, res, null); // Mantis#3451 로 주석 처리 //(result, res, type_of_warp_business_logs) = await tryWarpToEditRoom(warp_meta_data); //if (result.isFail()) //{ // return (result, res); //} } case MetaAssets.WarpType.RETURN: { (result, res, type_of_warp_business_logs) = await tryWarpToReturn(warp_meta_data); if (result.isFail() || null == type_of_warp_business_logs) { return (result, res, null); } } break; default: { err_msg = $"WarpType Invalid !!! : type:{warp_meta_data.TargetType}, warpMetaId:{warp_meta_data.WarpId} - {player.toBasicString()}"; result.setFail(ServerErrorCode.WarpTypeInvalid, err_msg); Log.getLogger().error(err_msg); return (result, res, null); } } business_logs.AddRange(type_of_warp_business_logs); return (result, res, business_logs); } public async Task<(Result, ClientToGameRes.Types.TaxiRes, List?)> tryTaxi(int taxiMetaId) { var result = new Result(); var err_msg = string.Empty; var res = new ClientToGameRes.Types.TaxiRes(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var server_type = server_logic.getServerType().toServerType(); if (server_type != ServerType.Channel) { err_msg = $"Not Usable Place !!! : ServerType:{server_type} - {player.toBasicString()}"; result.setFail(ServerErrorCode.NotUsablePlace, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } if (!MetaData.Instance._TaxiMetaTable.TryGetValue(taxiMetaId, out var taxi_meta_data)) { err_msg = $"Failed to MetaData.TryGetValue() !!! : taxiMetaId:{taxiMetaId} - {player.toBasicString()}"; result.setFail(ServerErrorCode.TaxiMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } var taxi_log_info = TaxiBusinessLogHelper.toTaxiLogInfo(taxi_meta_data); var taxi_business_log = new TaxiBusinessLog(taxi_log_info); business_logs.Add(taxi_business_log); var money_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(money_action, () => $"money action is null !!! - {player.toBasicString()}"); result = await money_action.changeMoney(CurrencyType.Gold, -taxi_meta_data.UnloadingCost); if (result.isFail()) { err_msg = $"Failed to changeMoney() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } switch (taxi_meta_data.Type) { case MetaAssets.TaxiType.INSTANCE: { if (!MetaData.Instance._WorldMetaTable.TryGetValue(taxi_meta_data.UnloadingWorldId, out var world_meta_data)) { err_msg = $"Failed to MetaData.TryGetValue() !!! : worldMetaId:{taxi_meta_data.UnloadingWorldId} - {player.toBasicString()}"; result.setFail(ServerErrorCode.WorldMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } if (!MapManager.Instance.GetWorldMapTree(world_meta_data.MapPath, out var world_map_tree)) { err_msg = $"Failed to GetWorldMapTree() !!! : MapPath:{world_meta_data.MapPath} - {player.toBasicString()}"; result.setFail(ServerErrorCode.WorldMapTreeDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } if (!world_map_tree.ChildLandMapTrees.TryGetValue(taxi_meta_data.UnloadingLandId, out var land_map_tree)) { err_msg = $"Failed to WorldMapTree.ChildLandMaps.TryGetValue() !!! : WorldMap:{world_map_tree.WorldMapFileName}, landMetaId:{taxi_meta_data.UnloadingLandId} - {player.toBasicString()}"; result.setFail(ServerErrorCode.WorldMapTreeChildLandNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } (result, var room_map_tree, var address_business_log) = MapHelper.tryGetRoomMapTree(taxi_meta_data.UnloadingLandId, taxi_meta_data.UnloadingFloorId); if (result.isFail() || null == room_map_tree || null == address_business_log) { err_msg = $"Failed to tryGetRoomMapTree() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } var instance_meta_id = room_map_tree.InstanceMetaId; if (!MetaData.Instance._IndunTable.TryGetValue(instance_meta_id, out var indun_meta_data)) { err_msg = $"Failed to MetaData.TryGetValue() !!! : instanceMetaId:{instance_meta_id} - {player.toBasicString()}"; result.setFail(ServerErrorCode.InstanceMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } ServerConnectInfo? server_connect_info; List? join_instance_business_logs; if (indun_meta_data.ContentsType == ContentsType.MyHome) { (result, server_connect_info, join_instance_business_logs) = await tryEnterMyhome(room_map_tree.OwnerGuid, room_map_tree.MyhomeGuid); if (result.isFail() || null == server_connect_info || null == join_instance_business_logs) { err_msg = $"Failed to tryEnterMyhome() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } } else { (result, server_connect_info, join_instance_business_logs) = await tryJoinInstance(player.getUserGuid(), instance_meta_id); if (result.isFail() || null == server_connect_info || null == join_instance_business_logs) { err_msg = $"Failed to tryJoinInstance() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } } res.InstanceServerConnectInfo = server_connect_info; business_logs.Add(address_business_log); business_logs.AddRange(join_instance_business_logs); } break; case MetaAssets.TaxiType.WAYPOINT: { var game_zone_action = getOwner().getEntityAction(); ArgumentNullException.ThrowIfNull(game_zone_action); (result, var new_pos, var taxi_way_point_business_log) = game_zone_action.tryMoveTaxiWayPoint(taxi_meta_data); if (result.isFail() || null == taxi_way_point_business_log) { err_msg = $"Failed to tryMoveTaxiWayPoint() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } res.Pos = new_pos; business_logs.AddRange(taxi_way_point_business_log); } break; default: { err_msg = $"TaxiType Invalid !!! : type:{taxi_meta_data.Type}, taixMetaId:{taxi_meta_data.TaxiId} - {player.toBasicString()}"; result.setFail(ServerErrorCode.TaxiTypeInvalid, err_msg); Log.getLogger().error(err_msg); return (result, res, null); } } res.CurrencyInfo = money_action.toCurrency4Client(); return (result, res, business_logs); } // 역할 : warpData 에 있는 좌표로 보냄 // warpData -> 타입이 WORLD && WorldId == Current.WorldId && Current.Channel : warpData 좌표로 이동 // warpData -> 타입이 WORLD && WorldId != Current.WorldId && Current.Channel : warpData.WorldId 의 warpData 좌표로 이동 // warpData -> 타입이 WORLD && Current.Indun : Channel의 warpData 좌표로 이동 private async Task<(Result, ClientToGameRes.Types.WarpRes, List?)> tryWarpToChannel(MetaAssets.WarpMetaData warpData) { var result = new Result(); var err_msg = string.Empty; var res = new ClientToGameRes.Types.WarpRes(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var server_logic = GameServerApp.getServerLogic(); 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); var server_move_type = ServerMoveType.Force; WorldMetaData? world_meta_data = null; var newPos = ServerBase.EntityHelper.makePos(warpData.PositionX, warpData.PositionY, warpData.PositionZ, warpData.Rotate); // Channel 서버에서 이동 if (server_logic.getServerType().toServerType() == ServerType.Channel) { // 동일 World 의 Channel 로 이동 ( Channel 변경 없음 / 이동만 처리 ) if (warpData.WorldId == server_logic.getWorldId()) { var location_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action, () => $"location_action is null !!! - {player.toBasicString()}"); result = location_action.tryUpdateCurrentPos(newPos); if (result.isFail()) { err_msg = $"Failed to tryUpdateCurrentPos() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } res.Pos = newPos; var arrival_position_info = player.getCurrentPositionInfo(); arrival_position_info.Pos = newPos; var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, arrival_position_info); var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info); business_logs.Add(arrival_position_business_log); return (result, res, business_logs); } // world 이동 조건 체크 (result, world_meta_data) = await checkWarpToWorldConditions(player, warpData.WorldId); if (result.isFail() || null == world_meta_data) { return (result, res, null); } server_move_type = ServerMoveType.Auto; } var server_info = await server_logic.getBalancedServerInfo(player, ServerType.Channel, server_move_type, (ushort)warpData.WorldId); if (null == server_info) { err_msg = $"Failed to get balanced GameServer !!! - {player.toBasicString()}"; result.setFail(ServerErrorCode.NoServerConnectable, err_msg); Log.getLogger().error(err_msg); return (result, res, null); } // 예약 처리 var message = new ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER(); message.MoveType = ServerMoveType.Auto; message.RequestUserGuid = player.getUserGuid(); message.RequestServerName = server_logic.getServerName(); var reserved = await server_logic.getReservationManager().registerReservationEnterToServer(message, server_info.Name); // 예약 실패 체크 if (null == reserved) { err_msg = $"Failed to Reservation Enter to server !!! : {server_info.Name} - {player.toBasicString()}"; result.setFail(ServerErrorCode.FailedToReservationEnter, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } // 이동 처리 result = await GameZoneMoveHelper.moveToAnotherChannel(player, server_info, newPos); if (result.isFail()) { err_msg = $"Failed to moveToAnotherChannel() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } if(null != world_meta_data) { // 요구 아이템 삭제 (result, var delete_items) = await deleteRequiredItem(player, world_meta_data); if (result.isFail()) { err_msg = $"Failed to deleteRequiredItem() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } if (null != delete_items) { foreach (var item in delete_items) { var data = item.toItemData4Client(); var input = new ItemGuidCount(); input.ItemGuid = data.ItemGuid; input.ItemCount = world_meta_data.DeleteItemCount; res.DeleteItems.Add(input); } } } // res 채우기 var account_attribute = player.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account attribute is null !!! - {player.toBasicString()}"); res.GameServerConnectInfo = new() { ServerAddr = server_info.Address, ServerPort = server_info.Port, Otp = account_attribute.OtpForServerConnect }; { var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, server_info.Name, server_info.Channel.ToString(), MapFileType.World, warpData.WorldId, newPos); var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info); business_logs.Add(arrival_position_business_log); } return (result, res, business_logs); } private async Task<(Result, IEnumerable?)> deleteRequiredItem(Player player, WorldMetaData? meta) { var result = new Result(); if (null == meta) { var err_msg = $"fail to get world meta data !! : {nameof(tryWarpToChannel)}.{nameof(deleteRequiredItem)}"; result.setFail(ServerErrorCode.WorldMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null); } // 1. 아이템 소모 타입인지 체크 if (meta.AccessType != WorldAccessType.Item) return (result, null); // 2. 아이템 제거 var inventory_action = player.getEntityAction(); (result, var del_items) = await inventory_action.tryDeleteItemByMetaId((uint)meta.DeleteItem, (ushort)meta.DeleteItemCount); if (result.isFail()) return (result, null); return (result, del_items); } private async Task<(Result, ClientToGameRes.Types.WarpRes, List?)> tryWarpToIndun(USER_GUID userGuid, MetaAssets.WarpMetaData warpData) { var result = new Result(); var err_msg = string.Empty; var res = new ClientToGameRes.Types.WarpRes(); var business_logs = new List(); var server_logic = GameServerApp.getServerLogic(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); // 1. Dest Instance 정보 획득 (result, var room_map_tree, var address_business_log) = MapHelper.tryGetRoomMapTree(warpData.LandId, warpData.FloorId); if (result.isFail() || null == room_map_tree || null == address_business_log) { err_msg = $"Failed to tryGetRoomMapTree() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } // 2. Dest Meta 정보 획득 var instance_meta_id = room_map_tree.InstanceMetaId; if (!MetaData.Instance._IndunTable.TryGetValue(instance_meta_id, out var indun_meta_data)) { err_msg = $"Failed to MetaData.TryGetValue() !!! : instanceMetaId:{instance_meta_id} - {player.toBasicString()}"; result.setFail(ServerErrorCode.InstanceMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } ServerConnectInfo? server_connect_info; List? join_instance_business_logs; // 3. Indun 서버에서 이동 if (server_logic.getServerType().toServerType() == ServerType.Indun) { var check_same_location = checkSameIndunLocation(player, room_map_tree); if(check_same_location.result.isFail()) return (check_same_location.result, res, null); // Dest == Current : 좌표 이동 if (check_same_location.isSame) { 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); var location_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action, () => $"LocationAction is null !!! - {player.toBasicString()}"); var newPos = ServerBase.EntityHelper.makePos(warpData.PositionX, warpData.PositionY, warpData.PositionZ, warpData.Rotate); // World 좌표 변환 if (indun_meta_data.ContentsType == ContentsType.MyHome) { newPos = MapHelper.getWorldPosFromMyhomeRelativePos(newPos); } else { (result, newPos) = MapHelper.getWorldPosFromRoomRelativePos(room_map_tree, newPos); if (result.isFail()) return (result, res, null); } // 좌표 설정 result = location_action.tryUpdateCurrentPos(newPos); if (result.isFail()) return (result, res, null); res.Pos = newPos; var arrival_position_info = player.getCurrentPositionInfo(); arrival_position_info.Pos = newPos; var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, arrival_position_info); var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info); business_logs.Add(arrival_position_business_log); return (result, res, business_logs); } } // 4. Dest Type : MyHome if (indun_meta_data.ContentsType == ContentsType.MyHome) { (result, server_connect_info, join_instance_business_logs) = await tryEnterMyhome(room_map_tree.OwnerGuid, room_map_tree.MyhomeGuid); if (result.isFail() || null == server_connect_info || null == join_instance_business_logs) { err_msg = $"Failed to tryEnterMyhome() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } } // 5. Dest Type : 나머지 else { (result, server_connect_info, join_instance_business_logs) = await tryJoinInstance(player.getUserGuid(), instance_meta_id); if (result.isFail() || null == server_connect_info || null == join_instance_business_logs) { err_msg = $"Failed to tryJoinInstance() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } } res.InstanceServerConnectInfo = server_connect_info; business_logs.Add(address_business_log); business_logs.AddRange(join_instance_business_logs); return (result, res, business_logs); } private async Task<(Result, ClientToGameRes.Types.WarpRes, List?)> tryWarpToMyHome(MetaAssets.WarpMetaData warpData) { var result = new Result(); var err_msg = string.Empty; var res = new ClientToGameRes.Types.WarpRes(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var user_guid = player.getUserGuid(); (result, var server_connect_info, var enter_myhome_business_logs) = await tryEnterMyhome(user_guid); if (result.isFail() || null == server_connect_info || null == enter_myhome_business_logs) { err_msg = $"Failed to tryEnterMyhome() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } res.InstanceServerConnectInfo = server_connect_info; business_logs.AddRange(enter_myhome_business_logs); return (result, res, business_logs); } private async Task<(Result, ClientToGameRes.Types.WarpRes, List?)> tryWarpToFittingRoom(MetaAssets.WarpMetaData warpData) { var result = new Result(); var err_msg = string.Empty; var res = new ClientToGameRes.Types.WarpRes(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var server_logic = GameServerApp.getServerLogic(); 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); (result, var instance_room_id) = await InstanceRoomHandler.joinDressRoomInstance(player.getUserGuid()); if (result.isFail()) { err_msg = $"Failed to joinDressRoomInstance() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } 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, res, null); } string 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 = player.getUserGuid(); 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, res, null); } var location_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action, () => $"location action is null !!! - {player.toBasicString()}"); result = await location_action.tryMoveToIndun(instance_room_info); if (result.isFail()) { err_msg = $"Failed to tryMoveToIndun() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } var buff_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff action is null !!! - {player.toBasicString()}"); result = await buff_action.MoveServer(EPlaceType.DressRoom); if (result.isFail()) { err_msg = $"Failed to MoveServer() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } (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, res, null); } var game_login_action = player.getEntityAction(); 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; res.InstanceServerConnectInfo = new() { ServerAddr = instance_room_info.InstanceAddress, ServerPort = instance_room_info.InstancePort, Otp = reserved_to_switch_server.OneTimeKey, RoomId = instance_room_info.roomId }; var start_pos = MapHelper.getWarpPos(ContentsType.DressRoom); var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, server_name, instance_room_info.roomId, MapFileType.Instance, instance_room_info.InstanceId, start_pos); var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info); business_logs.Add(arrival_position_business_log); await QuestManager.It.QuestCheckWithoutTransaction(player, new QuestDressRoom(EQuestEventTargetType.DRESSROOM, EQuestEventNameType.ENTERED, "MYSELF")); return (result, res, business_logs); } private async Task<(Result, ClientToGameRes.Types.WarpRes, List?)> tryWarpToEditRoom(MetaAssets.WarpMetaData warpData) { var result = new Result(); var err_msg = string.Empty; var res = new ClientToGameRes.Types.WarpRes(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var user_guid = player.getUserGuid(); (result, var server_connect_info, var enter_myhome_edit_room_business_logs) = await tryEnterMyhomeEditRoom(user_guid); if (result.isFail() || null == server_connect_info || null == enter_myhome_edit_room_business_logs) { err_msg = $"Failed to tryEnterMyhomeEditRoom() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } res.InstanceServerConnectInfo = server_connect_info; business_logs.AddRange(enter_myhome_edit_room_business_logs); return (result, res, business_logs); } private async Task<(Result, ClientToGameRes.Types.WarpRes, List?)> tryWarpToReturn(MetaAssets.WarpMetaData warpData) { var result = new Result(); var err_msg = string.Empty; var res = new ClientToGameRes.Types.WarpRes(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var server_type = server_logic.getServerType().toServerType(); if (server_type == ServerType.Channel) { err_msg = $"Not Usable Place !!! : ServerType:{server_type} - {player.toBasicString()}"; result.setFail(ServerErrorCode.NotUsablePlace, err_msg); Log.getLogger().error(result.toBasicString()); return (result, res, null); } var location_attribute = player.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"location attribute is null !!! - {player.toBasicString()}"); var instance_room_id_str_cause_quest = new string(location_attribute.CurrentIndunLocation.InstanceRoomId); var instacne_room_id_cause_quest = InstanceRoomManager.Instance.getRoomId(instance_room_id_str_cause_quest); bool is_return_to_indun = false; MyHomeAttrib? myhome_attrib = null; MyhomeUgcInfo? myhome_ugc_info = null; while (location_attribute.ReturnIndunLocations.Count > 0) { var last_index = location_attribute.ReturnIndunLocations.Count - 1; var return_location = location_attribute.ReturnIndunLocations[last_index]; location_attribute.ReturnIndunLocations.RemoveAt(last_index); if (!MetaData.Instance._IndunTable.TryGetValue(return_location.InstanceMetaId, out var instance_meta_data)) { err_msg = $"Failed to MetaData.TryGetValue() !!! : instanceMetaId:{return_location.InstanceMetaId} - {player.toBasicString()}"; Log.getLogger().error(result.toBasicString()); continue; } string roomId = string.Empty; switch (instance_meta_data.ContentsType) { case ContentsType.None: break; case ContentsType.MyHome: { result = MyhomeHelper.getMyhomeOwnerUserGuidAndMyhomeGuidFromRoomId(return_location.InstanceRoomId, out var myhome_owner_user_guid, out var myhome_guid); if (result.isFail()) { err_msg = $"Failed to getMyHomeOwnerUserGuidFromRoomId() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); continue; } (result, myhome_attrib) = await MyhomeHelper.getEnterMyhomeAttribFromDynamoDb(myhome_owner_user_guid, myhome_guid); if (result.isFail() || null == myhome_attrib) { err_msg = $"Failed to getSelectedMyhomeUgcInfoFromDynamoDb() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); continue; } (result, myhome_ugc_info) = await MyhomeHelper.getMyhomeUgcInfo(myhome_attrib); if (result.isFail() || null == myhome_ugc_info) { err_msg = $"Failed to getMyhomeUgcInfo() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); continue; } var user_guid = player.getUserGuid(); if (user_guid != myhome_owner_user_guid) { result = await MyhomeHelper.checkMyhomeIsEditting(myhome_attrib.MyhomeGuid, myhome_owner_user_guid); if (result.isFail()) { err_msg = $"Failed to checkMyhomeIsEditting() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); continue; } } result = MyhomeHelper.getMyhomeInstanceId(myhome_ugc_info.RoomType, out var instance_meta_id); if (result.isFail()) { err_msg = $"Fail to getMyhomeInstanceId() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); continue; } var enter_player_count = 0; if (MapManager.Instance.getRoomMapTree(myhome_guid, out var room_map_tree)) enter_player_count = room_map_tree.EnterPlayerCount; result = await InstanceRoomHandler.joinTargetInstanceRoom(player.getUserGuid(), return_location.InstanceRoomId, return_location.InstanceMetaId, enter_player_count); if (result.isSuccess()) { roomId = return_location.InstanceRoomId; } else { (result, roomId) = await InstanceRoomHandler.joinMyhomeInstance(player.getUserGuid(), myhome_owner_user_guid, myhome_guid, instance_meta_id, enter_player_count); if (result.isFail()) { err_msg = $"Failed to JoinMyHomeInstance() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); continue; } } } break; case ContentsType.DressRoom: { (result, roomId) = await InstanceRoomHandler.joinDressRoomInstance(player.getUserGuid()); if (result.isFail()) { err_msg = $"Failed to joinDressRoomInstance() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); continue; } } break; case ContentsType.EditRoom: { (result, var instance_room_id) = await InstanceRoomHandler.joinEditRoomInstance(player.getUserGuid()); if (result.isFail()) { err_msg = $"Failed to joinEditRoomInstance() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); continue; } } break; default: { (result, roomId) = await InstanceRoomHandler.joinInstance(player.getUserGuid(), return_location.InstanceMetaId, return_location.InstanceRoomId); if (result.isFail()) { err_msg = $"Failed to joinInstance() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); continue; } } break; } if (roomId == string.Empty) continue; var instance_room_storage = new InstanceRoomStorage(); instance_room_storage.Init(server_logic.getRedisDb(), ""); var instance_room_info = await instance_room_storage.GetInstanceRoomInfo(roomId); if (instance_room_info == null) { err_msg = $"Failed to GetInstanceRoomInfo() !!! : instanceRoomId:{roomId} - {player.toBasicString()}"; result.setFail(ServerErrorCode.NotExistRoomInfoForEnter, err_msg); Log.getLogger().error(result.toBasicString()); continue; } string 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 = player.getUserGuid(); 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(err_msg); continue; } var location_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action, () => $"location action is null !!! - {player.toBasicString()}"); Pos return_pos = new(); return_location.toPos(return_pos); result = await location_action.tryMoveToIndun(instance_room_info, return_pos, true); if (result.isFail()) { err_msg = $"Failed to tryMoveToIndun() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); continue; } var buff_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff action is null !!! - {player.toBasicString()}"); result = await buff_action.MoveServer(instance_meta_data.placeType()); if (result.isFail()) { err_msg = $"Failed to MoveServer() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); continue; } (result, var reserved_to_switch_server) = await ServerConnectionSwitchHelper.startServerSwitch(player, server_logic.getRedisConnector(), reserved.ReservationServerName); if (result.isFail() || null == reserved_to_switch_server) { err_msg = $"Failed to startServerSwitch() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); continue; } var game_login_action = player.getEntityAction(); 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; res.InstanceServerConnectInfo = new() { ServerAddr = instance_room_info.InstanceAddress, ServerPort = instance_room_info.InstancePort, Otp = reserved_to_switch_server.OneTimeKey, RoomId = instance_room_info.roomId, Pos = return_pos, InstanceId = instance_meta_data.Id }; if (myhome_attrib != null) { res.InstanceServerConnectInfo.MyhomeInfo = new(); res.InstanceServerConnectInfo.MyhomeInfo.MyhomeGuid = myhome_attrib.MyhomeGuid; res.InstanceServerConnectInfo.MyhomeInfo.MyhomeName = myhome_attrib.MyhomeName; res.InstanceServerConnectInfo.MyhomeInfo.MyhomeUgcInfo = myhome_ugc_info; } 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); var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, server_name, instance_room_info.roomId, MapFileType.Instance, instance_room_info.InstanceId, return_pos); var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info); business_logs.Add(arrival_position_business_log); is_return_to_indun = true; break; } // 채널 서버로 이동 if (!is_return_to_indun) { (result, var server_connect_info, var leave_instance_business_logs) = await tryLeaveInstance(); if (result.isFail() || null == server_connect_info || null == leave_instance_business_logs) { err_msg = $"Failed to tryLeaveInstance() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, res, null); } res.GameServerConnectInfo = server_connect_info; business_logs.AddRange(leave_instance_business_logs); } await QuestManager.It.QuestCheckAtWarpRet(player, instance_room_id_str_cause_quest, instacne_room_id_cause_quest); return (result, res, business_logs); } private async Task<(Result result, WorldMetaData? meta)> checkWarpToWorldConditions(Player player, int worldId) { var result = new Result(); string err_msg; // 1. world meta 정보 획득 if (!MetaData.Instance._WorldMetaTable.TryGetValue(worldId, out var meta)) { err_msg = $"fail to get world meta !!! : worldId - {worldId}"; result.setFail(ServerErrorCode.WorldMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); return (result, null); } // 2. 조건 타입 체크 switch (meta.AccessType) { case WorldAccessType.Public: break; case WorldAccessType.Item: result = await checkRequiredItem(player, meta.DeleteItem, meta.DeleteItemCount); break; case WorldAccessType.NFT: result = await checkReqiredNFT(player, meta.AccessId); break; default: err_msg = $"fail to get world meta !!! : worldId - {worldId}"; result.setFail(ServerErrorCode.WorldMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); break; } return (result, meta); } private async Task checkRequiredItem(Player player, int itemId, int itemCount) { var result = new Result(); var inventory_action = player.getEntityAction(); var list = inventory_action.tryGetItemAllByItemMetaId((uint)itemId); if (itemCount > list.Count) { var err_msg = $"fail to get inventory item : item is lack - itemId[{itemId}] / count[{itemCount}] / inventory[{list.Count}]"; result.setFail(ServerErrorCode.LackOfWorldEnterItem, err_msg); Log.getLogger().error(err_msg); } return await Task.FromResult(result); } private async Task checkReqiredNFT(Player player, int nftId) { // todo(sangyeob.kim): nft 소지여부 검사 로직이 필요함 return await Task.FromResult(new Result()); } private (Result result, bool isSame) checkSameIndunLocation(Player player, RoomMapTree roomMapTree) { var result = new Result(); var location_attribute = player.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"LocationAttribute is null !!! - player:{player.toBasicString()}"); var current_instance_meta_id = location_attribute.CurrentIndunLocation.InstanceMetaId; if (!MetaData.Instance._IndunTable.TryGetValue(current_instance_meta_id, out var current_indun_meta_data)) { var err_msg = $"Failed to MetaData.TryGetValue() !!! : CurrentinstanceMetaId:{current_instance_meta_id} - player:{player.toBasicString()}"; result.setFail(ServerErrorCode.InstanceMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return (result, false); } if (current_indun_meta_data.ContentsType == ContentsType.MyHome) { var myHome_result = MyhomeHelper.getMyhomeOwnerUserGuidAndMyhomeGuidFromRoomId(location_attribute.CurrentIndunLocation.InstanceRoomId, out _, out var myHomeGuid); if (myHome_result.isFail()) return (myHome_result, false); if (myHomeGuid != roomMapTree.MyhomeGuid) return (result, false); } else { if (current_instance_meta_id != roomMapTree.InstanceMetaId) return (result, false); } return (result, true); } public async Task<(Result, ServerConnectInfo?)> tryJoinFriendMyhomeInstance(string friendMyhomeRoomId) { 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 instance_room_storage = new InstanceRoomStorage(); instance_room_storage.Init(server_logic.getRedisDb(), ""); result = MyhomeHelper.getMyhomeOwnerUserGuidAndMyhomeGuidFromRoomId(friendMyhomeRoomId, out var myhome_owner_user_guid, out _); if (result.isFail()) { err_msg = $"Failed to getMyHomeOwnerUserGuidFromRoomId() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null); } (result, var myhome_attrib) = await MyhomeHelper.getEnterMyhomeAttribFromDynamoDb(myhome_owner_user_guid); if (result.isFail() || null == myhome_attrib) { err_msg = $"Failed to getSelectedMyhomeUgcInfoFromDynamoDb() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null); } (result, var myhome_ugc_info) = await MyhomeHelper.getMyhomeUgcInfo(myhome_attrib); if (result.isFail() || null == myhome_ugc_info) { err_msg = $"Fail to getMyhomeUgcInfo() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null); } result = await MyhomeHelper.checkMyhomeIsEditting(myhome_attrib.MyhomeGuid, myhome_owner_user_guid); if (result.isFail()) { err_msg = $"Fail to checkMyhomeIsEditting() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null); } result = MyhomeHelper.getMyhomeInstanceId(myhome_ugc_info.RoomType, out var instance_meta_id); if (result.isFail()) { err_msg = $"Fail to getMyhomeInstanceId() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null); } var roomId = string.Empty; var enter_player_count = 0; if (MapManager.Instance.getRoomMapTree(myhome_attrib.MyhomeGuid, out var room_map_tree)) enter_player_count = room_map_tree.EnterPlayerCount; result = await InstanceRoomHandler.joinTargetInstanceRoom(player.getUserGuid(), friendMyhomeRoomId, instance_meta_id, enter_player_count); if (result.isSuccess()) { roomId = friendMyhomeRoomId; } else { (result, roomId) = await InstanceRoomHandler.joinMyhomeInstance(player.getUserGuid(), myhome_owner_user_guid, myhome_attrib.MyhomeGuid, instance_meta_id, enter_player_count); if (result.isFail()) { err_msg = $"Fail to JoinMyHomeInstance() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null); } } var instance_room_info = await instance_room_storage.GetInstanceRoomInfo(roomId); if (instance_room_info == null) { err_msg = $"Not found InstanceRoomInfo. friendRoomId:{roomId}"; result.setFail(ServerErrorCode.NotExistRoomInfoForEnter, err_msg); Log.getLogger().error(result.toBasicString()); return (result, null); } var start_pos_anchor_postion = myhome_ugc_info.getMyhomeStartPosAnchorPosition(); var myhome_start_pos = MapHelper.getMyhomeStartPos(start_pos_anchor_postion); var location_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action, () => $"location action is null !!! - {player.toBasicString()}"); result = await location_action.tryMoveToIndun(instance_room_info, myhome_start_pos); if (result.isFail()) { err_msg = $"Fail to tryMoveToIndun"; Log.getLogger().error(err_msg); return (result, null); } var buff_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff action is null !!! - {player.toBasicString()}"); result = await buff_action.MoveServer(EPlaceType.MyHome); if (result.isFail()) { return (result, null); } string serverName = ServerType.Indun.toServerName(instance_room_info.InstanceAddress, (ushort)instance_room_info.InstancePort); (result, var reserved_to_switch_server) = await ServerConnectionSwitchHelper.startServerSwitch(player, server_logic.getRedisConnector(), serverName); if (result.isFail() || null == reserved_to_switch_server) { err_msg = $"Fail to startServerSwitch() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null); } var game_login_action = player.getEntityAction(); 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; var myhome_info = new MyHomeInfo { MyhomeGuid = myhome_attrib.MyhomeGuid, MyhomeName = myhome_attrib.MyhomeName, MyhomeUgcInfo = myhome_ugc_info, }; ServerConnectInfo server_connect_info = new() { ServerAddr = instance_room_info.InstanceAddress, ServerPort = instance_room_info.InstancePort, Otp = reserved_to_switch_server.OneTimeKey, RoomId = instance_room_info.roomId, MyhomeInfo = myhome_info, }; // 이동 예약 걸기 var message = new ServerMessage.Types.GS2GS_REQ_RESERVATION_ENTER_TO_SERVER(); message.MoveType = ServerMoveType.Force; message.RequestUserGuid = player.getUserGuid(); message.RequestServerName = server_logic.getServerName(); var reserved = await server_logic.getReservationManager().registerReservationEnterToServer(message, serverName); // 예약 실패 체크 if (null == reserved) { err_msg = $"Failed to Reservation Enter to server !!!! - {serverName}"; result.setFail(ServerErrorCode.FailedToReservationEnter, err_msg); Log.getLogger().error(err_msg); return (result, null); } return (result, server_connect_info); } public async Task<(Result, ServerConnectInfo?, List?)> tryEnterMyhome(string ownerGuid, string enterMyhomeGuid = "") { var result = new Result(); var err_msg = string.Empty; var server_connect_info = new ServerConnectInfo(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var server_logic = GameServerApp.getServerLogic(); (result, var myhome_attrib) = await MyhomeHelper.getEnterMyhomeAttribFromDynamoDb(ownerGuid, enterMyhomeGuid); if (result.isFail() || null == myhome_attrib) { err_msg = $"Failed to getSelectedMyhomeUgcInfoFromDynamoDb() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } (result, var myhome_ugc_info) = await MyhomeHelper.getMyhomeUgcInfo(myhome_attrib); if (result.isFail() || null == myhome_ugc_info) { err_msg = $"Failed to getMyhomeUgcInfo() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } enterMyhomeGuid = myhome_attrib.MyhomeGuid; result = await MyhomeHelper.checkMyhomeIsEditting(enterMyhomeGuid, (string)ownerGuid); if (result.isFail()) { err_msg = $"Failed to checkMyhomeIsEditting() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } result = MyhomeHelper.getMyhomeInstanceId(myhome_ugc_info.RoomType, out var instance_meta_id); if (result.isFail()) { err_msg = $"Fail to getMyhomeInstanceId() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } var enter_player_count = 0; if (MapManager.Instance.getRoomMapTree(enterMyhomeGuid, out var room_map_tree)) enter_player_count = room_map_tree.EnterPlayerCount; 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); (result, var instance_room_id) = await InstanceRoomHandler.joinMyhomeInstance(player.getUserGuid(), ownerGuid, enterMyhomeGuid, instance_meta_id, enter_player_count); if (instance_room_id == string.Empty) { err_msg = $"Failed to JoinMyHomeInstance() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } 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, null); } 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 = player.getUserGuid(); 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, null); } var start_pos_anchor_postion = myhome_ugc_info.getMyhomeStartPosAnchorPosition(); var myhome_start_pos = MapHelper.getMyhomeStartPos(start_pos_anchor_postion); var location_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action, () => $"location action is null !!! - {player.toBasicString()}"); result = await location_action.tryMoveToIndun(instance_room_info, myhome_start_pos); if (result.isFail()) { err_msg = $"Failed to tryMoveToIndun() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } var buff_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff action is null !!! - {player.toBasicString()}"); result = await buff_action.MoveServer(EPlaceType.MyHome); if (result.isFail()) { err_msg = $"Failed to MoveServer() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } (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, null); } var game_login_action = player.getEntityAction(); 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; var myhome_info = new MyHomeInfo { MyhomeGuid = enterMyhomeGuid, MyhomeName = myhome_attrib.MyhomeName, MyhomeUgcInfo = myhome_ugc_info, }; 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; server_connect_info.MyhomeInfo = myhome_info; var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, server_name, instance_room_info.roomId, MapFileType.Instance, instance_room_info.InstanceId, myhome_start_pos); var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info); business_logs.Add(arrival_position_business_log); await QuestManager.It.QuestCheckWithoutTransaction(player, new QuestMyHome(EQuestEventTargetType.MYHOME, EQuestEventNameType.ENTERED, "MYSELF")); return (result, server_connect_info, business_logs); } public async Task<(Result, ServerConnectInfo?, List?)> tryEnterMyhomeEditRoom(string myhomeGuid) { var result = new Result(); var err_msg = string.Empty; var server_connect_info = new ServerConnectInfo(); var business_logs = new List(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var server_logic = GameServerApp.getServerLogic(); 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); (result, var instance_room_id) = await InstanceRoomHandler.joinEditRoomInstance(player.getUserGuid()); if (result.isFail()) { err_msg = $"Failed to joinEditRoomInstance() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } 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, null); } result = await instance_room_storage.setInstanceRoomMyhomeGuid(instance_room_id, myhomeGuid); if (result.isFail()) { err_msg = $"Failed to setInstanceRoomMyhomeGuid() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } 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 = player.getUserGuid(); 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, null); } var location_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(location_action, () => $"location action is null !!! - {player.toBasicString()}"); result = await location_action.tryMoveToIndun(instance_room_info); if (result.isFail()) { err_msg = $"Failed to tryMoveToIndun() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } var buff_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(buff_action, () => $"buff action is null !!! - {player.toBasicString()}"); result = await buff_action.MoveServer(EPlaceType.EditRoom); if (result.isFail()) { err_msg = $"Failed to MoveServer() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, null); } (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, null); } var game_login_action = player.getEntityAction(); 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; var start_pos = MapHelper.getWarpPos(ContentsType.EditRoom); var arrival_position_log_info = PositionBusinessLogHelper.toPositionLogInfo(PositionMoveType.Arrival, server_name, instance_room_info.roomId, MapFileType.Instance, instance_room_info.InstanceId, start_pos); var arrival_position_business_log = new PositionBusinessLog(arrival_position_log_info); business_logs.Add(arrival_position_business_log); return (result, server_connect_info, business_logs); } }