浏览代码

Package update and library source changes.

/main/staging/closed_beta_package_update
当前提交
0657af8f
共有 69 个文件被更改,包括 1621 次插入300 次删除
  1. 1
      Assets/Scripts/Lobby/LobbyAPIInterface.cs
  2. 14
      Packages/com.unity.services.lobby/CHANGELOG.md
  3. 97
      Packages/com.unity.services.lobby/Runtime/Apis/LobbyApi.cs
  4. 7
      Packages/com.unity.services.lobby/Runtime/Apis/LobbyApiRequests.cs
  5. 12
      Packages/com.unity.services.lobby/Runtime/Configuration/Configuration.cs
  6. 4
      Packages/com.unity.services.lobby/Runtime/Http/JsonObject.cs
  7. 4
      Packages/com.unity.services.lobby/Runtime/LobbyService.cs
  8. 16
      Packages/com.unity.services.lobby/Runtime/LobbyServiceProvider.cs
  9. 44
      Packages/com.unity.services.lobby/package.json
  10. 15
      Packages/com.unity.services.relay/CHANGELOG.md
  11. 41
      Packages/com.unity.services.relay/Runtime/Apis/AllocationsApi.cs
  12. 104
      Packages/com.unity.services.relay/Runtime/Apis/AllocationsApiRequests.cs
  13. 12
      Packages/com.unity.services.relay/Runtime/Configuration/Configuration.cs
  14. 4
      Packages/com.unity.services.relay/Runtime/Http/BaseApiClient.cs
  15. 14
      Packages/com.unity.services.relay/Runtime/Http/DeserializationException.cs
  16. 54
      Packages/com.unity.services.relay/Runtime/Http/HttpClient.cs
  17. 13
      Packages/com.unity.services.relay/Runtime/Http/HttpException.cs
  18. 5
      Packages/com.unity.services.relay/Runtime/Http/IHttpClient.cs
  19. 4
      Packages/com.unity.services.relay/Runtime/Http/JsonHelpers.cs
  20. 58
      Packages/com.unity.services.relay/Runtime/Http/ResponseHandler.cs
  21. 25
      Packages/com.unity.services.relay/Runtime/Models/AllocateResponseBody.cs
  22. 49
      Packages/com.unity.services.relay/Runtime/Models/Allocation.cs
  23. 9
      Packages/com.unity.services.relay/Runtime/Models/AllocationData.cs
  24. 26
      Packages/com.unity.services.relay/Runtime/Models/AllocationRequest.cs
  25. 26
      Packages/com.unity.services.relay/Runtime/Models/ErrorResponseBody.cs
  26. 57
      Packages/com.unity.services.relay/Runtime/Models/JoinAllocation.cs
  27. 14
      Packages/com.unity.services.relay/Runtime/Models/JoinAllocationAllOf.cs
  28. 14
      Packages/com.unity.services.relay/Runtime/Models/JoinCodeData.cs
  29. 14
      Packages/com.unity.services.relay/Runtime/Models/JoinCodeRequest.cs
  30. 11
      Packages/com.unity.services.relay/Runtime/Models/JoinCodeResponseBody.cs
  31. 9
      Packages/com.unity.services.relay/Runtime/Models/JoinData.cs
  32. 14
      Packages/com.unity.services.relay/Runtime/Models/JoinRequest.cs
  33. 10
      Packages/com.unity.services.relay/Runtime/Models/JoinResponseBody.cs
  34. 10
      Packages/com.unity.services.relay/Runtime/Models/KeyValuePair.cs
  35. 20
      Packages/com.unity.services.relay/Runtime/Models/RelayServer.cs
  36. 37
      Packages/com.unity.services.relay/Runtime/Models/RelayServerEndpoint.cs
  37. 14
      Packages/com.unity.services.relay/Runtime/Models/ResponseLinks.cs
  38. 20
      Packages/com.unity.services.relay/Runtime/Models/ResponseMeta.cs
  39. 2
      Packages/com.unity.services.relay/Runtime/RelayService.cs
  40. 19
      Packages/com.unity.services.relay/Runtime/RelayServiceProvider.cs
  41. 4
      Packages/com.unity.services.relay/Runtime/Scheduler/ThreadHelper.cs
  42. 14
      Packages/com.unity.services.relay/package.json
  43. 4
      Packages/packages-lock.json
  44. 76
      Packages/com.unity.services.lobby/Third Party Notices.md
  45. 7
      Packages/com.unity.services.lobby/Third Party Notices.md.meta
  46. 15
      Packages/com.unity.services.relay/Runtime/Http/DeserializationSettings.cs
  47. 11
      Packages/com.unity.services.relay/Runtime/Http/DeserializationSettings.cs.meta
  48. 53
      Packages/com.unity.services.relay/Runtime/Http/JsonObject.cs
  49. 11
      Packages/com.unity.services.relay/Runtime/Http/JsonObject.cs.meta
  50. 28
      Packages/com.unity.services.relay/Runtime/Http/JsonObjectConverter.cs
  51. 11
      Packages/com.unity.services.relay/Runtime/Http/JsonObjectConverter.cs.meta
  52. 34
      Packages/com.unity.services.relay/Runtime/Http/ResponseDeserializationException.cs
  53. 11
      Packages/com.unity.services.relay/Runtime/Http/ResponseDeserializationException.cs.meta
  54. 52
      Packages/com.unity.services.relay/Runtime/Models/Region.cs
  55. 11
      Packages/com.unity.services.relay/Runtime/Models/Region.cs.meta
  56. 42
      Packages/com.unity.services.relay/Runtime/Models/RegionsData.cs
  57. 11
      Packages/com.unity.services.relay/Runtime/Models/RegionsData.cs.meta
  58. 39
      Packages/com.unity.services.relay/Runtime/Models/RegionsResponseBody.cs
  59. 11
      Packages/com.unity.services.relay/Runtime/Models/RegionsResponseBody.cs.meta
  60. 76
      Packages/com.unity.services.relay/Third Party Notices.md
  61. 7
      Packages/com.unity.services.relay/Third Party Notices.md.meta
  62. 8
      Packages/com.unity.services.lobby/Samples~/HelloWorld.meta
  63. 5
      Packages/com.unity.services.lobby/Samples~/HelloWorld/.sample.json
  64. 430
      Packages/com.unity.services.lobby/Samples~/HelloWorld/LobbyHelloWorld.cs
  65. 11
      Packages/com.unity.services.lobby/Samples~/HelloWorld/LobbyHelloWorld.cs.meta
  66. 9
      Packages/com.unity.services.lobby/CONTRIBUTING.md
  67. 7
      Packages/com.unity.services.lobby/CONTRIBUTING.md.meta

1
Assets/Scripts/Lobby/LobbyAPIInterface.cs


using System.Collections.Generic;
using System.Threading.Tasks;
using Unity.Services.Lobbies;
using Unity.Services.Lobbies.Lobby;
using Unity.Services.Lobbies.Models;
namespace LobbyRelaySample.lobby

14
Packages/com.unity.services.lobby/CHANGELOG.md


# Changelog
## [1.0.0-pre.2] - 2021-08-06
* Update `com.unity.services.core` dependency to latest `1.1.0-pre.4`
## [1.0.0-pre.1] - 2021-07-30
* Re-version in preparation for Open Beta.
Regenerate after adding Heartbeat API.
* Add Heartbeat API.
* Update with latest HTTP code.
Add preview tag.
* Add preview tag.
## [0.2.0] - 2021-07-06

97
Packages/com.unity.services.lobby/Runtime/Apis/LobbyApi.cs


using Unity.Services.Lobbies.Http;
using TaskScheduler = Unity.Services.Lobbies.Scheduler.TaskScheduler;
using Unity.Services.Authentication;
using Unity.Services.Lobbies;
using Unity.Services.Lobbies.Lobby;
namespace Unity.Services.Lobbies.Apis
namespace Unity.Services.Lobbies.Apis.Lobby
{
public interface ILobbyApiClient
{

/// <param name="operationConfiguration">Configuration for CreateLobby</param>
/// <returns>Task for a Response object containing status code, headers, and Lobby object</returns>
/// <exception cref="Unity.Services.Lobbies.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<Lobby>> CreateLobbyAsync(CreateLobbyRequest request, Configuration operationConfiguration = null);
Task<Response<Models.Lobby>> CreateLobbyAsync(CreateLobbyRequest request, Configuration operationConfiguration = null);
/// <summary>
/// Async Operation.

/// <param name="operationConfiguration">Configuration for GetLobby</param>
/// <returns>Task for a Response object containing status code, headers, and Lobby object</returns>
/// <exception cref="Unity.Services.Lobbies.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<Lobby>> GetLobbyAsync(GetLobbyRequest request, Configuration operationConfiguration = null);
Task<Response<Models.Lobby>> GetLobbyAsync(GetLobbyRequest request, Configuration operationConfiguration = null);
/// <summary>
/// Async Operation.

/// <param name="operationConfiguration">Configuration for JoinLobbyByCode</param>
/// <returns>Task for a Response object containing status code, headers, and Lobby object</returns>
/// <exception cref="Unity.Services.Lobbies.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<Lobby>> JoinLobbyByCodeAsync(JoinLobbyByCodeRequest request, Configuration operationConfiguration = null);
Task<Response<Models.Lobby>> JoinLobbyByCodeAsync(JoinLobbyByCodeRequest request, Configuration operationConfiguration = null);
/// <summary>
/// Async Operation.

/// <param name="operationConfiguration">Configuration for JoinLobbyById</param>
/// <returns>Task for a Response object containing status code, headers, and Lobby object</returns>
/// <exception cref="Unity.Services.Lobbies.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<Lobby>> JoinLobbyByIdAsync(JoinLobbyByIdRequest request, Configuration operationConfiguration = null);
Task<Response<Models.Lobby>> JoinLobbyByIdAsync(JoinLobbyByIdRequest request, Configuration operationConfiguration = null);
/// <summary>
/// Async Operation.

/// <param name="operationConfiguration">Configuration for QuickJoinLobby</param>
/// <returns>Task for a Response object containing status code, headers, and Lobby object</returns>
/// <exception cref="Unity.Services.Lobbies.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<Lobby>> QuickJoinLobbyAsync(QuickJoinLobbyRequest request, Configuration operationConfiguration = null);
Task<Response<Models.Lobby>> QuickJoinLobbyAsync(QuickJoinLobbyRequest request, Configuration operationConfiguration = null);
/// <summary>
/// Async Operation.

/// <param name="operationConfiguration">Configuration for UpdateLobby</param>
/// <returns>Task for a Response object containing status code, headers, and Lobby object</returns>
/// <exception cref="Unity.Services.Lobbies.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<Lobby>> UpdateLobbyAsync(UpdateLobbyRequest request, Configuration operationConfiguration = null);
Task<Response<Models.Lobby>> UpdateLobbyAsync(UpdateLobbyRequest request, Configuration operationConfiguration = null);
/// <summary>
/// Async Operation.

/// <param name="operationConfiguration">Configuration for UpdatePlayer</param>
/// <returns>Task for a Response object containing status code, headers, and Lobby object</returns>
/// <exception cref="Unity.Services.Lobbies.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<Lobby>> UpdatePlayerAsync(UpdatePlayerRequest request, Configuration operationConfiguration = null);
Task<Response<Models.Lobby>> UpdatePlayerAsync(UpdatePlayerRequest request, Configuration operationConfiguration = null);
}

private IAccessToken _accessToken;
private const int _baseTimeout = 10;
private Configuration _configuration;
public Configuration Configuration
{

_accessToken = accessToken;
}
public async Task<Response<Lobby>> CreateLobbyAsync(CreateLobbyRequest request,
public async Task<Response<Models.Lobby>> CreateLobbyAsync(CreateLobbyRequest request,
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "201", typeof(Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) } };
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "201", typeof(Models.Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) } };
// Merge the operation/request level configuration with the client level configuration.
var finalConfiguration = Configuration.MergeConfigurations(operationConfiguration, Configuration);

request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<Lobby>(response, statusCodeToTypeMap);
return new Response<Lobby>(response, handledResponse);
var handledResponse = ResponseHandler.HandleAsyncResponse<Models.Lobby>(response, statusCodeToTypeMap);
return new Response<Models.Lobby>(response, handledResponse);
}
public async Task<Response> DeleteLobbyAsync(DeleteLobbyRequest request,

request.ConstructUrl(finalConfiguration.BasePath),
request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
public async Task<Response<Lobby>> GetLobbyAsync(GetLobbyRequest request,
public async Task<Response<Models.Lobby>> GetLobbyAsync(GetLobbyRequest request,
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) } };
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Models.Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) } };
// Merge the operation/request level configuration with the client level configuration.
var finalConfiguration = Configuration.MergeConfigurations(operationConfiguration, Configuration);

request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<Lobby>(response, statusCodeToTypeMap);
return new Response<Lobby>(response, handledResponse);
var handledResponse = ResponseHandler.HandleAsyncResponse<Models.Lobby>(response, statusCodeToTypeMap);
return new Response<Models.Lobby>(response, handledResponse);
}
public async Task<Response> HeartbeatAsync(HeartbeatRequest request,

request.ConstructUrl(finalConfiguration.BasePath),
request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
public async Task<Response<Lobby>> JoinLobbyByCodeAsync(JoinLobbyByCodeRequest request,
public async Task<Response<Models.Lobby>> JoinLobbyByCodeAsync(JoinLobbyByCodeRequest request,
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "409", typeof(ErrorStatus) } };
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Models.Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "409", typeof(ErrorStatus) } };
// Merge the operation/request level configuration with the client level configuration.
var finalConfiguration = Configuration.MergeConfigurations(operationConfiguration, Configuration);

request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<Lobby>(response, statusCodeToTypeMap);
return new Response<Lobby>(response, handledResponse);
var handledResponse = ResponseHandler.HandleAsyncResponse<Models.Lobby>(response, statusCodeToTypeMap);
return new Response<Models.Lobby>(response, handledResponse);
public async Task<Response<Lobby>> JoinLobbyByIdAsync(JoinLobbyByIdRequest request,
public async Task<Response<Models.Lobby>> JoinLobbyByIdAsync(JoinLobbyByIdRequest request,
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) },{ "409", typeof(ErrorStatus) } };
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Models.Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) },{ "409", typeof(ErrorStatus) } };
// Merge the operation/request level configuration with the client level configuration.
var finalConfiguration = Configuration.MergeConfigurations(operationConfiguration, Configuration);

request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<Lobby>(response, statusCodeToTypeMap);
return new Response<Lobby>(response, handledResponse);
var handledResponse = ResponseHandler.HandleAsyncResponse<Models.Lobby>(response, statusCodeToTypeMap);
return new Response<Models.Lobby>(response, handledResponse);
}
public async Task<Response<QueryResponse>> QueryLobbiesAsync(QueryLobbiesRequest request,

request.ConstructUrl(finalConfiguration.BasePath),
request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
public async Task<Response<Lobby>> QuickJoinLobbyAsync(QuickJoinLobbyRequest request,
public async Task<Response<Models.Lobby>> QuickJoinLobbyAsync(QuickJoinLobbyRequest request,
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) },{ "409", typeof(ErrorStatus) } };
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Models.Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) },{ "409", typeof(ErrorStatus) } };
// Merge the operation/request level configuration with the client level configuration.
var finalConfiguration = Configuration.MergeConfigurations(operationConfiguration, Configuration);

request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<Lobby>(response, statusCodeToTypeMap);
return new Response<Lobby>(response, handledResponse);
var handledResponse = ResponseHandler.HandleAsyncResponse<Models.Lobby>(response, statusCodeToTypeMap);
return new Response<Models.Lobby>(response, handledResponse);
}
public async Task<Response> RemovePlayerAsync(RemovePlayerRequest request,

request.ConstructUrl(finalConfiguration.BasePath),
request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
public async Task<Response<Lobby>> UpdateLobbyAsync(UpdateLobbyRequest request,
public async Task<Response<Models.Lobby>> UpdateLobbyAsync(UpdateLobbyRequest request,
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) } };
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Models.Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) } };
// Merge the operation/request level configuration with the client level configuration.
var finalConfiguration = Configuration.MergeConfigurations(operationConfiguration, Configuration);

request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<Lobby>(response, statusCodeToTypeMap);
return new Response<Lobby>(response, handledResponse);
var handledResponse = ResponseHandler.HandleAsyncResponse<Models.Lobby>(response, statusCodeToTypeMap);
return new Response<Models.Lobby>(response, handledResponse);
public async Task<Response<Lobby>> UpdatePlayerAsync(UpdatePlayerRequest request,
public async Task<Response<Models.Lobby>> UpdatePlayerAsync(UpdatePlayerRequest request,
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) } };
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(Models.Lobby) },{ "400", typeof(ErrorStatus) },{ "403", typeof(ErrorStatus) },{ "404", typeof(ErrorStatus) } };
// Merge the operation/request level configuration with the client level configuration.
var finalConfiguration = Configuration.MergeConfigurations(operationConfiguration, Configuration);

request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<Lobby>(response, statusCodeToTypeMap);
return new Response<Lobby>(response, handledResponse);
var handledResponse = ResponseHandler.HandleAsyncResponse<Models.Lobby>(response, statusCodeToTypeMap);
return new Response<Models.Lobby>(response, handledResponse);
}
}

7
Packages/com.unity.services.lobby/Runtime/Apis/LobbyApiRequests.cs


using Unity.Services.Lobbies.Models;
using Unity.Services.Authentication;
namespace Unity.Services.Lobbies
namespace Unity.Services.Lobbies.Lobby
{
internal static class JsonSerialization
{

[Preserve]
public List<string> AddParamsToQueryParams<T>(List<string> queryParams, string key, T value)
{
if (queryParams == null)
{
queryParams = new List<string>();
}
key = UnityWebRequest.EscapeURL(key);
string valueString = UnityWebRequest.EscapeURL(value.ToString());
queryParams.Add($"{key}={valueString}");

12
Packages/com.unity.services.lobby/Runtime/Configuration/Configuration.cs


public class Configuration
{
public string BasePath;
public int RequestTimeout;
public int NumberOfRetries;
public int? RequestTimeout;
public int? NumberOfRetries;
public Configuration(string basePath, int requestTimeout, int numRetries, IDictionary<string, string> headers)
public Configuration(string basePath, int? requestTimeout, int? numRetries, IDictionary<string, string> headers)
{
BasePath = basePath;
RequestTimeout = requestTimeout;

}
}
mergedConfig.Headers = headers;
mergedConfig.Headers = headers;
mergedConfig.RequestTimeout = mergedConfig.RequestTimeout ?? b.RequestTimeout;
mergedConfig.NumberOfRetries = mergedConfig.NumberOfRetries ?? b.NumberOfRetries;
return mergedConfig;
}

4
Packages/com.unity.services.lobby/Runtime/Http/JsonObject.cs


{
return JsonConvert.SerializeObject(obj);
}
catch (System.Exception e)
catch (System.Exception)
{
throw new System.Exception("Failed to convert JsonObject to string.");
}

{
throw new DeserializationException(e.Message);
}
catch (System.Exception e)
catch (System.Exception)
{
throw new DeserializationException("Unable to deserialize object.");
}

4
Packages/com.unity.services.lobby/Runtime/LobbyService.cs


using Unity.Services.Lobbies.Apis;
using Unity.Services.Lobbies.Apis.Lobby;
namespace Unity.Services.Lobbies

/// </summary>
public static ILobbyApiClient LobbyApiClient { get; internal set; }
public static Configuration Configuration = new Configuration("https://lobby.cloud.unity3d.com/v1", 10, 4, null);
public static Configuration Configuration = new Configuration("https://lobby.services.api.unity.com/v1", 10, 4, null);
}
}

16
Packages/com.unity.services.lobby/Runtime/LobbyServiceProvider.cs


using UnityEngine;
using System.Threading.Tasks;
using Unity.Services.Lobbies.Apis;
using Unity.Services.Lobbies.Apis.Lobby;
using TaskScheduler = Unity.Services.Lobbies.Scheduler.TaskScheduler;
using Unity.Services.Core;
using Unity.Services.Authentication;

{
// Pass an instance of this class to Core
var generatedPackageRegistry =
CoreRegistry.Instance.RegisterPackage(new LobbyServiceProvider());
// And specify what components it requires, or provides.
CoreRegistry.Instance.RegisterPackage(new LobbyServiceProvider());
// And specify what components it requires, or provides.
;
;
}
public Task Initialize(CoreRegistry registry)

var accessTokenLobbyApi = registry.GetServiceComponent<IAccessToken>();
if (accessTokenLobbyApi != null)

return Task.CompletedTask;
}
}

44
Packages/com.unity.services.lobby/package.json


{
"name": "com.unity.services.lobby",
"displayName":"Unity Lobby",
"version": "0.2.1-preview",
"unity": "2020.3",
"description": "Client API SDK Package for communicating with the Unity Lobby service",
"dependencies": {
"com.unity.services.core": "1.1.0-pre.2",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.nuget.newtonsoft-json": "2.0.0"
"name": "com.unity.services.lobby",
"displayName": "Lobby",
"version": "1.0.0-pre.2",
"unity": "2020.3",
"description": "Enable players to find, create, and join lobbies with Lobby. Add Lobby to your multiplayer game to empower players to create the gaming experiences they want. Features include Quick Join, Public Lobby, and Private Match to allow flexibility in how players want to game with each other.",
"dependencies": {
"com.unity.services.core": "1.1.0-pre.4",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.nuget.newtonsoft-json": "2.0.0"
},
"relatedPackages": {
"com.unity.services.lobby.tests": "1.0.0-pre.2"
},
"upmCi": {
"footprint": "81d7a8922f15a5246bfe1dd090a8fe34920efa5f"
},
"repository": {
"url": "https://github.cds.internal.unity3d.com/unity/com.unity.services.rooms.git",
"type": "git",
"revision": "d1b949fb990f301ebd08a2a7dfe4e1a8489e3a20"
},
"samples": [
{
"displayName": "Hello World Sample",
"description": "This sample walks through using most of the Lobby APIs in a simple, linear way.",
"path": "Samples~/HelloWorld"
]
}

15
Packages/com.unity.services.relay/CHANGELOG.md


# Changelog
## [1.0.0-pre.3] - 2021-08-06
* Updates to latest version of Relay Service API
* Multi-region support
## [1.0.0-pre.2] - 2021-07-30
* Update Third Party Notices
* Update package description
* Use generator version `v0.4.0`
* uses `com.unity.services.core` `v1.1.0-pre.4`
* allows compatibility with `com.unity.services.authentication` `v0.7.1`
* Adds `ListRegions`
* `CreateAllocationAsync` takes optional argument `region`
## [0.0.1-preview.9] - 2021-07-07
* Update documentation, points to dashboard

41
Packages/com.unity.services.relay/Runtime/Apis/AllocationsApi.cs


/// Create Allocation
/// </summary>
/// <param name="request">Request object for CreateAllocation</param>
/// <param name="operationConfiguration">Configuration for CreateAllocation</param>
/// <returns>Task for a Response object containing status code, headers, and AllocateResponseBody object</returns>
/// <exception cref="Unity.Services.Relay.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<AllocateResponseBody>> CreateAllocationAsync(CreateAllocationRequest request, Configuration operationConfiguration = null);

/// Create Join Code
/// </summary>
/// <param name="request">Request object for CreateJoincode</param>
/// <param name="operationConfiguration">Configuration for CreateJoincode</param>
/// <returns>Task for a Response object containing status code, headers, and JoinCodeResponseBody object</returns>
/// <exception cref="Unity.Services.Relay.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<JoinCodeResponseBody>> CreateJoincodeAsync(CreateJoincodeRequest request, Configuration operationConfiguration = null);

/// Join Relay
/// </summary>
/// <param name="request">Request object for JoinRelay</param>
/// <param name="operationConfiguration">Configuration for JoinRelay</param>
/// <summary>
/// Async Operation.
/// List relay regions
/// </summary>
/// <param name="request">Request object for ListRegions</param>
/// <param name="operationConfiguration">Configuration for ListRegions</param>
/// <returns>Task for a Response object containing status code, headers, and RegionsResponseBody object</returns>
/// <exception cref="Unity.Services.Relay.Http.HttpException">An exception containing the HttpClientResponse with headers, response code, and string of error.</exception>
Task<Response<RegionsResponseBody>> ListRegionsAsync(ListRegionsRequest request, Configuration operationConfiguration = null);
}
///<inheritdoc cref="IAllocationsApiClient"/>

private const int _baseTimeout = 10;
private Configuration _configuration;
public Configuration Configuration
{

}
public AllocationsApiClient(IHttpClient httpClient,
TaskScheduler taskScheduler,
Configuration configuration = null) : base(httpClient, taskScheduler)
Configuration configuration = null) : base(httpClient)
{
// We don't need to worry about the configuration being null at
// this stage, we will check this in the accessor.

request.ConstructUrl(finalConfiguration.BasePath),
request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<AllocateResponseBody>(response, statusCodeToTypeMap);
return new Response<AllocateResponseBody>(response, handledResponse);

request.ConstructUrl(finalConfiguration.BasePath),
request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<JoinCodeResponseBody>(response, statusCodeToTypeMap);
return new Response<JoinCodeResponseBody>(response, handledResponse);

request.ConstructUrl(finalConfiguration.BasePath),
request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout);
finalConfiguration.RequestTimeout ?? _baseTimeout);
}
public async Task<Response<RegionsResponseBody>> ListRegionsAsync(ListRegionsRequest request,
Configuration operationConfiguration = null)
{
var statusCodeToTypeMap = new Dictionary<string, System.Type>() { { "200", typeof(RegionsResponseBody) },{ "400", typeof(ErrorResponseBody) },{ "401", typeof(ErrorResponseBody) },{ "403", typeof(ErrorResponseBody) },{ "500", typeof(ErrorResponseBody) } };
// Merge the operation/request level configuration with the client level configuration.
var finalConfiguration = Configuration.MergeConfigurations(operationConfiguration, Configuration);
var response = await HttpClient.MakeRequestAsync("GET",
request.ConstructUrl(finalConfiguration.BasePath),
request.ConstructBody(),
request.ConstructHeaders(_accessToken, finalConfiguration),
finalConfiguration.RequestTimeout ?? _baseTimeout);
var handledResponse = ResponseHandler.HandleAsyncResponse<RegionsResponseBody>(response, statusCodeToTypeMap);
return new Response<RegionsResponseBody>(response, handledResponse);
}
}

104
Packages/com.unity.services.relay/Runtime/Apis/AllocationsApiRequests.cs


using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Unity.Services.Relay.Http;
using UnityEngine;
using UnityEngine.Networking;
using Unity.Services.Relay.Models;

key = UnityWebRequest.EscapeURL(key);
value = UnityWebRequest.EscapeURL(value);
queryParams.Add($"{key}={value}");
public List<string> AddParamsToQueryParams(List<string> queryParams, string key, List<string> values)
public List<string> AddParamsToQueryParams(List<string> queryParams, string key, List<string> values, string style, bool explode)
foreach(var value in values)
if (explode)
string escapedValue = UnityWebRequest.EscapeURL(value);
queryParams.Add($"{UnityWebRequest.EscapeURL(key)}[]={escapedValue}");
foreach(var value in values)
{
string escapedValue = UnityWebRequest.EscapeURL(value);
queryParams.Add($"{UnityWebRequest.EscapeURL(key)}={escapedValue}");
}
}
else
{
string paramString = $"{UnityWebRequest.EscapeURL(key)}=";
foreach(var value in values)
{
paramString += UnityWebRequest.EscapeURL(value) + ",";
}
paramString = paramString.Remove(paramString.Length - 1);
queryParams.Add(paramString);
return queryParams;
}

if (queryParams == null)
{
queryParams = new List<string>();
}
key = UnityWebRequest.EscapeURL(key);
string valueString = UnityWebRequest.EscapeURL(value.ToString());
queryParams.Add($"{key}={valueString}");

string[] contentTypes = {
"application/json"
};
string[] accepts = {
"application/json",
"application/problem+json"
};
var acceptHeader = GenerateAcceptHeader(accepts);
if (!string.IsNullOrEmpty(acceptHeader))
{
headers.Add("Accept", acceptHeader);
}
var contentTypeHeader = GenerateContentTypeHeader(contentTypes);
if (!string.IsNullOrEmpty(contentTypeHeader))
{
headers.Add("Content-Type", contentTypeHeader);
}
// We also check if there are headers that are defined as part of
// the request configuration.
if (operationConfiguration != null && operationConfiguration.Headers != null)
{
foreach (var pair in operationConfiguration.Headers)
{
headers[pair.Key] = pair.Value;
}
}
return headers;
}
}
[Preserve]
public class ListRegionsRequest : AllocationsApiBaseRequest
{
string PathAndQueryParams;
/// <summary>
/// ListRegions Request Object.
/// List relay regions
/// </summary>
/// <returns>A ListRegions request object.</returns>
[Preserve]
public ListRegionsRequest()
{
PathAndQueryParams = $"/v1/regions";
List<string> queryParams = new List<string>();
if (queryParams.Count > 0)
{
PathAndQueryParams = $"{PathAndQueryParams}?{string.Join("&", queryParams)}";
}
}
public string ConstructUrl(string requestBasePath)
{
return requestBasePath + PathAndQueryParams;
}
public byte[] ConstructBody()
{
return null;
}
public Dictionary<string, string> ConstructHeaders(IAccessToken accessToken,
Configuration operationConfiguration = null)
{
var headers = new Dictionary<string, string>();
if(!string.IsNullOrEmpty(accessToken.AccessToken))
{
headers.Add("authorization", "Bearer " + accessToken.AccessToken);
}
string[] contentTypes = {
};
string[] accepts = {

12
Packages/com.unity.services.relay/Runtime/Configuration/Configuration.cs


public class Configuration
{
public string BasePath;
public int RequestTimeout;
public int NumberOfRetries;
public int? RequestTimeout;
public int? NumberOfRetries;
public Configuration(string basePath, int requestTimeout, int numRetries, IDictionary<string, string> headers)
public Configuration(string basePath, int? requestTimeout, int? numRetries, IDictionary<string, string> headers)
{
BasePath = basePath;
RequestTimeout = requestTimeout;

}
}
mergedConfig.Headers = headers;
mergedConfig.Headers = headers;
mergedConfig.RequestTimeout = mergedConfig.RequestTimeout ?? b.RequestTimeout;
mergedConfig.NumberOfRetries = mergedConfig.NumberOfRetries ?? b.NumberOfRetries;
return mergedConfig;
}

4
Packages/com.unity.services.relay/Runtime/Http/BaseApiClient.cs


{
protected readonly IHttpClient HttpClient;
public BaseApiClient(IHttpClient httpClient, TaskScheduler scheduler)
public BaseApiClient(IHttpClient httpClient)
HttpClient = httpClient ?? new HttpClient(scheduler);
HttpClient = httpClient ?? new HttpClient();
}
}
}

14
Packages/com.unity.services.relay/Runtime/Http/DeserializationException.cs


[Serializable]
public class DeserializationException : Exception
{
public HttpClientResponse response;
public DeserializationException() : base()
{
}

DeserializationException(string message, Exception inner) : base(message, inner)
{
}
public DeserializationException(HttpClientResponse httpClientResponse) : base(
"Unable to Deserialize Http Client Response")
{
response = httpClientResponse;
}
public DeserializationException(HttpClientResponse httpClientResponse, string message) : base(
message)
{
response = httpClientResponse;
}
}
}

54
Packages/com.unity.services.relay/Runtime/Http/HttpClient.cs


};
private static readonly List<int> ErrorCodes = new List<int> {408, 500, 502, 503, 504};
private TaskScheduler _scheduler;
public HttpClient(TaskScheduler scheduler)
{
_scheduler = scheduler;
}
public void Get(string url, Dictionary<string, string> headers, Action<HttpClientResponse> onCompleted,
int requestTimeout = 10)
{
_scheduler.ScheduleMainThreadTask(() =>
{
_scheduler.StartCoroutine(ProcessRequest(UnityWebRequest.kHttpVerbGET, url, headers, null,
requestTimeout, onCompleted));
});
}
public void Delete(string url, Dictionary<string, string> headers, Action<HttpClientResponse> onCompleted,
int requestTimeout = 10)
{
_scheduler.ScheduleMainThreadTask(() =>
{
_scheduler.StartCoroutine(ProcessRequest(UnityWebRequest.kHttpVerbDELETE, url, headers, null,
requestTimeout, onCompleted));
});
}
public void Post(string url, byte[] body, Dictionary<string, string> headers,
Action<HttpClientResponse> onCompleted, int requestTimeout = 10)
{
_scheduler.ScheduleMainThreadTask(() =>
{
_scheduler.StartCoroutine(ProcessRequest(UnityWebRequest.kHttpVerbPOST, url, headers, body,
requestTimeout, onCompleted));
});
}
public void Put(string url, byte[] body, Dictionary<string, string> headers,
Action<HttpClientResponse> onCompleted, int requestTimeout = 10)
public HttpClient()
_scheduler.ScheduleMainThreadTask(() =>
{
_scheduler.StartCoroutine(ProcessRequest(UnityWebRequest.kHttpVerbPUT, url, headers, body,
requestTimeout, onCompleted));
});
}
public void MakeRequest(string method, string url, byte[] body, Dictionary<string, string> headers,
Action<HttpClientResponse> onCompleted, int requestTimeout = 10)
{
_scheduler.ScheduleMainThreadTask(() =>
{
_scheduler.StartCoroutine(ProcessRequest(method.ToUpper(), url, headers, body, requestTimeout,
onCompleted));
});
}
public async Task<HttpClientResponse> MakeRequestAsync(string method, string url, byte[] body,

13
Packages/com.unity.services.relay/Runtime/Http/HttpException.cs


using System;
using UnityEngine.Scripting;
[Preserve]
[Preserve]
[Preserve]
[Preserve]
[Preserve]
[Preserve]
public HttpException(HttpClientResponse response) : base(response.ErrorMessage)
{
Response = response;

[Serializable]
[Preserve]
[Preserve]
[Preserve]
[Preserve]
[Preserve]
[Preserve]
public HttpException(HttpClientResponse response, T actualError) : base(response)
{
ActualError = actualError;

5
Packages/com.unity.services.relay/Runtime/Http/IHttpClient.cs


{
public interface IHttpClient
{
void Get(string url, Dictionary<string, string> headers, Action<HttpClientResponse> onCompleted, int requestTimeout = 10);
void Delete(string url, Dictionary<string, string> headers, Action<HttpClientResponse> onCompleted, int requestTimeout = 10);
void Post(string url, byte[] body, Dictionary<string, string> headers, Action<HttpClientResponse> onCompleted, int requestTimeout = 10);
void Put(string url, byte[] body, Dictionary<string, string> headers, Action<HttpClientResponse> onCompleted, int requestTimeout = 10);
void MakeRequest(string method, string url, byte[] body, Dictionary<string, string> headers, Action<HttpClientResponse> onCompleted, int requestTimeout = 10);
Task<HttpClientResponse> MakeRequestAsync(string method, string url, byte[] body, Dictionary<string, string> headers, int requestTimeout);
Task<HttpClientResponse> MakeRequestAsync(string method, string url, List<IMultipartFormSection> body, Dictionary<string, string> headers, int requestTimeout, string boundary = null);
}

4
Packages/com.unity.services.relay/Runtime/Http/JsonHelpers.cs


using Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Utilities;
using UnityEngine;

success = false;
args.ErrorContext.Handled = true;
},
MissingMemberHandling = MissingMemberHandling.Ignore
MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore
};
result = JsonConvert.DeserializeObject<T>(@this, settings);
return success;

58
Packages/com.unity.services.relay/Runtime/Http/ResponseHandler.cs


{
var settings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Ignore
MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore
return JsonConvert.DeserializeObject<T>(GetDeserializardJson(response.Data), settings);
return JsonConvert.DeserializeObject<T>(GetDeserializedJson(response.Data), settings);
}
public static object TryDeserializeResponse(HttpClientResponse response, Type type)

MissingMemberHandling = MissingMemberHandling.Ignore
MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore
return JsonConvert.DeserializeObject(GetDeserializardJson(response.Data), type, settings);
return JsonConvert.DeserializeObject(GetDeserializedJson(response.Data), type, settings);
private static string GetDeserializardJson(byte[] data)
private static string GetDeserializedJson(byte[] data)
{
return Encoding.UTF8.GetString(data);
}

}
catch (ArgumentException e)
{
throw new DeserializationException(response, e.Message);
throw new ResponseDeserializationException(response, e.Message);
throw new DeserializationException(response,
throw new ResponseDeserializationException(response,
catch (DeserializationException e) when (e.response == null)
catch (ResponseDeserializationException e)
throw new DeserializationException(response, e.Message);
}
catch (DeserializationException)
{
if (e.response == null)
{
throw new ResponseDeserializationException(response, e.Message);
}
throw new DeserializationException(response);
throw new ResponseDeserializationException(response);
}
}

}
catch (ArgumentException e)
{
throw new DeserializationException(response, e.Message);
throw new ResponseDeserializationException(response, e.Message);
throw new DeserializationException(response,
throw new ResponseDeserializationException(response,
catch (DeserializationException e) when (e.response == null)
catch (ResponseDeserializationException e)
throw new DeserializationException(response, e.Message);
}
catch (DeserializationException)
{
if (e.response == null)
{
throw new ResponseDeserializationException(response, e.Message);
}
throw new DeserializationException(response);
throw new ResponseDeserializationException(response);
}
}

}
catch (ArgumentException e)
{
throw new DeserializationException(response, e.Message);
throw new ResponseDeserializationException(response, e.Message);
throw new DeserializationException(response,
throw new ResponseDeserializationException(response,
catch (DeserializationException e) when (e.response == null)
{
throw new DeserializationException(response, e.Message);
}
catch (DeserializationException)
catch (ResponseDeserializationException e)
if (e.response == null)
{
throw new ResponseDeserializationException(response, e.Message);
}
throw new DeserializationException(response);
throw new ResponseDeserializationException(response);
}
}
}

25
Packages/com.unity.services.relay/Runtime/Models/AllocateResponseBody.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// AllocateResponseBody model
/// </summary>
/// <param name="links">links param</param>
/// <param name="links">links param</param>
/// </summary>
/// <summary>
/// Creates an instance of AllocateResponseBody.
/// </summary>
/// <param name="meta">meta param</param>
/// <param name="data">data param</param>
/// <param name="links">links param</param>
public AllocateResponseBody(ResponseMeta meta, AllocationData data, ResponseLinks links = default(ResponseLinks))
public AllocateResponseBody(ResponseMeta meta, AllocationData data, ResponseLinks links = default)
Links = links;
Links = links;
[DataMember(Name = "data", IsRequired = true, EmitDefaultValue = true)]
public AllocationData Data{ get; }
[Preserve]
[Preserve]
[DataMember(Name = "data", IsRequired = true, EmitDefaultValue = true)]
public AllocationData Data{ get; }
}
}

49
Packages/com.unity.services.relay/Runtime/Models/Allocation.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// Details of an allocation to a relay server
/// <param name="allocationId">ID of the allocation</param>
/// <param name="serverEndpoints">Connection endpoints for the assigned relay server</param>
/// <param name="relayServer">relayServer param</param>
/// <param name="key">Base64-encoded key required for the HMAC signature of the BIND message</param>
/// <param name="connectionData">Base64 encoded representation of an encrypted connection data blob describing this allocation. Required for establishing communication with other players.</param>
/// <param name="allocationIdBytes">Base64 encoded form of AllocationID. When decoded, this is the exact expected byte alignment to be used when crafting relay protocol messages that require AllocationID. eg. PING, CONNECT, RELAY, CLOSE, etc.</param>
/// <param name="allocation_id">ID of the allocation</param>
/// <param name="server_endpoints">Connection endpoints for the assigned relay server</param>
/// <param name="relay_server">relay_server param</param>
/// <param name="key">Base64-encoded key required for the HMAC signature of the BIND message</param>
/// <param name="connection_data">Base64 encoded representation of an encrypted connection data blob describing this allocation. Required for establishing communication with other players.</param>
/// <param name="allocation_id_bytes">Base64 encoded form of AllocationID. When decoded, this is the exact expected byte alignment to be used when crafting relay protocol messages that require AllocationID. eg. PING, CONNECT_REQUEST, RELAY, CLOSE, etc.</param>
/// <summary>
/// Details of an allocation to a relay server
/// </summary>
/// <param name="allocationId">ID of the allocation</param>
/// <param name="serverEndpoints">Connection endpoints for the assigned relay server</param>
/// <param name="relayServer">relayServer param</param>
/// <param name="key">Base64-encoded key required for the HMAC signature of the BIND message</param>
/// <param name="connectionData">Base64 encoded representation of an encrypted connection data blob describing this allocation. Required for establishing communication with other players.</param>
/// <param name="allocationIdBytes">Base64 encoded form of AllocationID. When decoded, this is the exact expected byte alignment to be used when crafting relay protocol messages that require AllocationID. eg. PING, CONNECT, RELAY, CLOSE, etc.</param>
[Preserve]
public Allocation(System.Guid allocationId, List<RelayServerEndpoint> serverEndpoints, RelayServer relayServer, byte[] key, byte[] connectionData, byte[] allocationIdBytes)
{

AllocationIdBytes = allocationIdBytes;
}
/// <summary>
/// ID of the allocation
/// </summary>
[DataMember(Name = "allocation_id", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "allocationId", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Connection endpoints for the assigned relay server
/// </summary>
[DataMember(Name = "server_endpoints", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "serverEndpoints", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "relay_server", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "relayServer", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Base64-encoded key required for the HMAC signature of the BIND message
/// </summary>
/// <summary>
/// Base64 encoded representation of an encrypted connection data blob describing this allocation. Required for establishing communication with other players.
/// </summary>
[DataMember(Name = "connection_data", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "connectionData", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Base64 encoded form of AllocationID. When decoded, this is the exact expected byte alignment to be used when crafting relay protocol messages that require AllocationID. eg. PING, CONNECT, RELAY, CLOSE, etc.
/// </summary>
[DataMember(Name = "allocation_id_bytes", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "allocationIdBytes", IsRequired = true, EmitDefaultValue = true)]
public byte[] AllocationIdBytes{ get; }
}

9
Packages/com.unity.services.relay/Runtime/Models/AllocationData.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// AllocationData model
/// <param name="allocation">allocation param</param>
/// <param name="allocation">allocation param</param>
/// <summary>
/// Creates an instance of AllocationData.
/// </summary>
/// <param name="allocation">allocation param</param>
[Preserve]
public AllocationData(Allocation allocation)
{

[Preserve]
[DataMember(Name = "allocation", IsRequired = true, EmitDefaultValue = true)]
public Allocation Allocation{ get; }

26
Packages/com.unity.services.relay/Runtime/Models/AllocationRequest.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// A request to create an allocation
/// <param name="maxConnections">Indicates the maximum number of connections that the client will allow to communicate with them. It will also be used in order to find a relay with sufficient capacity</param>
/// <param name="region">Indicates the region this allocation should go. If not provided, a default region will be chosen.</param>
/// <param name="max_connections">Indicates the maximum number of connections that the client will allow to communicate with them. It will also be used in order to find a relay with sufficient capacity</param>
/// <summary>
/// A request to create an allocation
/// </summary>
/// <param name="maxConnections">Indicates the maximum number of connections that the client will allow to communicate with them. It will also be used in order to find a relay with sufficient capacity</param>
/// <param name="region">Indicates the region this allocation should go. If not provided, a default region will be chosen.</param>
public AllocationRequest(int maxConnections)
public AllocationRequest(int maxConnections, string region = default)
Region = region;
/// <summary>
/// Indicates the maximum number of connections that the client will allow to communicate with them. It will also be used in order to find a relay with sufficient capacity
/// </summary>
[DataMember(Name = "max_connections", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "maxConnections", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Indicates the region this allocation should go. If not provided, a default region will be chosen.
/// </summary>
[Preserve]
[DataMember(Name = "region", EmitDefaultValue = false)]
public string Region{ get; }
}
}

26
Packages/com.unity.services.relay/Runtime/Models/ErrorResponseBody.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// ErrorResponseBody model
/// </summary>
/// </summary>
/// <summary>
/// Creates an instance of ErrorResponseBody.
/// </summary>
/// <param name="status">MUST use the same status code in the actual HTTP response.</param>
/// <param name="detail">A human-readable explanation specific to this occurrence of the problem. Ought to focus on helping the client correct the problem, rather than giving debugging information.</param>
/// <param name="title">SHOULD be the same as the recommended HTTP status phrase for that code.</param>
/// <param name="details">Machine readable list of individual errors.</param>
public ErrorResponseBody(int status, string detail, string title, List<KeyValuePair> details = default(List<KeyValuePair>))
public ErrorResponseBody(int status, string detail, string title, List<KeyValuePair> details = default)
{
Status = status;
Detail = detail;

/// <summary>
/// MUST use the same status code in the actual HTTP response.
/// </summary>
/// <summary>
/// A human-readable explanation specific to this occurrence of the problem. Ought to focus on helping the client correct the problem, rather than giving debugging information.
/// </summary>
/// <summary>
/// SHOULD be the same as the recommended HTTP status phrase for that code.
/// </summary>
/// <summary>
/// Machine readable list of individual errors.
/// </summary>
[Preserve]
[DataMember(Name = "details", EmitDefaultValue = false)]
public List<KeyValuePair> Details{ get; }

57
Packages/com.unity.services.relay/Runtime/Models/JoinAllocation.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// An allocation created via a join code
/// <param name="allocationId">ID of the allocation</param>
/// <param name="serverEndpoints">Connection endpoints for the assigned relay server</param>
/// <param name="relayServer">relayServer param</param>
/// <param name="key">Base64-encoded key required for the HMAC signature of the BIND message</param>
/// <param name="connectionData">Base64 encoded representation of an encrypted connection data blob describing this allocation. Required for establishing communication with other players.</param>
/// <param name="allocationIdBytes">Base64 encoded form of AllocationID. When decoded, this is the exact expected byte alignment to be used when crafting relay protocol messages that require AllocationID. eg. PING, CONNECT, RELAY, CLOSE, etc.</param>
/// <param name="hostConnectionData">Base64 encoded representation of an encrypted connection data blob describing the allocation and relay server of the player who created the join code. Used for establishing communication with the host.</param>
/// <param name="allocation_id">ID of the allocation</param>
/// <param name="server_endpoints">Connection endpoints for the assigned relay server</param>
/// <param name="relay_server">relay_server param</param>
/// <param name="key">Base64-encoded key required for the HMAC signature of the BIND message</param>
/// <param name="connection_data">Base64 encoded representation of an encrypted connection data blob describing this allocation. Required for establishing communication with other players.</param>
/// <param name="allocation_id_bytes">Base64 encoded form of AllocationID. When decoded, this is the exact expected byte alignment to be used when crafting relay protocol messages that require AllocationID. eg. PING, CONNECT_REQUEST, RELAY, CLOSE, etc.</param>
/// <param name="host_connection_data">Base64 encoded representation of an encrypted connection data blob describing the allocation and relay server of the player who created the join code. Used for establishing communication with the host.</param>
/// <summary>
/// An allocation created via a join code
/// </summary>
/// <param name="allocationId">ID of the allocation</param>
/// <param name="serverEndpoints">Connection endpoints for the assigned relay server</param>
/// <param name="relayServer">relayServer param</param>
/// <param name="key">Base64-encoded key required for the HMAC signature of the BIND message</param>
/// <param name="connectionData">Base64 encoded representation of an encrypted connection data blob describing this allocation. Required for establishing communication with other players.</param>
/// <param name="allocationIdBytes">Base64 encoded form of AllocationID. When decoded, this is the exact expected byte alignment to be used when crafting relay protocol messages that require AllocationID. eg. PING, CONNECT, RELAY, CLOSE, etc.</param>
/// <param name="hostConnectionData">Base64 encoded representation of an encrypted connection data blob describing the allocation and relay server of the player who created the join code. Used for establishing communication with the host.</param>
[Preserve]
public JoinAllocation(System.Guid allocationId, List<RelayServerEndpoint> serverEndpoints, RelayServer relayServer, byte[] key, byte[] connectionData, byte[] allocationIdBytes, byte[] hostConnectionData)
{

HostConnectionData = hostConnectionData;
}
/// <summary>
/// ID of the allocation
/// </summary>
[DataMember(Name = "allocation_id", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "allocationId", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Connection endpoints for the assigned relay server
/// </summary>
[DataMember(Name = "server_endpoints", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "serverEndpoints", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "relay_server", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "relayServer", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Base64-encoded key required for the HMAC signature of the BIND message
/// </summary>
/// <summary>
/// Base64 encoded representation of an encrypted connection data blob describing this allocation. Required for establishing communication with other players.
/// </summary>
[DataMember(Name = "connection_data", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "connectionData", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Base64 encoded form of AllocationID. When decoded, this is the exact expected byte alignment to be used when crafting relay protocol messages that require AllocationID. eg. PING, CONNECT, RELAY, CLOSE, etc.
/// </summary>
[DataMember(Name = "allocation_id_bytes", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "allocationIdBytes", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Base64 encoded representation of an encrypted connection data blob describing the allocation and relay server of the player who created the join code. Used for establishing communication with the host.
/// </summary>
[DataMember(Name = "host_connection_data", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "hostConnectionData", IsRequired = true, EmitDefaultValue = true)]
public byte[] HostConnectionData{ get; }
}

14
Packages/com.unity.services.relay/Runtime/Models/JoinAllocationAllOf.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// JoinAllocationAllOf model
/// <param name="hostConnectionData">Base64 encoded representation of an encrypted connection data blob describing the allocation and relay server of the player who created the join code. Used for establishing communication with the host.</param>
/// <param name="host_connection_data">Base64 encoded representation of an encrypted connection data blob describing the allocation and relay server of the player who created the join code. Used for establishing communication with the host.</param>
/// <summary>
/// Creates an instance of JoinAllocationAllOf.
/// </summary>
/// <param name="hostConnectionData">Base64 encoded representation of an encrypted connection data blob describing the allocation and relay server of the player who created the join code. Used for establishing communication with the host.</param>
[Preserve]
public JoinAllocationAllOf(byte[] hostConnectionData)
{

/// <summary>
/// Base64 encoded representation of an encrypted connection data blob describing the allocation and relay server of the player who created the join code. Used for establishing communication with the host.
/// </summary>
[DataMember(Name = "host_connection_data", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "hostConnectionData", IsRequired = true, EmitDefaultValue = true)]
public byte[] HostConnectionData{ get; }
}

14
Packages/com.unity.services.relay/Runtime/Models/JoinCodeData.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// JoinCodeData model
/// <param name="joinCode">The join code is used to lookup the connection data for the player responsible for creating it. It is case-insensitive. The connection data is returned to the caller and can be used in the request to the \&quot;join\&quot; endpoint to join a relay server.</param>
/// <param name="join_code">Join code associated with the given connection data</param>
/// <summary>
/// Creates an instance of JoinCodeData.
/// </summary>
/// <param name="joinCode">The join code is used to lookup the connection data for the player responsible for creating it. It is case-insensitive. The connection data is returned to the caller and can be used in the request to the \&quot;join\&quot; endpoint to join a relay server.</param>
[Preserve]
public JoinCodeData(string joinCode)
{

/// <summary>
/// The join code is used to lookup the connection data for the player responsible for creating it. It is case-insensitive. The connection data is returned to the caller and can be used in the request to the \&quot;join\&quot; endpoint to join a relay server.
/// </summary>
[DataMember(Name = "join_code", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "joinCode", IsRequired = true, EmitDefaultValue = true)]
public string JoinCode{ get; }
}

14
Packages/com.unity.services.relay/Runtime/Models/JoinCodeRequest.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// A request to create a join code
/// <param name="allocationId">UUID of the allocation which will be mapped to the generated join code. The connection data blob from the allocation will be shared with clients who use the generated join code on the /v1/join endpoint. This sharing is a mechanism to establish communication between players via the relay server data protocol</param>
/// <param name="allocation_id">UUID of the allocation which will be mapped to the generated join code. The connection data blob from the allocation will be shared with clients who use the generated join code on the /v1/join endpoint. This sharing is a mechanism to establish communication between players via the relay server data protocol</param>
/// <summary>
/// A request to create a join code
/// </summary>
/// <param name="allocationId">UUID of the allocation which will be mapped to the generated join code. The connection data blob from the allocation will be shared with clients who use the generated join code on the /v1/join endpoint. This sharing is a mechanism to establish communication between players via the relay server data protocol</param>
[Preserve]
public JoinCodeRequest(System.Guid allocationId)
{

/// <summary>
/// UUID of the allocation which will be mapped to the generated join code. The connection data blob from the allocation will be shared with clients who use the generated join code on the /v1/join endpoint. This sharing is a mechanism to establish communication between players via the relay server data protocol
/// </summary>
[DataMember(Name = "allocation_id", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "allocationId", IsRequired = true, EmitDefaultValue = true)]
public System.Guid AllocationId{ get; }
}

11
Packages/com.unity.services.relay/Runtime/Models/JoinCodeResponseBody.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// JoinCodeResponseBody model
/// </summary>
/// </summary>
/// <summary>
/// Creates an instance of JoinCodeResponseBody.
/// </summary>
/// <param name="meta">meta param</param>
/// <param name="links">links param</param>
/// <param name="data">data param</param>
[Preserve]
public JoinCodeResponseBody(ResponseMeta meta, ResponseLinks links, JoinCodeData data)
{

}
[Preserve]
[DataMember(Name = "meta", IsRequired = true, EmitDefaultValue = true)]
public ResponseMeta Meta{ get; }

9
Packages/com.unity.services.relay/Runtime/Models/JoinData.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// JoinData model
/// <param name="allocation">allocation param</param>
/// <param name="allocation">allocation param</param>
/// <summary>
/// Creates an instance of JoinData.
/// </summary>
/// <param name="allocation">allocation param</param>
[Preserve]
public JoinData(JoinAllocation allocation)
{

[Preserve]
[DataMember(Name = "allocation", IsRequired = true, EmitDefaultValue = true)]
public JoinAllocation Allocation{ get; }

14
Packages/com.unity.services.relay/Runtime/Models/JoinRequest.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// A request to join a relay using a join code
/// <param name="joinCode">The join code is used to lookup the connection data for the player responsible for creating it. It is case-insensitive. The connection data is returned to the caller and can be used in the request to the \&quot;join\&quot; endpoint to join a relay server.</param>
/// <param name="join_code">The join code is used to lookup the connection data for the player responsible for creating it. The connection data is returned to the caller and can be used to establish communication.</param>
/// <summary>
/// A request to join a relay using a join code
/// </summary>
/// <param name="joinCode">The join code is used to lookup the connection data for the player responsible for creating it. It is case-insensitive. The connection data is returned to the caller and can be used in the request to the \&quot;join\&quot; endpoint to join a relay server.</param>
[Preserve]
public JoinRequest(string joinCode)
{

/// <summary>
/// The join code is used to lookup the connection data for the player responsible for creating it. It is case-insensitive. The connection data is returned to the caller and can be used in the request to the \&quot;join\&quot; endpoint to join a relay server.
/// </summary>
[DataMember(Name = "join_code", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "joinCode", IsRequired = true, EmitDefaultValue = true)]
public string JoinCode{ get; }
}

10
Packages/com.unity.services.relay/Runtime/Models/JoinResponseBody.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// JoinResponseBody model
/// </summary>
/// </summary>
/// <summary>
/// Creates an instance of JoinResponseBody.
/// </summary>
/// <param name="meta">meta param</param>
/// <param name="data">data param</param>
[Preserve]
public JoinResponseBody(ResponseMeta meta, JoinData data)
{

[Preserve]
[DataMember(Name = "meta", IsRequired = true, EmitDefaultValue = true)]
public ResponseMeta Meta{ get; }

10
Packages/com.unity.services.relay/Runtime/Models/KeyValuePair.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// KeyValuePair model
/// </summary>
/// </summary>
/// <summary>
/// Creates an instance of KeyValuePair.
/// </summary>
/// <param name="key">key param</param>
/// <param name="value">value param</param>
[Preserve]
public KeyValuePair(string key, string value)
{

[Preserve]
[DataMember(Name = "key", IsRequired = true, EmitDefaultValue = true)]
public string Key{ get; }

20
Packages/com.unity.services.relay/Runtime/Models/RelayServer.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// Deprecated: IPv4 connection details for a relay server. The network protocol (currently supported options are tcp and udp) required by this IP/Port is determined by the relay server configuration and is not indicated here. Prefer the \&quot;relay server endpoint\&quot; collection to see IP/Port combinations with the network protocol required.
/// </summary>
/// <param name="ip_v4">IP (v4) address of the relay server</param>
/// <param name="ipV4">IP (v4) address of the relay server</param>
/// </summary>
/// <summary>
/// Deprecated: IPv4 connection details for a relay server. The network protocol (currently supported options are tcp and udp) required by this IP/Port is determined by the relay server configuration and is not indicated here. Prefer the \&quot;relay server endpoint\&quot; collection to see IP/Port combinations with the network protocol required.
/// </summary>
/// <param name="ipV4">IP (v4) address of the relay server</param>
/// <param name="port">Port of the relay server</param>
[Preserve]
public RelayServer(string ipV4, int port)
{

/// <summary>
/// IP (v4) address of the relay server
/// </summary>
[DataMember(Name = "ip_v4", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "ipV4", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Port of the relay server
/// </summary>
[Preserve]
[DataMember(Name = "port", IsRequired = true, EmitDefaultValue = true)]
public int Port{ get; }

37
Packages/com.unity.services.relay/Runtime/Models/RelayServerEndpoint.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// Endpoint connection details for a relay server
/// </summary>
/// <param name="connection_type">Canonical connection type</param>
/// <param name="connectionType">Canonical connection type</param>
/// </summary>
/// <summary>
/// Endpoint connection details for a relay server
/// </summary>
/// <param name="connectionType">Canonical connection type</param>
/// <param name="network">IP network (udp, tcp)</param>
/// <param name="reliable">Is the delivery of data guaranteed</param>
/// <param name="secure">Is the endpoint secured</param>
/// <param name="host">Host name or address of the relay server</param>
/// <param name="port">Port number</param>
[Preserve]
public RelayServerEndpoint(string connectionType, NetworkOptions network, bool reliable, bool secure, string host, int port)
{

Port = port;
}
/// <summary>
/// Canonical connection type
/// </summary>
[DataMember(Name = "connection_type", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "connectionType", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// IP network (udp, tcp)
/// </summary>
/// <summary>
/// Is the delivery of data guaranteed
/// </summary>
/// <summary>
/// Is the endpoint secured
/// </summary>
/// <summary>
/// Host name or address of the relay server
/// </summary>
/// <summary>
/// Port number
/// </summary>
[Preserve]
[DataMember(Name = "port", IsRequired = true, EmitDefaultValue = true)]
public int Port{ get; }

/// IP network (udp, tcp)
/// </summary>
/// <value>IP network (udp, tcp)</value>
[Preserve]
[JsonConverter(typeof(StringEnumConverter))]
public enum NetworkOptions
{

14
Packages/com.unity.services.relay/Runtime/Models/ResponseLinks.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// Represents links to related API endpoints
/// <param name="next">Indicates the URL of the suggest API endpoint to call next</param>
/// <param name="next">Indicates the URL of the suggest API endpoint to call next</param>
/// <summary>
/// Represents links to related API endpoints
/// </summary>
/// <param name="next">Indicates the URL of the suggest API endpoint to call next</param>
public ResponseLinks(string next = default(string))
public ResponseLinks(string next = default)
/// <summary>
/// Indicates the URL of the suggest API endpoint to call next
/// </summary>
[Preserve]
[DataMember(Name = "next", EmitDefaultValue = false)]
public string Next{ get; }

20
Packages/com.unity.services.relay/Runtime/Models/ResponseMeta.cs


using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;

/// Metadata for a response returned from an API call
/// </summary>
/// <param name="request_id">Unique ID for this request that triggered this response</param>
/// <param name="requestId">Unique ID for this request that triggered this response</param>
/// </summary>
/// <summary>
/// Metadata for a response returned from an API call
/// </summary>
/// <param name="requestId">Unique ID for this request that triggered this response</param>
/// <param name="status">Indicates the HTTP status code of the response</param>
[Preserve]
public ResponseMeta(string requestId, int status)
{

/// <summary>
/// Unique ID for this request that triggered this response
/// </summary>
[DataMember(Name = "request_id", IsRequired = true, EmitDefaultValue = true)]
[DataMember(Name = "requestId", IsRequired = true, EmitDefaultValue = true)]
/// <summary>
/// Indicates the HTTP status code of the response
/// </summary>
[Preserve]
[DataMember(Name = "status", IsRequired = true, EmitDefaultValue = true)]
public int Status{ get; }

2
Packages/com.unity.services.relay/Runtime/RelayService.cs


/// </summary>
public static IAllocationsApiClient AllocationsApiClient { get; internal set; }
public static Configuration Configuration = new Configuration("https://relay-allocations.cloud.unity3d.com", 10, 4, null);
public static Configuration Configuration = new Configuration("https://relay-allocations.services.api.unity.com", 10, 4, null);
}
}

19
Packages/com.unity.services.relay/Runtime/RelayServiceProvider.cs


using UnityEngine;
using System.Threading.Tasks;
using TaskScheduler = Unity.Services.Relay.Scheduler.TaskScheduler;
using Unity.Services.Core;
using Unity.Services.Authentication;

{
// Pass an instance of this class to Core
var generatedPackageRegistry =
CoreRegistry.Instance.RegisterPackage(new RelayServiceProvider());
// And specify what components it requires, or provides.
CoreRegistry.Instance.RegisterPackage(new RelayServiceProvider());
// And specify what components it requires, or provides.
;
;
var scheduler = _gameObjectFactory.GetComponent<TaskScheduler>();
var httpClient = new HttpClient(scheduler);
var httpClient = new HttpClient();
RelayService.AllocationsApiClient = new AllocationsApiClient(httpClient, scheduler, accessTokenAllocationsApi);
RelayService.AllocationsApiClient = new AllocationsApiClient(httpClient, accessTokenAllocationsApi);
return Task.CompletedTask;
}
}

4
Packages/com.unity.services.relay/Runtime/Scheduler/ThreadHelper.cs


using System.Threading;
using UnityEditor;
using UnityEngine;
namespace Unity.Services.Relay.Scheduler

private static System.Threading.Tasks.TaskScheduler _taskScheduler;
private static int _mainThreadId;
#if UNITY_EDITOR
[InitializeOnLoadMethod]
#endif
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void Init()
{

14
Packages/com.unity.services.relay/package.json


{
"name": "com.unity.services.relay",
"displayName": "Unity Relay Allocations",
"version": "0.0.1-preview.9",
"displayName": "Relay Allocations",
"version": "1.0.0-pre.3",
"description": "Client API SDK Package for communicating with the Relay Allocation service.",
"description": "Connect the players of your peer-hosted games with Relay. Your games will also benefit from improved reliability, privacy and the ability to communicate across platforms. To get started, enable listen-server UDP networking for your project on the Unity Dashboard.\n\nFeatures include an allocation service to join game hosts via code, multi-region support, and more.",
"com.unity.services.core": "1.1.0-pre.2",
"com.unity.services.core": "1.1.0-pre.4",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",

},
"relatedPackages": {
"com.unity.services.relay.tests": "0.0.1-preview.9"
"com.unity.services.relay.tests": "1.0.0-pre.3"
"footprint": "138cf8db778f8f5693da448db26c683bc4925418"
"footprint": "55b3403a5ee8d6ec4a35cf2211fede62d292dde1"
"revision": "a47b39cde6df7aab6b1c702b339dc51adda48494"
"revision": "980a48b44f402ffb7e1d0672ee4392c138442102"
}
}

4
Packages/packages-lock.json


"depth": 0,
"source": "embedded",
"dependencies": {
"com.unity.services.core": "1.1.0-pre.2",
"com.unity.services.core": "1.1.0-pre.4",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",

"depth": 0,
"source": "embedded",
"dependencies": {
"com.unity.services.core": "1.1.0-pre.2",
"com.unity.services.core": "1.1.0-pre.4",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",

76
Packages/com.unity.services.lobby/Third Party Notices.md


This package contains third-party software components governed by the license(s) indicated below:
---------
Component Name: Newtonsoft.Json
License Type: MIT
The MIT License (MIT)
Copyright (c) 2007 James Newton-King
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &quot;Software&quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<hr>
Component Name: Json.Net.Unity3D
License Type: MIT
The MIT License (MIT)
Copyright (c) Copyright (c) 2016 SaladLab
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &quot;Software&quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<hr>
Component Name: Newtonsoft.Json-for-Unity
License Type: MIT
The MIT License (MIT)
Copyright (c) Copyright (c) 2019 Kalle Jillheden (jilleJr)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &quot;Software&quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<hr>
Component Name: com.newtonsoft.json
License Type: MIT
MIT License
Copyright (c) 2019 Mike Wuetherick
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the &quot;Software&quot;), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

7
Packages/com.unity.services.lobby/Third Party Notices.md.meta


fileFormatVersion: 2
guid: 941f0de9f9074c74485555365dd5c67c
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

15
Packages/com.unity.services.relay/Runtime/Http/DeserializationSettings.cs


using System;
namespace Unity.Services.Relay.Http
{
public enum MissingMemberHandling
{
Error,
Ignore
}
public class DeserializationSettings
{
public MissingMemberHandling MissingMemberHandling = MissingMemberHandling.Error;
}
}

11
Packages/com.unity.services.relay/Runtime/Http/DeserializationSettings.cs.meta


fileFormatVersion: 2
guid: b764d3594d93a411cbcdfc89f56291e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

53
Packages/com.unity.services.relay/Runtime/Http/JsonObject.cs


using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Utilities;
using UnityEngine;
namespace Unity.Services.Relay.Http
{
public class JsonObject
{
internal JsonObject(object obj)
{
this.obj = obj;
}
internal object obj;
public string GetAsString()
{
try
{
return JsonConvert.SerializeObject(obj);
}
catch (System.Exception)
{
throw new System.Exception("Failed to convert JsonObject to string.");
}
}
public T GetAs<T>(DeserializationSettings deserializationSettings = null)
{
// Check if derializationSettings is null so we can use the default value.
deserializationSettings = deserializationSettings ?? new DeserializationSettings();
JsonSerializerSettings jsonSettings = new JsonSerializerSettings
{
MissingMemberHandling = deserializationSettings.MissingMemberHandling == MissingMemberHandling.Error
? Newtonsoft.Json.MissingMemberHandling.Error
: Newtonsoft.Json.MissingMemberHandling.Ignore
};
try
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj), jsonSettings);
}
catch (Newtonsoft.Json.JsonSerializationException e)
{
throw new DeserializationException(e.Message);
}
catch (System.Exception)
{
throw new DeserializationException("Unable to deserialize object.");
}
}
}
}

11
Packages/com.unity.services.relay/Runtime/Http/JsonObject.cs.meta


fileFormatVersion: 2
guid: a60146f44cbeb488fbe04186676cc4fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

28
Packages/com.unity.services.relay/Runtime/Http/JsonObjectConverter.cs


using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Utilities;
using UnityEngine;
namespace Unity.Services.Relay.Http
{
class JsonObjectConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JsonObject jobj = (JsonObject) value;
JToken t = JToken.FromObject(jobj.obj);
t.WriteTo(writer);
}
public override object ReadJson(JsonReader reader, System.Type objectType, object existingValue, JsonSerializer serializer)
{
throw new System.NotImplementedException();
}
public override bool CanConvert(System.Type objectType)
{
throw new System.NotImplementedException();
}
}
}

11
Packages/com.unity.services.relay/Runtime/Http/JsonObjectConverter.cs.meta


fileFormatVersion: 2
guid: 4ad4ebc6198cd46b1baa3e32d92e397f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

34
Packages/com.unity.services.relay/Runtime/Http/ResponseDeserializationException.cs


using System;
namespace Unity.Services.Relay.Http
{
[Serializable]
public class ResponseDeserializationException : Exception
{
public HttpClientResponse response;
public ResponseDeserializationException() : base()
{
}
public ResponseDeserializationException(string message) : base(message)
{
}
ResponseDeserializationException(string message, Exception inner) : base(message, inner)
{
}
public ResponseDeserializationException(HttpClientResponse httpClientResponse) : base(
"Unable to Deserialize Http Client Response")
{
response = httpClientResponse;
}
public ResponseDeserializationException(HttpClientResponse httpClientResponse, string message) : base(
message)
{
response = httpClientResponse;
}
}
}

11
Packages/com.unity.services.relay/Runtime/Http/ResponseDeserializationException.cs.meta


fileFormatVersion: 2
guid: 01df1d96af8bd43a29e815eaeff7078c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

52
Packages/com.unity.services.relay/Runtime/Models/Region.cs


using System;
using System.Collections.Generic;
using UnityEngine.Scripting;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;
namespace Unity.Services.Relay.Models
{
/// <summary>
/// Region model
/// <param name="id">The region id used in allocation requests</param>
/// <param name="description">A human readable description of the region. May include geographical information, for example, city name, country.</param>
/// </summary>
[Preserve]
[DataContract(Name = "Region")]
public class Region
{
/// <summary>
/// Creates an instance of Region.
/// </summary>
/// <param name="id">The region id used in allocation requests</param>
/// <param name="description">A human readable description of the region. May include geographical information, for example, city name, country.</param>
[Preserve]
public Region(string id, string description)
{
Id = id;
Description = description;
}
/// <summary>
/// The region id used in allocation requests
/// </summary>
[Preserve]
[DataMember(Name = "id", IsRequired = true, EmitDefaultValue = true)]
public string Id{ get; }
/// <summary>
/// A human readable description of the region. May include geographical information, for example, city name, country.
/// </summary>
[Preserve]
[DataMember(Name = "description", IsRequired = true, EmitDefaultValue = true)]
public string Description{ get; }
}
}

11
Packages/com.unity.services.relay/Runtime/Models/Region.cs.meta


fileFormatVersion: 2
guid: 98d7b6730e60f46d18f239388c08878f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

42
Packages/com.unity.services.relay/Runtime/Models/RegionsData.cs


using System;
using System.Collections.Generic;
using UnityEngine.Scripting;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;
namespace Unity.Services.Relay.Models
{
/// <summary>
/// RegionsData model
/// <param name="regions">Regions where relay servers might be available</param>
/// </summary>
[Preserve]
[DataContract(Name = "RegionsData")]
public class RegionsData
{
/// <summary>
/// Creates an instance of RegionsData.
/// </summary>
/// <param name="regions">Regions where relay servers might be available</param>
[Preserve]
public RegionsData(List<Region> regions)
{
Regions = regions;
}
/// <summary>
/// Regions where relay servers might be available
/// </summary>
[Preserve]
[DataMember(Name = "regions", IsRequired = true, EmitDefaultValue = true)]
public List<Region> Regions{ get; }
}
}

11
Packages/com.unity.services.relay/Runtime/Models/RegionsData.cs.meta


fileFormatVersion: 2
guid: f091fa486ae964cd89ed99c055575d21
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

39
Packages/com.unity.services.relay/Runtime/Models/RegionsResponseBody.cs


using System;
using System.Collections.Generic;
using UnityEngine.Scripting;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Unity.Services.Relay.Http;
namespace Unity.Services.Relay.Models
{
/// <summary>
/// RegionsResponseBody model
/// <param name="data">data param</param>
/// </summary>
[Preserve]
[DataContract(Name = "RegionsResponseBody")]
public class RegionsResponseBody
{
/// <summary>
/// Creates an instance of RegionsResponseBody.
/// </summary>
/// <param name="data">data param</param>
[Preserve]
public RegionsResponseBody(RegionsData data)
{
Data = data;
}
[Preserve]
[DataMember(Name = "data", IsRequired = true, EmitDefaultValue = true)]
public RegionsData Data{ get; }
}
}

11
Packages/com.unity.services.relay/Runtime/Models/RegionsResponseBody.cs.meta


fileFormatVersion: 2
guid: 013db46fafeb3453193d41d72005b408
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

76
Packages/com.unity.services.relay/Third Party Notices.md


This package contains third-party software components governed by the license(s) indicated below:
---------
Component Name: Newtonsoft.Json
License Type: MIT
The MIT License (MIT)
Copyright (c) 2007 James Newton-King
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &quot;Software&quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<hr>
Component Name: Json.Net.Unity3D
License Type: MIT
The MIT License (MIT)
Copyright (c) Copyright (c) 2016 SaladLab
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &quot;Software&quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<hr>
Component Name: Newtonsoft.Json-for-Unity
License Type: MIT
The MIT License (MIT)
Copyright (c) Copyright (c) 2019 Kalle Jillheden (jilleJr)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &quot;Software&quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<hr>
Component Name: com.newtonsoft.json
License Type: MIT
MIT License
Copyright (c) 2019 Mike Wuetherick
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the &quot;Software&quot;), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

7
Packages/com.unity.services.relay/Third Party Notices.md.meta


fileFormatVersion: 2
guid: f125b46aaa0524bdfb7c96d3cf3c5f17
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Packages/com.unity.services.lobby/Samples~/HelloWorld.meta


fileFormatVersion: 2
guid: 9ada111e9bb0b9b40a4136e17c5b6003
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

5
Packages/com.unity.services.lobby/Samples~/HelloWorld/.sample.json


{
"displayName":"Hello World Sample",
"description": "This sample walks through using most of the Lobby APIs in a simple, linear way.",
"createSeparatePackage": false
}

430
Packages/com.unity.services.lobby/Samples~/HelloWorld/LobbyHelloWorld.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UnityEngine;
using Unity.Services.Authentication;
using Unity.Services.Core;
using Unity.Services.Lobbies;
using Unity.Services.Lobbies.Http;
using Unity.Services.Lobbies.Models;
using Random = UnityEngine.Random;
public class LobbyHelloWorld : MonoBehaviour
{
// Inspector properties with initial values
public string newLobbyName = Guid.NewGuid().ToString();
public int maxPlayers = 8;
public bool isPrivate = false;
// We'll only be in one lobby at once for this demo, so let's track it here
private Lobby currentLobby;
async void Start()
{
try
{
await ExecuteLobbyDemoAsync();
}
catch (Exception ex)
{
Debug.LogException(ex);
}
finally
{
await CleanupDemoLobbyAsync();
}
}
// Clean up the lobby we're in if we're the host
async Task CleanupDemoLobbyAsync()
{
var localPlayerId = AuthenticationService.Instance.PlayerId;
// This is so that orphan lobbies aren't left around in case the demo fails partway through
if (currentLobby != null && currentLobby.HostId.Equals(localPlayerId))
{
await DeleteLobbyAsync(currentLobby.Id);
}
}
// A basic demo of lobby functionality
async Task ExecuteLobbyDemoAsync()
{
await UnityServices.Initialize();
// Log in a player for this game client
Player loggedInPlayer = await GetPlayerFromAnonymousLoginAsync();
// Add some data to our player
// This data will be included in a lobby under players -> player.data
loggedInPlayer.Data.Add("Ready", new PlayerDataObject(PlayerDataObject.VisibilityOptions.Member, "No"));
// Look for existing lobbies
List<Lobby> foundLobbies = await QueryLobbiesAsync(new QueryRequest(
count: 10, // Return up to 10 results
sampleResults: false, // Do not give random results
filter: new List<QueryFilter>
{
// Use filters to only return lobbies which match specific conditions
// You can only filter on built-in properties (Ex: AvailableSlots) or indexed custom data (S1, N1, etc.)
// Take a look at the API for other built-in fields you can filter on
// Let's search for games with open slots (AvailableSlots greater than 0)
new QueryFilter(
field: QueryFilter.FieldOptions.AvailableSlots,
op: QueryFilter.OpOptions.GT,
value: "0"),
// Let's add some filters for custom indexed fields
new QueryFilter(
field: QueryFilter.FieldOptions.S1, // S1 = "Test"
op: QueryFilter.OpOptions.EQ,
value: "true"),
new QueryFilter(
field: QueryFilter.FieldOptions.S2, // S2 = "GameMode"
op: QueryFilter.OpOptions.EQ,
value: "ctf"),
// Example "skill" range filter (skill is a custom numeric field in this example)
new QueryFilter(
field: QueryFilter.FieldOptions.N1, // N1 = "Skill"
op: QueryFilter.OpOptions.GT,
value: "0"),
new QueryFilter(
field: QueryFilter.FieldOptions.N1, // N1 = "Skill"
op: QueryFilter.OpOptions.LT,
value: "51"),
},
order: new List<QueryOrder>
{
// Order results by available player slots (least first), then by lobby age, then by lobby name
new QueryOrder(true, QueryOrder.FieldOptions.AvailableSlots),
new QueryOrder(false, QueryOrder.FieldOptions.Created),
new QueryOrder(false, QueryOrder.FieldOptions.Name),
}));
if (foundLobbies.Any()) // Try to join a random lobby if one exists
{
// Let's print info about the lobbies we found
Debug.Log("Found lobbies:\n" + JsonConvert.SerializeObject(foundLobbies));
// Let's pick a random lobby to join
var randomLobby = foundLobbies[Random.Range(0, foundLobbies.Count)];
// Try to join the lobby
// Player is optional because the service can pull the player data from the auth token
currentLobby = await JoinLobbyAsync(lobbyId: randomLobby.Id, player: null);
// You can also join via a Lobby Code instead of a lobby ID
// Lobby Codes are a short, unique codes that map to a specific lobby Id
// currentLobby = await JoinLobbyWithCodeAsync("MyLobbyCode");
}
else // Didn't find any lobbies, create a new lobby
{
// Populate the new lobby with some data; use indexes so it's easy to search for
var lobbyData = new Dictionary<string, DataObject>()
{
["Test"] = new DataObject(DataObject.VisibilityOptions.Public, "true", DataObject.IndexOptions.S1),
["GameMode"] = new DataObject(DataObject.VisibilityOptions.Public, "ctf", DataObject.IndexOptions.S2),
["Skill"] = new DataObject(DataObject.VisibilityOptions.Public, Random.Range(1, 51).ToString(), DataObject.IndexOptions.N1),
["Rank"] = new DataObject(DataObject.VisibilityOptions.Public, Random.Range(1, 51).ToString()),
};
// Create a new lobby
currentLobby = await CreateLobbyAsync(new CreateRequest(
name: newLobbyName,
player: loggedInPlayer,
maxPlayers: maxPlayers,
isPrivate: isPrivate,
data: lobbyData));
}
// Let's write a little info about the lobby we joined / created
Debug.Log("Lobby info:\n" + JsonConvert.SerializeObject(currentLobby));
// Let's add some new data for our player and update the lobby state
// Players can update their own data
loggedInPlayer.Data.Add("ExamplePublicPlayerData",
new PlayerDataObject(PlayerDataObject.VisibilityOptions.Public, "Everyone can see this"));
loggedInPlayer.Data.Add("ExamplePrivatePlayerData",
new PlayerDataObject(PlayerDataObject.VisibilityOptions.Private, "Only the host sees this"));
loggedInPlayer.Data.Add("ExampleMemberPlayerData",
new PlayerDataObject(PlayerDataObject.VisibilityOptions.Member, "Only lobby members see this"));
// Update the lobby
currentLobby = await UpdateLobbyPlayerDataAsync(currentLobby.Id, loggedInPlayer);
Debug.Log("Updated lobby info:\n" + JsonConvert.SerializeObject(currentLobby));
// Let's poll for the lobby data again just to see what it looks like
currentLobby = await GetLobbyAsync(currentLobby.Id);
Debug.Log("Updated lobby info:\n" + JsonConvert.SerializeObject(currentLobby));
if (!currentLobby.HostId.Equals(loggedInPlayer.Id))
{
// Since we're not the lobby host, let's just leave the lobby
await RemovePlayerFromLobbyAsync(currentLobby.Id, loggedInPlayer.Id);
}
else
{
// Only hosts can set lobby data, and we're the host, so let's set some
// Note that lobby host can be passed around intentionally (by the current host updating the host id)
// Host is randomly assigned if the previous host leaves
// Let's update some existing lobby data
currentLobby.Data["GameMode"] =
new DataObject(DataObject.VisibilityOptions.Public, "deathmatch", DataObject.IndexOptions.S2);
// Let's add some new data to the lobby
currentLobby.Data.Add("ExamplePublicLobbyData",
new DataObject(DataObject.VisibilityOptions.Public, "Everyone can see this"));
currentLobby.Data.Add("ExamplePrivateLobbyData",
new DataObject(DataObject.VisibilityOptions.Private, "Only the host sees this"));
currentLobby.Data.Add("ExampleMemberLobbyData",
new DataObject(DataObject.VisibilityOptions.Member, "Only lobby members see this"));
// OK, now let's try to push these local changes to the service
currentLobby = await UpdateLobbyDataAsync(currentLobby);
// Let's print the updated lobby
Debug.Log("Updated lobby info:\n" + JsonConvert.SerializeObject(currentLobby));
// OK, we're done with the lobby - let's delete it
await DeleteLobbyAsync(currentLobby.Id);
}
// Now, let's try the QuickJoin API, which just puts our player in a matching lobby automatically
// This is fast and reliable, but removes some user interactivity (can't choose from a list of lobbies)
// You can use filters to specify which types of lobbies can be joined
currentLobby = await QuickJoinLobbyAsync(loggedInPlayer, new List<QueryFilter>
{
// Let's search for games with open slots (AvailableSlots greater than 0)
new QueryFilter(
field: QueryFilter.FieldOptions.AvailableSlots,
op: QueryFilter.OpOptions.GT,
value: "0"),
// You can add more filters here, such as filters on custom data fields
});
// If we didn't find a lobby, abort run
if (currentLobby == null)
{
Debug.Log("Unable to find a lobby using Query and Join");
return;
}
// Let's write a little info about the lobby we quick-joined
Debug.Log("Lobby info:\n" + JsonConvert.SerializeObject(currentLobby));
// There's not anything else we can really do here, so let's leave the lobby
await RemovePlayerFromLobbyAsync(currentLobby.Id, loggedInPlayer.Id);
}
// Log in a player using Unity's "Anonymous Login" API and construct a Player object for use with the Lobbies APIs
static async Task<Player> GetPlayerFromAnonymousLoginAsync()
{
if (!AuthenticationService.Instance.IsSignedIn)
{
Debug.Log($"Trying to log in a player ...");
// Use Unity Authentication to log in
await AuthenticationService.Instance.SignInAnonymouslyAsync();
if (!AuthenticationService.Instance.IsSignedIn)
{
Debug.Log("Player was not signed in successfully?");
throw new InvalidOperationException("Unable to continue with no logged in player");
}
}
Debug.Log("Player signed in as " + AuthenticationService.Instance.PlayerId);
// Player objects have Get-only properties, so you need to initialize the data bag here if you want to use it
return new Player(AuthenticationService.Instance.PlayerId, null, new Dictionary<string, PlayerDataObject>());
}
// Create a new lobby
static async Task<Lobby> CreateLobbyAsync(CreateRequest createRequest)
{
Debug.Log($"Trying to create a new lobby ...");
Response<Lobby> response = await LobbyService.LobbyApiClient.CreateLobbyAsync(new CreateLobbyRequest(createRequest));
Debug.Log($"Player {createRequest.Player.Id} created lobby {response.Result.Id}");
return response.Result;
}
// Get a list of existing lobbies (Optional: use a filter)
static async Task<List<Lobby>> QueryLobbiesAsync(QueryRequest queryRequest)
{
Debug.Log($"Trying to query compatible lobbies ...");
Response<QueryResponse> response = await LobbyService.LobbyApiClient.QueryLobbiesAsync(new QueryLobbiesRequest(queryRequest));
Debug.Log($"Found {response.Result.Results.Count} matching lobbies");
return response.Result.Results;
}
// Ask the service to join any available lobby; can provide a filter
static async Task<Lobby> QuickJoinLobbyAsync(Player player, List<QueryFilter> filter = null)
{
Debug.Log($"Trying to query and join a compatible lobby ...");
var request = new QuickJoinLobbyRequest(new QuickJoinRequest(
player: player,
filter: filter
));
// This is an example of how to handle some common errors when calling the service
// 404s are expected if no lobby is found, and the API currently throws exceptions on 404
try
{
Response<Lobby> response = await LobbyService.LobbyApiClient.QuickJoinLobbyAsync(request);
Debug.Log($"Player {player.Id} joined lobby {response.Result.Id}");
return response.Result;
}
catch (HttpException ex)
{
if (TryGetErrorFromResponse(ex.Response, out var error))
{
// If we got a structured error we can deserialize, let's log it
Debug.Log($"Lobby service error; Http Status {ex.Response.StatusCode}" +
$"\nResponse Error: {ex.Response.ErrorMessage}" +
$"\nLobby Error Status: {error.status}" +
$"\nLobby Error Title: {error.title}");
}
else
{
// For error we can't deserialize, log the exception + body for debugging
Debug.Log($"Lobby service error; Http Status {ex.Response.StatusCode}" +
$"\nResponse Error: {ex.Response.ErrorMessage}" +
$"\nBody: {Encoding.UTF8.GetString(ex.Response.Data)}");
Debug.LogException(ex);
}
}
return null;
}
// Try to join a specific lobby
static async Task<Lobby> JoinLobbyAsync(string lobbyId, Player player = null)
{
Debug.Log($"Attempting to join lobby {lobbyId} ...");
Response<Lobby> response = await LobbyService.LobbyApiClient.JoinLobbyByIdAsync(
new JoinLobbyByIdRequest(lobbyId, player));
Debug.Log($"Joined lobby {response.Result.Id}");
return response.Result;
}
// Try to join a specific lobby; use a lobbyCode to join instead of a LobbyId
static async Task<Lobby> JoinLobbyWithCodeAsync(string lobbyCode, Player player = null)
{
Debug.Log($"Attempting to join lobby with lobby code {lobbyCode} ...");
Response<Lobby> response = await LobbyService.LobbyApiClient.JoinLobbyByCodeAsync(
new JoinLobbyByCodeRequest(new JoinByCodeRequest(lobbyCode, player)));
Debug.Log($"Joined lobby {response.Result.Id}");
return response.Result;
}
// Get details about a specific lobby
static async Task<Lobby> GetLobbyAsync(string lobbyId)
{
Debug.Log($"Getting lobby {lobbyId} ...");
Response<Lobby> response = await LobbyService.LobbyApiClient.GetLobbyAsync(
new GetLobbyRequest(lobbyId));
return response.Result;
}
// Delete an existing lobby; see API docs for access restrictions
static async Task DeleteLobbyAsync(string lobbyId)
{
Debug.Log($"Deleting lobby {lobbyId} ...");
Response response = await LobbyService.LobbyApiClient.DeleteLobbyAsync(
new DeleteLobbyRequest(lobbyId));
Debug.Log($"Lobby {lobbyId} deleted");
}
// Remove a player from a lobby; see API docs for access restrictions
static async Task RemovePlayerFromLobbyAsync(string lobbyId, string playerId)
{
Debug.Log($"Removing {playerId} from lobby {lobbyId} ...");
var request = new RemovePlayerRequest(lobbyId, playerId);
Response response = await LobbyService.LobbyApiClient.RemovePlayerAsync(request);
Debug.Log($"Player {playerId} removed from lobby {lobbyId}");
}
// Set lobby data; see API docs for access restrictions
static async Task<Lobby> UpdateLobbyDataAsync(Lobby lobby)
{
Debug.Log($"Updating lobby data for lobby {lobby.Id} ...");
UpdateRequest updatedState = new UpdateRequest(
maxPlayers: lobby.MaxPlayers,
isPrivate: lobby.IsPrivate,
data: lobby.Data,
hostId: lobby.HostId,
name: lobby.Name);
var updateReq = new UpdateLobbyRequest(lobby.Id, updatedState);
Response<Lobby> response = await LobbyService.LobbyApiClient.UpdateLobbyAsync(updateReq);
Debug.Log($"Lobby data for lobby {lobby.Id} updated");
return response.Result;
}
// Set player data in a lobby; see API docs for access restrictions
static async Task<Lobby> UpdateLobbyPlayerDataAsync(string lobbyId, Player player)
{
Debug.Log($"Updating player data for player {player.Id} in lobby {lobbyId} ...");
var newPlayerState = new PlayerUpdateRequest(
connectionInfo: player.ConnectionInfo,
data: player.Data,
allocationId: player.AllocationId);
var updateReq = new UpdatePlayerRequest(lobbyId, player.Id, newPlayerState);
Response<Lobby> response = await LobbyService.LobbyApiClient.UpdatePlayerAsync(updateReq);
Debug.Log($"Player data for player {player.Id} in lobby {lobbyId} updated");
return response.Result;
}
// A class for errors returned from the service on failures (4xx errors, etc.)
class LobbyError
{
public int status { get; set; }
public string title { get; set; }
public Detail[] details { get; set; }
}
class Detail
{
public string message { get; set; }
public string errorType { get; set; }
}
static bool TryGetErrorFromResponse(HttpClientResponse response, out LobbyError error)
{
var decodedJsonString = Encoding.UTF8.GetString(response.Data);
var success = true;
var settings = new JsonSerializerSettings
{
Error = (sender, args) =>
{
success = false;
args.ErrorContext.Handled = true;
},
MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore
};
error = JsonConvert.DeserializeObject<LobbyError>(decodedJsonString, settings);
return success;
}
}

11
Packages/com.unity.services.lobby/Samples~/HelloWorld/LobbyHelloWorld.cs.meta


fileFormatVersion: 2
guid: 36b1cdc3d10416a44ac98753d781b1c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Packages/com.unity.services.lobby/CONTRIBUTING.md


# Contributing
## If you are interested in contributing, here are some ground rules:
* ... Define guidelines & rules for what contributors need to know to successfully make Pull requests against your repo ...
## All contributions are subject to the [Unity Contribution Agreement(UCA)](https://unity3d.com/legal/licenses/Unity_Contribution_Agreement)
By making a pull request, you are confirming agreement to the terms and conditions of the UCA, including that your Contributions are your original creation and that you have complete right and authority to make your Contributions.
## Once you have a change ready following these ground rules. Simply make a pull request

7
Packages/com.unity.services.lobby/CONTRIBUTING.md.meta


fileFormatVersion: 2
guid: d997183ab5f3e4f1aabd60a9e9d99360
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存