111 lines
4.3 KiB
C#
111 lines
4.3 KiB
C#
using FinalFactory.Rendezvous.Contracts;
|
|
|
|
namespace FinalFactory.Rendezvous.Client;
|
|
|
|
public sealed class RendezvousSessionBrowserClient : IRendezvousSessionBrowserClient
|
|
{
|
|
private readonly RendezvousHttpTransport _transport;
|
|
|
|
public RendezvousSessionBrowserClient(
|
|
HttpClient httpClient,
|
|
RendezvousClientOptions? options = null,
|
|
IRendezvousDelay? delay = null)
|
|
{
|
|
_transport = new(httpClient, options, delay);
|
|
}
|
|
|
|
public Task<RendezvousClientResult<BrowseSessionsResponse>> BrowseAsync(
|
|
BrowseSessionsRequest request,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (request is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(request));
|
|
}
|
|
|
|
string query = $"v1/sessions?contractVersion={request.ContractVersion}"
|
|
+ $"&gameId={Escape(request.GameId.Value)}"
|
|
+ $"&environmentId={Escape(request.EnvironmentId.Value)}"
|
|
+ $"&protocolVersion={request.ProtocolVersion}"
|
|
+ $"&pageSize={request.PageSize}"
|
|
+ $"&excludeFull={request.ExcludeFull.ToString().ToLowerInvariant()}"
|
|
+ (request.RegionId.HasValue ? $"®ionId={Escape(request.RegionId.Value.Value)}" : string.Empty)
|
|
+ (request.Cursor is not null ? $"&cursor={Escape(request.Cursor)}" : string.Empty);
|
|
return _transport.SendSafeAsync<BrowseSessionsResponse>(
|
|
() => new HttpRequestMessage(HttpMethod.Get, query),
|
|
cancellationToken);
|
|
}
|
|
|
|
public async Task<RendezvousClientResult<IReadOnlyList<SessionListing>>> BrowseAllAsync(
|
|
BrowseSessionsRequest request,
|
|
int maximumPages = 100,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (request is null)
|
|
{
|
|
throw new ArgumentNullException(nameof(request));
|
|
}
|
|
|
|
if (maximumPages is < 1 or > 1000)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(maximumPages));
|
|
}
|
|
|
|
List<SessionListing> items = [];
|
|
string? cursor = request.Cursor;
|
|
for (int page = 0; page < maximumPages; page++)
|
|
{
|
|
BrowseSessionsRequest pageRequest = new()
|
|
{
|
|
ContractVersion = request.ContractVersion,
|
|
GameId = request.GameId,
|
|
EnvironmentId = request.EnvironmentId,
|
|
ProtocolVersion = request.ProtocolVersion,
|
|
RegionId = request.RegionId,
|
|
PageSize = request.PageSize,
|
|
ExcludeFull = request.ExcludeFull,
|
|
Cursor = cursor,
|
|
};
|
|
RendezvousClientResult<BrowseSessionsResponse> result = await BrowseAsync(
|
|
pageRequest,
|
|
cancellationToken).ConfigureAwait(false);
|
|
if (!result.IsSuccess || result.Value is null)
|
|
{
|
|
return RendezvousClientResult.Failure<IReadOnlyList<SessionListing>>(
|
|
result.Error,
|
|
result.Message,
|
|
result.RetryAfterSeconds);
|
|
}
|
|
|
|
items.AddRange(result.Value.Items);
|
|
cursor = result.Value.NextCursor;
|
|
if (string.IsNullOrEmpty(cursor))
|
|
{
|
|
return RendezvousClientResult.Success<IReadOnlyList<SessionListing>>(items.AsReadOnly());
|
|
}
|
|
}
|
|
|
|
return RendezvousClientResult.Failure<IReadOnlyList<SessionListing>>(
|
|
RendezvousErrorCode.CapacityExceeded,
|
|
$"Browsing exceeded the configured {maximumPages}-page limit.");
|
|
}
|
|
|
|
public Task<RendezvousClientResult<GetSessionResponse>> GetAsync(
|
|
SessionListingId listingId,
|
|
GameId gameId,
|
|
EnvironmentId environmentId,
|
|
uint protocolVersion,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
string query = $"v1/sessions/{listingId}?contractVersion={ContractLimits.ContractVersion}"
|
|
+ $"&gameId={Escape(gameId.Value)}"
|
|
+ $"&environmentId={Escape(environmentId.Value)}"
|
|
+ $"&protocolVersion={protocolVersion}";
|
|
return _transport.SendSafeAsync<GetSessionResponse>(
|
|
() => new HttpRequestMessage(HttpMethod.Get, query),
|
|
cancellationToken);
|
|
}
|
|
|
|
private static string Escape(string value) => Uri.EscapeDataString(value ?? string.Empty);
|
|
}
|