-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add stats endpoint with player, server, ticket and party count * Update playlists * Remove unnecessary .ToList * Use REPR for auth and stats endpoints Clean up 'Program.cs' a bit Fix matchmaking namespace
- Loading branch information
1 parent
2c6d9c6
commit 6d764a0
Showing
29 changed files
with
1,112 additions
and
921 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using MatchmakingServer.Authentication; | ||
using MatchmakingServer.Stats; | ||
|
||
namespace MatchmakingServer.Api | ||
{ | ||
public static class EndpointRouteBuilderExtensions | ||
{ | ||
public static void MapEndpoints(this WebApplication app) | ||
{ | ||
app.MapEndpoint<AuthenticationEndpoint>(); | ||
app.MapEndpoint<StatsEndpoint>(); | ||
} | ||
|
||
private static IEndpointRouteBuilder MapEndpoint<TEndpoint>(this IEndpointRouteBuilder app) where TEndpoint : IEndpoint | ||
{ | ||
TEndpoint.Map(app); | ||
return app; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace MatchmakingServer.Api | ||
{ | ||
public interface IEndpoint | ||
{ | ||
static abstract void Map(IEndpointRouteBuilder app); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace MatchmakingServer.Api | ||
{ | ||
public static class RouteHandlerBuilderExtensions | ||
{ | ||
public static RouteHandlerBuilder WithValidation<TRequest>(this RouteHandlerBuilder builder) | ||
{ | ||
return builder | ||
.AddEndpointFilter<ValidationFilter<TRequest>>() | ||
.ProducesValidationProblem(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using FluentValidation; | ||
|
||
namespace MatchmakingServer.Api; | ||
|
||
public class ValidationFilter<T>(IValidator<T> validator) : IEndpointFilter | ||
{ | ||
public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) | ||
{ | ||
T? request = context.Arguments.OfType<T>().First(); | ||
|
||
if (request is null) | ||
{ | ||
return Results.BadRequest(); | ||
} | ||
|
||
var validationResult = await validator.ValidateAsync(request); | ||
if (!validationResult.IsValid) | ||
{ | ||
return Results.ValidationProblem(validationResult.ToDictionary()); | ||
} | ||
|
||
return await next(context); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using MatchmakingServer.SignalR; | ||
|
||
using Serilog; | ||
|
||
namespace MatchmakingServer; | ||
|
||
public static class ApplicationSetup | ||
{ | ||
public static void UseRequestLogging(this IApplicationBuilder app) | ||
{ | ||
app.UseSerilogRequestLogging(options => | ||
{ | ||
options.MessageTemplate = "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms ({ClientAppName}/{ClientAppVersion})"; | ||
options.EnrichDiagnosticContext = (diagnosticContext, httpContext) => | ||
{ | ||
if (httpContext.Request.Headers.TryGetValue("X-App-Name", out var appNameValues) && appNameValues.Count != 0) | ||
{ | ||
diagnosticContext.Set("ClientAppName", appNameValues.FirstOrDefault()); | ||
} | ||
else | ||
{ | ||
diagnosticContext.Set("ClientAppName", "Unknown"); | ||
} | ||
|
||
if (httpContext.Request.Headers.TryGetValue("X-App-Version", out var appVersionValues) && appVersionValues.Count != 0) | ||
{ | ||
diagnosticContext.Set("ClientAppVersion", appVersionValues.FirstOrDefault()); | ||
} | ||
else | ||
{ | ||
diagnosticContext.Set("ClientAppVersion", "?"); | ||
} | ||
}; | ||
}); | ||
} | ||
|
||
public static void MapHubs(this IEndpointRouteBuilder app) | ||
{ | ||
app.MapHub<QueueingHub>("/Queue"); | ||
app.MapHub<PartyHub>("/Party"); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
MatchmakingServer/Authentication/AuthenticationEndpoint.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using System.Security.Claims; | ||
|
||
using FluentValidation; | ||
|
||
using MatchmakingServer.Api; | ||
|
||
using Microsoft.AspNetCore.Authentication.BearerToken; | ||
using Microsoft.AspNetCore.Http.HttpResults; | ||
|
||
namespace MatchmakingServer.Authentication | ||
{ | ||
public class AuthenticationEndpoint : IEndpoint | ||
{ | ||
public static void Map(IEndpointRouteBuilder app) => app | ||
.MapGet("/login", Handle) | ||
.WithSummary("Logs the user in with the UID and player name and returns a bearer token.") | ||
.WithValidation<Request>(); | ||
|
||
public record Request(string Uid, string PlayerName); | ||
public class RequestValidator : AbstractValidator<Request> | ||
{ | ||
public RequestValidator() | ||
{ | ||
RuleFor(x => x.Uid).NotEmpty().MaximumLength(36); | ||
RuleFor(x => x.PlayerName).NotEmpty().MaximumLength(69); | ||
} | ||
} | ||
|
||
private static SignInHttpResult Handle([AsParameters] Request request) | ||
{ | ||
ClaimsPrincipal claimsPrincipal = new( | ||
new ClaimsIdentity( | ||
[new Claim(ClaimTypes.Name, request.PlayerName), new Claim(ClaimTypes.NameIdentifier, request.Uid)], | ||
BearerTokenDefaults.AuthenticationScheme | ||
) | ||
); | ||
|
||
return TypedResults.SignIn(claimsPrincipal); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 28 additions & 29 deletions
57
MatchmakingServer/Matchmaking/MMServerPriorityComparer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,37 @@ | ||
namespace MatchmakingServer | ||
namespace MatchmakingServer.Matchmaking; | ||
|
||
class MMServerPriorityComparer : IComparer<GameServer> | ||
{ | ||
class MMServerPriorityComparer : IComparer<GameServer> | ||
public int Compare(GameServer? x, GameServer? y) | ||
{ | ||
public int Compare(GameServer? x, GameServer? y) | ||
if (x?.LastServerInfo is null || y?.LastServerInfo is null) | ||
{ | ||
if (x?.LastServerInfo is null || y?.LastServerInfo is null) | ||
{ | ||
return 0; | ||
} | ||
|
||
// Check if we should prioritize based on TotalScore < 1000 | ||
bool xIsHalfFull = x.LastStatusResponse?.TotalScore < 1000 && x.LastServerInfo.RealPlayerCount < 6; | ||
bool yIsHalfFull = y.LastStatusResponse?.TotalScore < 1000 && x.LastServerInfo.RealPlayerCount < 6; | ||
|
||
// Case 1: If both servers are half empty and under the score limit, | ||
// prioritize by player count (servers with fewer players should be prioritized) | ||
if (xIsHalfFull && yIsHalfFull) | ||
{ | ||
return x.LastServerInfo.RealPlayerCount.CompareTo(y.LastServerInfo.RealPlayerCount); | ||
} | ||
return 0; | ||
} | ||
|
||
// Case 2: If one server is half full and under the score limit and the other one is not, | ||
// prioritize the half full server | ||
if (xIsHalfFull && !yIsHalfFull) | ||
{ | ||
return -1; | ||
} | ||
if (!xIsHalfFull && yIsHalfFull) | ||
{ | ||
return 1; | ||
} | ||
// Check if we should prioritize based on TotalScore < 1000 | ||
bool xIsHalfFull = x.LastStatusResponse?.TotalScore < 1000 && x.LastServerInfo.RealPlayerCount < 6; | ||
bool yIsHalfFull = y.LastStatusResponse?.TotalScore < 1000 && x.LastServerInfo.RealPlayerCount < 6; | ||
|
||
// Case 3: If both servers are over the score limit, prioritize by fewer players | ||
// Case 1: If both servers are half empty and under the score limit, | ||
// prioritize by player count (servers with fewer players should be prioritized) | ||
if (xIsHalfFull && yIsHalfFull) | ||
{ | ||
return x.LastServerInfo.RealPlayerCount.CompareTo(y.LastServerInfo.RealPlayerCount); | ||
} | ||
|
||
// Case 2: If one server is half full and under the score limit and the other one is not, | ||
// prioritize the half full server | ||
if (xIsHalfFull && !yIsHalfFull) | ||
{ | ||
return -1; | ||
} | ||
if (!xIsHalfFull && yIsHalfFull) | ||
{ | ||
return 1; | ||
} | ||
|
||
// Case 3: If both servers are over the score limit, prioritize by fewer players | ||
return x.LastServerInfo.RealPlayerCount.CompareTo(y.LastServerInfo.RealPlayerCount); | ||
} | ||
} |
Oops, something went wrong.