Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 21 additions & 20 deletions GenOnlineService/LobbyManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,13 @@ public Lobby(Int64 lobby_id, UserSession owner, string name, ELobbyState state,
LobbyMember placeholderMember = new LobbyMember(this, null, -1, String.Empty, String.Empty, 0, -1, -1, -1, i < max_players ? EPlayerType.SLOT_OPEN : EPlayerType.SLOT_CLOSED, i, true);
Members[i] = placeholderMember;
}
}

public event Action<Lobby>? OnLobbyNeedsDestroyed;
using var scope = ServiceLocator.Services.CreateScope();
var factory = scope.ServiceProvider.GetRequiredService<IDbContextFactory<AppDbContext>>();
_db = factory.CreateDbContext();
}

public event Action<Lobby>? OnLobbyNeedsDestroyed;

public async Task OnAfterPlayerLeft(Int64 leavingUserID)
{
Expand Down Expand Up @@ -965,9 +969,10 @@ public void ForceReady()
private int m_cachedAtStart_numOpen = -1;
private int m_cachedAtStart_numClosed = -1;
private int m_cachedAtStart_numAI = -1;
private AppDbContext _db;

// TODO: Really, client also shouldnt upload data we arent going to process in this situation, its wasteful
public bool WasPVPAtStart()
// TODO: Really, client also shouldnt upload data we arent going to process in this situation, its wasteful
public bool WasPVPAtStart()
{
// debug
#if DEBUG
Expand Down Expand Up @@ -1012,10 +1017,7 @@ public async Task UpdateState(ELobbyState state)
try
{
// create placeholder
using var scope = ServiceLocator.Services.CreateScope();
var factory = scope.ServiceProvider.GetRequiredService<IDbContextFactory<AppDbContext>>();
await using var db = await factory.CreateDbContextAsync();
await Database.MatchHistory.CreatePlaceholderMatchHistory(db, this);
await Database.MatchHistory.CreatePlaceholderMatchHistory(_db, this);
}
catch (Exception ex)
{
Expand Down Expand Up @@ -1244,13 +1246,18 @@ public class LobbyManager
private Int64 m_NextLobbyID = 0;

private readonly IServiceProvider _services;
private readonly AppDbContext _db;

public LobbyManager(IServiceProvider services)
{
_services = services;
}

public async Task Cleanup()
var scope = _services.CreateScope();
var factory = scope.ServiceProvider.GetRequiredService<IDbContextFactory<AppDbContext>>();
var _db = factory.CreateDbContext();
}

public async Task Cleanup()
{
// Remove any lobby that has 0 members and has been around for a bit (enough time for host to join)
List<Lobby> lstLobbiesToRemove = new List<Lobby>();
Expand Down Expand Up @@ -1285,7 +1292,7 @@ private void HandleLobbyNeedsDestroyed(Lobby lobby)
m_queueLobbiesNeedingDestroyed.Enqueue(lobby);
}

private async Task ProcessLobbiesNeedingDestroyed()
public async Task ProcessLobbiesNeedingDestroyed()
{
while (m_queueLobbiesNeedingDestroyed.TryDequeue(out Lobby? lobbyToDestroy))
{
Expand Down Expand Up @@ -1365,8 +1372,6 @@ public async Task Tick()
{
await kvPair.Value.Tick();
}

await ProcessLobbiesNeedingDestroyed();
}

public async Task<bool> JoinLobby(AppDbContext _db, Lobby lobby, UserSession playerSession, string strDisplayName, UInt16 userPreferredPort, bool bHasMap)
Expand Down Expand Up @@ -1555,17 +1560,13 @@ public async Task<bool> DeleteLobby(Lobby lobby)
{
try
{
using var scope = _services.CreateScope();
var factory = scope.ServiceProvider.GetRequiredService<IDbContextFactory<AppDbContext>>();
await using var db = await factory.CreateDbContextAsync();

if (lobby.State != ELobbyState.COMPLETE)
{
// make done
await lobby.UpdateState(ELobbyState.COMPLETE);

// attempt to commit it
await Database.MatchHistory.CommitLobbyToMatchHistory(db, lobby);
await Database.MatchHistory.CommitLobbyToMatchHistory(_db, lobby);
}

// delete
Expand All @@ -1579,11 +1580,11 @@ public async Task<bool> DeleteLobby(Lobby lobby)
lobby.OnLobbyNeedsDestroyed -= HandleLobbyNeedsDestroyed;

// make sure we have a winner
await Database.MatchHistory.DetermineLobbyWinnerIfNotPresent(db, lobby);
await Database.MatchHistory.DetermineLobbyWinnerIfNotPresent(_db, lobby);

// Post match result to external leaderboard API for every lobby type.
// Only QuickMatch responses are expected to carry a ratings body.
await ExternalLeaderboardsClient.PostMatchResultAsync(db, lobby);
await ExternalLeaderboardsClient.PostMatchResultAsync(_db, lobby);
}

return bRemoved;
Expand Down
28 changes: 26 additions & 2 deletions GenOnlineService/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1268,8 +1268,32 @@ public static async Task Main(string[] args)
timerTick.Start();
}

// tick matchmaking (done at lower frequency)
{
// tick lobby cleanup - this is a separate timer to prevent main lobby tick from being blocked by cleanup
// @hotfix SkyAero 15/08/2026
{
System.Timers.Timer timerTick = new System.Timers.Timer(5); // 5ms tick
timerTick.AutoReset = false;
timerTick.Elapsed += async (sender, e) =>
{
try
{
var lobbyManager = ServiceLocator.Services.GetRequiredService<LobbyManager>();
await lobbyManager.ProcessLobbiesNeedingDestroyed();
}
catch (Exception ex)
{
Console.WriteLine($"[cleanupTick lobby] Exception: {ex}");
}
finally
{
timerTick.Start();
}
};
timerTick.Start();
}

// tick matchmaking (done at lower frequency)
{
System.Timers.Timer timerTick = new System.Timers.Timer(1000); // 1s tick
timerTick.AutoReset = false;
timerTick.Elapsed += async (sender, e) =>
Expand Down
Loading