Files
caliverse_server/GameServer/Contents/GameZone/Action/GameZoneMoveAction.cs
2025-05-01 07:20:41 +09:00

1873 lines
82 KiB
C#

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<Result> onInit()
{
var result = new Result();
return Task.FromResult(result);
}
public override void onClear()
{
return;
}
public async Task<(Result, ServerConnectInfo?, List<ILogInvoker>?)> tryLeaveInstance()
{
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();
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<LocationAttribute>();
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<LocationAction>();
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<BuffAction>();
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<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.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<ILogInvoker>?)> 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<ILogInvoker>();
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<LocationAction>();
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<BuffAction>();
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<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;
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<ILogInvoker>?)> tryWarp(int warpMetaId)
{
var result = new Result();
var err_msg = string.Empty;
var res = new ClientToGameRes.Types.WarpRes();
var business_logs = new List<ILogInvoker>();
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<ILogInvoker>? 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<ILogInvoker>?)> tryTaxi(int taxiMetaId)
{
var result = new Result();
var err_msg = string.Empty;
var res = new ClientToGameRes.Types.TaxiRes();
var business_logs = new List<ILogInvoker>();
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<MoneyAction>();
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<ILogInvoker>? 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<GameZoneAction>();
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<ILogInvoker>?)> tryWarpToChannel(MetaAssets.WarpMetaData warpData)
{
var result = new Result();
var err_msg = string.Empty;
var res = new ClientToGameRes.Types.WarpRes();
var business_logs = new List<ILogInvoker>();
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<LocationAction>();
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<AccountAttribute>();
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<Item>?)> 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<InventoryActionBase>();
(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<ILogInvoker>?)> 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<ILogInvoker>();
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<ILogInvoker>? 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<LocationAction>();
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<ILogInvoker>?)> tryWarpToMyHome(MetaAssets.WarpMetaData warpData)
{
var result = new Result();
var err_msg = string.Empty;
var res = new ClientToGameRes.Types.WarpRes();
var business_logs = new List<ILogInvoker>();
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<ILogInvoker>?)> tryWarpToFittingRoom(MetaAssets.WarpMetaData warpData)
{
var result = new Result();
var err_msg = string.Empty;
var res = new ClientToGameRes.Types.WarpRes();
var business_logs = new List<ILogInvoker>();
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<LocationAction>();
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<BuffAction>();
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<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;
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<ILogInvoker>?)> tryWarpToEditRoom(MetaAssets.WarpMetaData warpData)
{
var result = new Result();
var err_msg = string.Empty;
var res = new ClientToGameRes.Types.WarpRes();
var business_logs = new List<ILogInvoker>();
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<ILogInvoker>?)> tryWarpToReturn(MetaAssets.WarpMetaData warpData)
{
var result = new Result();
var err_msg = string.Empty;
var res = new ClientToGameRes.Types.WarpRes();
var business_logs = new List<ILogInvoker>();
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<LocationAttribute>();
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<LocationAction>();
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<BuffAction>();
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<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;
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<Result> checkRequiredItem(Player player, int itemId, int itemCount)
{
var result = new Result();
var inventory_action = player.getEntityAction<InventoryActionBase>();
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<Result> 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<LocationAttribute>();
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<LocationAction>();
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<BuffAction>();
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<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;
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<ILogInvoker>?)> 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<ILogInvoker>();
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<LocationAction>();
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<BuffAction>();
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<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;
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<ILogInvoker>?)> tryEnterMyhomeEditRoom(string myhomeGuid)
{
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();
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<LocationAction>();
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<BuffAction>();
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<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;
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);
}
}