using GameServer.Contents.GameMode.Helper; using GameServer.Contents.GameMode.Manage.PlayManage; using ServerBase; using ServerCommon; using ServerCore; namespace GameServer.Contents.GameMode.Manage.LeaveManage; public abstract class GameModeLeaveHandlerBase : IGameModeLeaveHandler { protected readonly GameModeType m_game_mode_type; protected Player m_player; protected string m_room_id; public GameModeLeaveHandlerBase(Player player, string roomId, GameModeType gameModeType) { m_game_mode_type = gameModeType; m_player = player; m_room_id = roomId; } public virtual async Task gameModeLeave() { var result = new Result(); if (false == GameModeManager.It.tryGetGameMode(m_room_id, out var gameMode)) { var err_msg = $"battle_instance_room is null : room_id - {m_room_id}"; Log.getLogger().error(err_msg); result.setFail(ServerErrorCode.BattleInstanceInfoNotExist, err_msg); return result; } await removeUserFromInstanceRoom(m_player, gameMode); await leaveGameZone(gameMode); await removeHost(gameMode); result = await postLeave(gameMode); if(result.isFail()) return result; result = await notifyAfterLeave(gameMode); if(result.isFail()) return result; result = await logAfterLeave(gameMode); if(result.isFail()) return result; await destroyCheck(gameMode); return result; } public async Task removeUserFromInstanceRoom(Player player, IGameMode gameMode) { var game_mode_base = GameModeHelper.toGameModeBase(gameMode); await Task.CompletedTask; var instance_room = game_mode_base.getInstanceRoom(); var user_guid = player.getUserGuid(); var result = instance_room.getMap().tryRemovePlayer(player); if (result.isFail()) return; await GameModeHelper.leaveGameInstanceRoom(user_guid, m_room_id); } public async Task removeHost(IGameMode gameMode) { var game_mode_base = GameModeHelper.toGameModeBase(gameMode); var host_user_guid = game_mode_base.m_host_migrator.getHostUserGuid(); if (m_player.getUserGuid().Equals(host_user_guid)) { using (var releaser = await game_mode_base.getAsyncLock()) { game_mode_base.m_host_migrator.removeHost(); } } } public async Task leaveGameZone(IGameMode gameMode) { var game_mode_base = GameModeHelper.toGameModeBase(gameMode); await Task.CompletedTask; var location_attribute = m_player.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"LocationAttribute is null !!! - player:{m_player.toBasicString()}"); location_attribute.CurrentIndunLocation.clear(); var game_zone_action = m_player.getEntityAction(); await game_zone_action.tryLeaveGameZone(); var instance_room = game_mode_base.getInstanceRoom(); if (instance_room.SessionCount + instance_room.getMap().getCurrCountAsAddConnectedUser() > 0) { ClientToGame clientToGame = new ClientToGame(); clientToGame.Message = new ClientToGameMessage(); clientToGame.Message.LeaveInstanceRoomMember = new ClientToGameMessage.Types.LeaveInstanceRoomMember(); clientToGame.Message.LeaveInstanceRoomMember.MemberGuid = m_player.getUserGuid(); instance_room.Broadcast(clientToGame); } } public async Task destroyCheck(IGameMode gameMode) { var game_mode_base = GameModeHelper.toGameModeBase(gameMode); if (game_mode_base.getInstanceRoom().isDestroy) { (var result, var destroy_handler) = GameModeHelper.getGameModeDestroyHandler(game_mode_base.getRoomId()); if (result.isSuccess() && destroy_handler is not null) { await destroy_handler.gameModeDestroy(); } } await Task.CompletedTask; } public abstract Task postLeave(IGameMode gameMode); public abstract Task notifyAfterLeave(IGameMode gameMode); public abstract Task logAfterLeave(IGameMode gameMode); }