diff --git a/server/src/Hokm.Server/Game/Contracts.cs b/server/src/Hokm.Server/Game/Contracts.cs
index 1bd8ef0..7f3658e 100644
--- a/server/src/Hokm.Server/Game/Contracts.cs
+++ b/server/src/Hokm.Server/Game/Contracts.cs
@@ -34,7 +34,8 @@ public record GameStateDto(
bool Ranked,
int Stake);
-public record MatchmakingStateDto(string Phase, int Players, int? QueuePosition);
+public record QueuePlayerDto(string Id, string Name, string Avatar, string? AvatarImage, int Level);
+public record MatchmakingStateDto(string Phase, int Players, int? QueuePosition, QueuePlayerDto[]? Queue = null);
public record ReactionDto(int Seat, string Reaction);
public static class Map
diff --git a/server/src/Hokm.Server/Game/GameManager.cs b/server/src/Hokm.Server/Game/GameManager.cs
index ef39b66..15fa8f3 100644
--- a/server/src/Hokm.Server/Game/GameManager.cs
+++ b/server/src/Hokm.Server/Game/GameManager.cs
@@ -88,13 +88,16 @@ public sealed partial class GameManager
}
}
- /// Push the current queue size to every waiting player (call inside _mmLock).
+ /// Push the current queue size + player list to every waiting player (call inside _mmLock).
private void BroadcastQueueLocked()
{
- int n = _waiting.Count;
+ var queue = _waiting
+ .Select(w => new QueuePlayerDto(w.player.UserId, w.player.Name, w.player.Avatar, w.player.AvatarImage, w.player.Level))
+ .ToArray();
+ int n = queue.Length;
foreach (var w in _waiting)
_ = _hub.Clients.User(w.player.UserId).SendAsync("matchmaking",
- new MatchmakingStateDto("searching", n, null));
+ new MatchmakingStateDto("searching", n, null, queue));
}
/// Client safety net: re-send the current game state to a player who
diff --git a/src/lib/online/signalr-service.ts b/src/lib/online/signalr-service.ts
index 663f649..1478a58 100644
--- a/src/lib/online/signalr-service.ts
+++ b/src/lib/online/signalr-service.ts
@@ -159,8 +159,9 @@ export class SignalrService implements OnlineService {
.configureLogging(signalR.LogLevel.Warning)
.build();
- conn.on("matchmaking", (s: { phase: string; players: number; queuePosition: number | null }) =>
- this.emitMM(s.phase, s.queuePosition ?? undefined, s.players));
+ conn.on("matchmaking", (s: { phase: string; players: number; queuePosition: number | null; queue?: Array<{ id: string; name: string; avatar: string; avatarImage?: string; level: number }> }) =>
+ this.emitMM(s.phase, s.queuePosition ?? undefined, s.players,
+ s.queue?.map(p => ({ id: p.id, displayName: p.name, avatar: p.avatar, avatarImage: p.avatarImage, level: p.level, rating: 0 }))));
conn.on("matchFound", () => {
this.emitMM("ready");
// Safety net: if the initial state never lands (dropped/raced), ask the
@@ -226,10 +227,15 @@ export class SignalrService implements OnlineService {
}
}
- private emitMM(phase: string, queuePosition?: number, waiting?: number) {
+ private emitMM(
+ phase: string,
+ queuePosition?: number,
+ waiting?: number,
+ queuePlayers?: Array<{ id: string; displayName: string; avatar: string; avatarImage?: string; level: number; rating: number }>
+ ) {
const state: MatchmakingState = {
phase: phase as MatchmakingState["phase"],
- players: [],
+ players: queuePlayers ?? [],
elapsedMs: 0,
ranked: this.mmRanked,
stake: this.mmStake,