feat: add bounded compatible session browser (#8)
quality-gate / quality (push) Successful in 57s

Closes #8
This commit is contained in:
KyuubiYoru
2026-07-16 06:06:29 +02:00
parent 49564c7e7e
commit a9a2b3db35
14 changed files with 786 additions and 10 deletions
@@ -1,4 +1,5 @@
using FinalFactory.Rendezvous.Contracts;
using FinalFactory.Rendezvous.Server.Browser;
using FinalFactory.Rendezvous.Server.Provisioning;
using FinalFactory.Rendezvous.Server.Sessions;
using FinalFactory.Rendezvous.Server.State;
@@ -55,11 +56,14 @@ internal static class ContractEndpoints
.WithName("DeleteSession");
sessions.MapGet("/", BrowseSessions)
.Produces<BrowseSessionsResponse>()
.Produces<ApiError>(NotImplementedStatus)
.Produces<ApiError>(StatusCodes.Status400BadRequest)
.Produces<ApiError>(StatusCodes.Status503ServiceUnavailable)
.WithName("BrowseSessions");
sessions.MapGet("/{listingId}", GetSession)
.Produces<GetSessionResponse>()
.Produces<ApiError>(NotImplementedStatus)
.Produces<ApiError>(StatusCodes.Status400BadRequest)
.Produces<ApiError>(StatusCodes.Status404NotFound)
.Produces<ApiError>(StatusCodes.Status503ServiceUnavailable)
.WithName("GetSession");
sessions.MapGet("/{listingId}/join-attempts", BrowseHostJoinAttempts)
.Produces<BrowseHostJoinAttemptsResponse>()
@@ -200,9 +204,64 @@ internal static class ContractEndpoints
[FromQuery] uint protocolVersion,
[FromQuery] string? regionId,
[FromQuery] int? pageSize,
[FromQuery] string? cursor) => NotImplemented();
[FromQuery] bool? excludeFull,
[FromQuery] string? cursor,
[FromServices] SessionBrowserService browser,
CancellationToken cancellationToken)
{
if (!GameId.TryParse(gameId, out GameId parsedGameId)
|| !EnvironmentId.TryParse(environmentId, out EnvironmentId parsedEnvironmentId)
|| (regionId is not null && !RegionId.TryParse(regionId, out _)))
{
return Error(RendezvousErrorCode.InvalidRequest);
}
private static IResult GetSession(SessionListingId listingId) => NotImplemented();
BrowserServiceResult<BrowseSessionsResponse> result = browser.Browse(new()
{
ContractVersion = contractVersion,
GameId = parsedGameId,
EnvironmentId = parsedEnvironmentId,
ProtocolVersion = protocolVersion,
RegionId = regionId is null ? null : new RegionId(regionId),
PageSize = pageSize ?? ContractLimits.BrowserPageMaxItems,
ExcludeFull = excludeFull ?? false,
Cursor = cursor,
}, cancellationToken);
return result.Succeeded && result.Value is not null
? Results.Ok(result.Value)
: Error(result.Error);
}
private static IResult GetSession(
SessionListingId listingId,
[FromQuery] int contractVersion,
[FromQuery] string gameId,
[FromQuery] string environmentId,
[FromQuery] uint protocolVersion,
[FromServices] SessionBrowserService browser,
CancellationToken cancellationToken)
{
if (ContractValidation.ValidateContractVersion(contractVersion) != RendezvousErrorCode.None)
{
return Error(RendezvousErrorCode.UnsupportedContractVersion);
}
if (!GameId.TryParse(gameId, out GameId parsedGameId)
|| !EnvironmentId.TryParse(environmentId, out EnvironmentId parsedEnvironmentId))
{
return Error(RendezvousErrorCode.InvalidRequest);
}
BrowserServiceResult<GetSessionResponse> result = browser.Get(
listingId,
parsedGameId,
parsedEnvironmentId,
protocolVersion,
cancellationToken);
return result.Succeeded && result.Value is not null
? Results.Ok(result.Value)
: Error(result.Error);
}
private static IResult BrowseHostJoinAttempts(
SessionListingId listingId,