86 lines
3.3 KiB
C#
86 lines
3.3 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using NitroxClient.Communication.Abstract;
|
|
using NitroxClient.Communication.Exceptions;
|
|
using NitroxModel.Helper;
|
|
using NitroxModel.Packets;
|
|
|
|
namespace NitroxClient.Communication.MultiplayerSession.ConnectionState
|
|
{
|
|
public class Disconnected : IMultiplayerSessionConnectionState
|
|
{
|
|
public MultiplayerSessionConnectionStage CurrentStage => MultiplayerSessionConnectionStage.DISCONNECTED;
|
|
|
|
public async Task NegotiateReservationAsync(IMultiplayerSessionConnectionContext sessionConnectionContext)
|
|
{
|
|
ValidateState(sessionConnectionContext);
|
|
|
|
IClient client = sessionConnectionContext.Client;
|
|
string ipAddress = sessionConnectionContext.IpAddress;
|
|
int port = sessionConnectionContext.ServerPort;
|
|
await StartClientAsync(ipAddress, client, port);
|
|
EstablishSessionPolicy(sessionConnectionContext, client);
|
|
}
|
|
|
|
private void ValidateState(IMultiplayerSessionConnectionContext sessionConnectionContext)
|
|
{
|
|
ValidateClient(sessionConnectionContext);
|
|
|
|
try
|
|
{
|
|
Validate.NotNull(sessionConnectionContext.IpAddress);
|
|
}
|
|
catch (ArgumentNullException ex)
|
|
{
|
|
throw new InvalidOperationException("The context is missing an IP address.", ex);
|
|
}
|
|
}
|
|
|
|
private static void ValidateClient(IMultiplayerSessionConnectionContext sessionConnectionContext)
|
|
{
|
|
try
|
|
{
|
|
Validate.NotNull(sessionConnectionContext.Client);
|
|
}
|
|
catch (ArgumentNullException ex)
|
|
{
|
|
throw new InvalidOperationException("The client must be set on the connection context before trying to negotiate a session reservation.", ex);
|
|
}
|
|
}
|
|
|
|
private static async Task StartClientAsync(string ipAddress, IClient client, int port)
|
|
{
|
|
if (!client.IsConnected)
|
|
{
|
|
await client.StartAsync(ipAddress, port);
|
|
|
|
if (!client.IsConnected)
|
|
{
|
|
throw new ClientConnectionFailedException("The client failed to connect without providing a reason why.");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void EstablishSessionPolicy(IMultiplayerSessionConnectionContext sessionConnectionContext, IClient client)
|
|
{
|
|
string policyRequestCorrelationId = Guid.NewGuid().ToString();
|
|
|
|
MultiplayerSessionPolicyRequest requestPacket = new MultiplayerSessionPolicyRequest(policyRequestCorrelationId);
|
|
client.Send(requestPacket);
|
|
|
|
EstablishingSessionPolicy nextState = new EstablishingSessionPolicy(policyRequestCorrelationId);
|
|
sessionConnectionContext.UpdateConnectionState(nextState);
|
|
}
|
|
|
|
public void JoinSession(IMultiplayerSessionConnectionContext sessionConnectionContext)
|
|
{
|
|
throw new InvalidOperationException("Cannot join a session until a reservation has been negotiated with the server.");
|
|
}
|
|
|
|
public void Disconnect(IMultiplayerSessionConnectionContext sessionConnectionContext)
|
|
{
|
|
throw new InvalidOperationException("Not connected to a multiplayer server.");
|
|
}
|
|
}
|
|
}
|