Skip to content

Commit ae0471b

Browse files
committed
Finish ToDo for leaderboard most hunted
1 parent ed42dde commit ae0471b

File tree

3 files changed

+66
-3
lines changed

3 files changed

+66
-3
lines changed

Client/Components/Pages/Leaderboard.razor

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ else
5656
}
5757
</tbody>
5858
</table>
59+
60+
<table class="table">
61+
<thead>
62+
<tr>
63+
<th>Player name</th>
64+
<th>Times hunted by antags</th>
65+
</tr>
66+
</thead>
67+
<tbody>
68+
@foreach (var player in LeaderboardData.MostHuntedPlayer)
69+
{
70+
<tr>
71+
<td>@player.Value.Player.Username</td>
72+
<td>@player.Value.Count</td>
73+
</tr>
74+
}
75+
</tbody>
76+
</table>
5977
}
6078

6179
<script>

Server/Api/DataController.cs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Net.WebSockets;
44
using System.Text;
55
using System.Text.Json;
6+
using System.Text.RegularExpressions;
67
using Microsoft.AspNetCore.Cors;
78
using Microsoft.AspNetCore.Mvc;
89
using Microsoft.EntityFrameworkCore;
@@ -20,6 +21,8 @@ namespace Server.Api;
2021
[Route("api/[controller]")]
2122
public class DataController : ControllerBase
2223
{
24+
public static readonly Regex HuntedRegex = new Regex(@"(?<=Kill(?:\sor\smaroon)\s)([^,]+)");
25+
2326
private readonly ReplayDbContext _context;
2427
private readonly IMemoryCache _cache;
2528

@@ -75,7 +78,8 @@ public async Task<LeaderboardData> GetLeaderboard(
7578
var leaderboardResult = new LeaderboardData()
7679
{
7780
MostSeenPlayers = new Dictionary<string, PlayerCount>(),
78-
MostAntagPlayers = new Dictionary<string, PlayerCount>()
81+
MostAntagPlayers = new Dictionary<string, PlayerCount>(),
82+
MostHuntedPlayer = new Dictionary<string, PlayerCount>(),
7983
};
8084

8185
// To calculate the most seen player, we just count how many times we see a player in each RoundEndPlayer list.
@@ -133,7 +137,36 @@ public async Task<LeaderboardData> GetLeaderboard(
133137

134138
#endregion
135139

136-
// TODO: Implement most hunted player
140+
// The most hunted player is a bit more complex. We need to check the round end text for the following string
141+
// "Kill or maroon <name>, <job> | "
142+
// We need to extract the name and then look for that player in the player list for that replay.
143+
// If we find the player, we increment the count.
144+
if (dataReplay.RoundEndText == null || dataReplay.RoundEndPlayers == null)
145+
continue;
146+
147+
var matches = HuntedRegex.Matches(dataReplay.RoundEndText);
148+
foreach (Match match in matches)
149+
{
150+
var playerName = match.Value.Trim();
151+
var player = dataReplay.RoundEndPlayers.FirstOrDefault(p => p.PlayerIcName == playerName);
152+
if (player == null)
153+
continue;
154+
155+
var playerKey = new PlayerData()
156+
{
157+
PlayerGuid = player.PlayerGuid,
158+
Username = ""
159+
};
160+
var didAdd = leaderboardResult.MostHuntedPlayer.TryAdd(playerKey.PlayerGuid.ToString(), new PlayerCount()
161+
{
162+
Count = 1,
163+
Player = playerKey,
164+
});
165+
if (!didAdd)
166+
{
167+
leaderboardResult.MostHuntedPlayer[playerKey.PlayerGuid.ToString()].Count++;
168+
}
169+
}
137170
}
138171

139172
// Need to only return the top 10 players
@@ -147,6 +180,11 @@ public async Task<LeaderboardData> GetLeaderboard(
147180
.Take(10)
148181
.ToDictionary(p => p.Key, p => p.Value);
149182

183+
leaderboardResult.MostHuntedPlayer = leaderboardResult.MostHuntedPlayer
184+
.OrderByDescending(p => p.Value.Count)
185+
.Take(10)
186+
.ToDictionary(p => p.Key, p => p.Value);
187+
150188
// Now we need to fetch the usernames for the players
151189
foreach (var player in leaderboardResult.MostSeenPlayers)
152190
{
@@ -162,6 +200,13 @@ public async Task<LeaderboardData> GetLeaderboard(
162200
await Task.Delay(50); // Rate limit the API
163201
}
164202

203+
foreach (var player in leaderboardResult.MostHuntedPlayer)
204+
{
205+
var playerData = await FetchPlayerDataFromGuid(player.Value.Player.PlayerGuid);
206+
player.Value.Player.Username = playerData.Username;
207+
await Task.Delay(50); // Rate limit the API
208+
}
209+
165210
// Save leaderboard to cache (its expensive as fuck to calculate)
166211
var cacheEntryOptions = new MemoryCacheEntryOptions()
167212
.SetAbsoluteExpiration(TimeSpan.FromHours(3));

Shared/LeaderboardData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class LeaderboardData
1010
/// <summary>
1111
/// Most times as a kill or maroon target.
1212
/// </summary>
13-
public Dictionary<string, PlayerData> MostHuntedPlayer { get; set; }
13+
public Dictionary<string, PlayerCount> MostHuntedPlayer { get; set; }
1414
}
1515

1616
public class PlayerCount

0 commit comments

Comments
 (0)