using System;
using System.Threading.Tasks;
using Unity.Services.Relay;
using Unity.Services.Relay.Allocations;
using Unity.Services.Relay.Models;
using UnityEngine;
namespace LobbyRelaySample.Relay
{
///
/// Does all the interaction with relay.
///
public static class RelayInterface
{
private class InProgressRequest
{
public InProgressRequest(Task task, Action onComplete)
{
DoRequest(task, onComplete);
}
private async void DoRequest(Task task, Action onComplete)
{
T result = default;
string currentTrace = System.Environment.StackTrace;
try {
result = await task;
} catch (Exception e) {
Exception eFull = new Exception($"Call stack before async call:\n{currentTrace}\n", e);
throw eFull;
} finally {
onComplete?.Invoke(result);
}
// TODO: Ensure that passing null as result is handled.
}
}
///
/// Creates a Relay Server, and returns the Allocation (Response.Result.Data.Allocation)
///
///
public static void AllocateAsync(int maxConnections, Action> onComplete)
{
CreateAllocationRequest createAllocationRequest = new CreateAllocationRequest(new AllocationRequest(maxConnections));
var task = RelayService.AllocationsApiClient.CreateAllocationAsync(createAllocationRequest);
new InProgressRequest>(task, onComplete);
}
public static void AllocateAsync(int maxConnections, Action onComplete)
{
AllocateAsync(maxConnections, a =>
{
if (a == null)
Debug.LogError("Relay returned a null Allocation. It's possible the Relay service is currently down.");
else if (a.Status >= 200 && a.Status < 300)
onComplete?.Invoke(a.Result.Data.Allocation);
else
Debug.LogError($"Allocation returned a non Success code: {a.Status}");
});
}
///
/// Get a JoinCode( Response.Result.Data.JoinCode) from an Allocated Server
///
public static void GetJoinCodeAsync(Guid hostAllocationId, Action> onComplete)
{
CreateJoincodeRequest joinCodeRequest = new CreateJoincodeRequest(new JoinCodeRequest(hostAllocationId));
var task = RelayService.AllocationsApiClient.CreateJoincodeAsync(joinCodeRequest);
new InProgressRequest>(task, onComplete);
}
public static void GetJoinCodeAsync(Guid hostAllocationId, Action onComplete)
{
GetJoinCodeAsync(hostAllocationId, a =>
{
if (a.Status >= 200 && a.Status < 300)
onComplete.Invoke(a.Result.Data.JoinCode);
else
{
Debug.LogError($"Join Code Get returned a non Success code: {a.Status}");
}
});
}
///
/// Retrieve an Allocation(Response.Result.Data.Allocation) by join code
///
public static void JoinAsync(string joinCode, Action> onComplete)
{
JoinRelayRequest joinRequest = new JoinRelayRequest(new JoinRequest(joinCode));
var task = RelayService.AllocationsApiClient.JoinRelayAsync(joinRequest);
new InProgressRequest>(task, onComplete);
}
public static void JoinAsync(string joinCode, Action onComplete)
{
JoinAsync(joinCode, a =>
{
if (a.Status >= 200 && a.Status < 300)
onComplete.Invoke(a.Result.Data.Allocation);
else
{
Debug.LogError($"Join Call returned a non Success code: {a.Status}");
}
});
}
}
}