Skip to content

Commit

Permalink
Per server leaderboards (#46)
Browse files Browse the repository at this point in the history
* Per server leaderboards

* Changelog
  • Loading branch information
Simyon264 authored Aug 22, 2024
1 parent 201e1f4 commit 0d46aff
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 8 deletions.
1 change: 1 addition & 0 deletions ReplayBrowser/Pages/Changelog.razor
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<li>Added a new contributors page.</li>
<li>Improved speed on the entire site by a whole bunch.</li>
<li>Added a favicon</li>
<li>Added per server leaderboards</li>
</ul>
<p>12.08.2024</p>
<ul>
Expand Down
67 changes: 64 additions & 3 deletions ReplayBrowser/Pages/Leaderboard.razor
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
@page "/leaderboard"
@using Microsoft.AspNetCore.Components.Authorization
@using ReplayBrowser.Data
@using ReplayBrowser.Models
@using ReplayBrowser.Services
@using Microsoft.AspNetCore.Components.Web
@using ReplayBrowser.Helpers
@using ReplayBrowser.Pages.Shared

@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IConfiguration Configuration
Expand Down Expand Up @@ -58,8 +58,40 @@ else
id="search"
value="@username"
>
<button class="btn btn-outline-success" type="button" onclick="search()">Filter</button>
</div>
<br/>
<button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#serverSelectionCollapse" aria-expanded="false" aria-controls="serverSelectionCollapse">
Toggle server selection
</button>

<div class="collapse" id="serverSelectionCollapse">
<div style="flex-direction: column; display: flex">
@{
var urls = Configuration.GetSection("ReplayUrls").Get<StorageUrl[]>()!;
var selectedServersQuery = queryDictionary["selectedServers"];
if (selectedServersQuery == null)
{
selectedServersQuery = urls.Select(x => x.FallBackServerName).Aggregate((x, y) => $"{x},{y}");
}

var selectedServers = selectedServersQuery.Split(',');
foreach (var storage in urls)
{
// Server selection
<input
type="checkbox"
class="server-checkbox"
id="@storage.FallBackServerName.Replace(' ', '_')"
name="@storage.FallBackServerName.Replace(' ', '_')"
value="@storage.FallBackServerName"
checked="@selectedServers.Contains(storage.FallBackServerName)"
>
<label for="@storage.FallBackServerName.Replace(' ', '_')">@storage.FallBackServerName (@storage.FallBackServerId)</label>
}
}
</div>
</div>
<button class="btn btn-outline-success" type="button" onclick="search()">Filter</button>
</div>

<hr/>
Expand Down Expand Up @@ -125,10 +157,22 @@ else
}

<script>
const allServersCount = document.getElementsByClassName("server-checkbox").length;
function changeTimeRange(timeRange) {
var uri = new URL(window.location.href);
uri.searchParams.set("timeRange", timeRange);
uri.searchParams.set("username", document.getElementById("search").value);
// Get the selected servers
let selectedServers = Array.from(document.getElementsByClassName("server-checkbox"))
.filter(x => x.checked)
.map(x => x.value)
.join(",");
// If we have all servers selected, we don't need to add the query parameter
if (selectedServers.split(',').length !== allServersCount)
{
uri.searchParams.set("selectedServers", selectedServers);
}
window.location.href = uri.toString();
}
Expand All @@ -137,6 +181,14 @@ else
var uri = new URL(window.location.href);
uri.searchParams.set("timeRange", uri.searchParams.get("timeRange") || 5);
uri.searchParams.set("username",search);
let selectedServers = Array.from(document.getElementsByClassName("server-checkbox"))
.filter(x => x.checked)
.map(x => x.value)
.join(",");
if (selectedServers.split(',').length !== allServersCount)
{
uri.searchParams.set("selectedServers", selectedServers);
}
window.location.href = uri.toString();
}
Expand All @@ -150,6 +202,7 @@ else
$('#search').autocomplete()
});
</script>

<style>
Expand Down Expand Up @@ -197,7 +250,15 @@ else
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
try
{
leaderboard = await LeaderboardService.GetLeaderboard(timeRangeEnum, username, authState);
var selectedServers = queryDictionary["selectedServers"];
if (selectedServers == null)
{
var urls = Configuration.GetSection("ReplayUrls").Get<StorageUrl[]>()!;
selectedServers = urls.Select(x => x.FallBackServerName).Aggregate((x, y) => $"{x},{y}");
}

var selectedServersArray = selectedServers.Split(',');
leaderboard = await LeaderboardService.GetLeaderboard(timeRangeEnum, username, selectedServersArray, authState);
}
catch (UnauthorizedAccessException)
{
Expand Down
26 changes: 21 additions & 5 deletions ReplayBrowser/Services/LeaderboardService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ public class LeaderboardService : IHostedService, IDisposable
private readonly Ss14ApiHelper _apiHelper;
private readonly IServiceScopeFactory _scopeFactory;
private readonly AccountService _accountService;
private readonly IConfiguration _configuration;

public LeaderboardService(IMemoryCache cache, Ss14ApiHelper apiHelper, IServiceScopeFactory factory, AccountService accountService)
public LeaderboardService(IMemoryCache cache, Ss14ApiHelper apiHelper, IServiceScopeFactory factory, AccountService accountService, IConfiguration configuration)
{
_cache = cache;
_apiHelper = apiHelper;
_scopeFactory = factory;
_accountService = accountService;
_configuration = configuration;
}

public Task StartAsync(CancellationToken cancellationToken)
Expand All @@ -50,7 +52,7 @@ private void DoWork(object? state)
foreach (var rangeOption in Enum.GetValues<RangeOption>())
{
var anonymousAuth = new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
GetLeaderboard(rangeOption, null, anonymousAuth, false).Wait();
GetLeaderboard(rangeOption, null, [], anonymousAuth, false).Wait();
}

sw.Stop();
Expand All @@ -68,8 +70,13 @@ public void Dispose()
_timer?.Dispose();
}

public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, string? username, AuthenticationState authenticationState, bool logAction = true)
public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, string? username, string[]? servers, AuthenticationState authenticationState, bool logAction = true)
{
if (servers == null || servers.Length == 0)
{
servers = _configuration.GetSection("ReplayUrls").Get<StorageUrl[]>()!.Select(x => x.FallBackServerName).ToArray();
}

var context = _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<ReplayDbContext>();

Account? accountCaller = null;
Expand Down Expand Up @@ -111,7 +118,10 @@ public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, strin
.Replace(" ", "-")
.Replace(".", "-")
.Replace("_", "-");
var cacheKey = "leaderboard-" + rangeOption + "-" + usernameCacheKey;

var serversCacheKey = string.Join("-", servers);

var cacheKey = "leaderboard-" + rangeOption + "-" + usernameCacheKey + "-" + serversCacheKey;
if (_cache.TryGetValue(cacheKey, out LeaderboardData? leaderboardData))
{
return leaderboardData!;
Expand All @@ -130,7 +140,6 @@ public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, strin
var stopwatch = new Stopwatch();
long stopwatchPrevious = 0;
stopwatch.Start();
var rangeTimespan = rangeOption.GetTimeSpan();
var leaderboards = new Dictionary<string, Leaderboard>()
{
{"MostSeenPlayers", new Leaderboard()
Expand Down Expand Up @@ -172,6 +181,7 @@ public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, strin
#region FUNNY SQL QUERIES

var mostplayed = await context.ReplayParticipants
.Where(p => servers.Contains(p.Replay.ServerName))
.Where(p => p.Replay!.Date >= (DateTime.UtcNow - rangeOption.GetNormalTimeSpan()))
.GroupBy(p => p.PlayerGuid)
.Select(pg => new {
Expand All @@ -195,6 +205,7 @@ public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, strin
stopwatch.Start();

var mostplayednoghost = await context.ReplayParticipants
.Where(p => servers.Contains(p.Replay.ServerName))
.Where(p => p.Replay!.Date >= (DateTime.UtcNow - rangeOption.GetNormalTimeSpan()))
.Where(p => p.Players!.Any(p => p.PlayerIcName != "Unknown"))
.GroupBy(p => p.PlayerGuid)
Expand All @@ -220,6 +231,7 @@ public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, strin
stopwatch.Start();

var mostantag = await context.ReplayParticipants
.Where(p => servers.Contains(p.Replay.ServerName))
.Where(p => p.Replay!.Date >= (DateTime.UtcNow - rangeOption.GetNormalTimeSpan()))
.Where(p => p.Players!.Any(p => p.AntagPrototypes.Count > 0))
.GroupBy(p => p.PlayerGuid)
Expand All @@ -246,6 +258,7 @@ public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, strin

var mostPlayedDepartments = await context.Players
.Where(p => p.EffectiveJobId != null)
.Where(p => servers.Contains(p.Participant.Replay.ServerName))
.Where(p => p.Participant.Replay!.Date >= (DateTime.UtcNow - rangeOption.GetNormalTimeSpan()))
.GroupBy(p => p.EffectiveJob!.Department)
.Select(pg => new {
Expand All @@ -272,6 +285,7 @@ public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, strin

var mostPlayedJobs = await context.Players
.Where(p => p.JobPrototypes.Count > 0)
.Where(p => servers.Contains(p.Participant.Replay.ServerName))
.Where(p => p.Participant.Replay!.Date >= (DateTime.UtcNow - rangeOption.GetNormalTimeSpan()))
.Select(p => p.JobPrototypes[0])
.GroupBy(p => p)
Expand Down Expand Up @@ -299,6 +313,7 @@ public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, strin

var perDepartmentPlayers = await context.Players
.Where(p => p.EffectiveJobId != null)
.Where(p => servers.Contains(p.Participant.Replay.ServerName))
.Where(p => p.Participant.Replay!.Date >= (DateTime.UtcNow - rangeOption.GetNormalTimeSpan()))
.GroupBy(p => new {
p.EffectiveJob!.Department,
Expand Down Expand Up @@ -335,6 +350,7 @@ public async Task<LeaderboardData> GetLeaderboard(RangeOption rangeOption, strin

var perJobPlayers = await context.Players
.Where(p => p.JobPrototypes.Count > 0)
.Where(p => servers.Contains(p.Participant.Replay.ServerName))
.Where(p => p.Participant.Replay!.Date >= (DateTime.UtcNow - rangeOption.GetNormalTimeSpan()))
.GroupBy(p => new {
Job = p.JobPrototypes[0],
Expand Down

0 comments on commit 0d46aff

Please sign in to comment.