using System; using System.Threading.Tasks; using NitroxClient.Communication.Abstract; using NitroxModel.Helper; using NitroxModel.MultiplayerSession; using NitroxModel.Packets.Exceptions; namespace NitroxClient.Communication.MultiplayerSession.ConnectionState { public class AwaitingSessionReservation : ConnectionNegotiatingState { private readonly string reservationCorrelationId; public AwaitingSessionReservation(string reservationCorrelationId) { Validate.NotNull(reservationCorrelationId); this.reservationCorrelationId = reservationCorrelationId; } public override MultiplayerSessionConnectionStage CurrentStage => MultiplayerSessionConnectionStage.AWAITING_SESSION_RESERVATION; public override Task NegotiateReservationAsync(IMultiplayerSessionConnectionContext sessionConnectionContext) { try { ValidateState(sessionConnectionContext); HandleReservation(sessionConnectionContext); } catch (Exception) { Disconnect(sessionConnectionContext); throw; } return Task.CompletedTask; } private static void HandleReservation(IMultiplayerSessionConnectionContext sessionConnectionContext) { IMultiplayerSessionConnectionState nextState = sessionConnectionContext.Reservation.ReservationState switch { MultiplayerSessionReservationState.RESERVED => new SessionReserved(), _ => new SessionReservationRejected(), }; sessionConnectionContext.UpdateConnectionState(nextState); } private void ValidateState(IMultiplayerSessionConnectionContext sessionConnectionContext) { ReservationIsNotNull(sessionConnectionContext); ReservationPacketIsCorrelated(sessionConnectionContext); } private static void ReservationIsNotNull(IMultiplayerSessionConnectionContext sessionConnectionContext) { try { Validate.NotNull(sessionConnectionContext.Reservation); } catch (ArgumentNullException ex) { throw new InvalidOperationException("The context does not have a reservation.", ex); } } private void ReservationPacketIsCorrelated(IMultiplayerSessionConnectionContext sessionConnectionContext) { if (!reservationCorrelationId.Equals(sessionConnectionContext.Reservation.CorrelationId)) { throw new UncorrelatedPacketException(sessionConnectionContext.Reservation, reservationCorrelationId); } } } }