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}"); } }); } } }