Skip to content

Commit a417d6a

Browse files
committed
feat: fix GetPlayerTopTimes ties (didn't account for them)
1 parent 1d12739 commit a417d6a

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

services/map-service/api/v3/intnl/server_leaderboard.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,21 @@ func (s *server) GetPlayerTopTimes(ctx context.Context, request GetPlayerTopTime
259259
}
260260

261261
// Use a redis pipeline to avoid network rtt
262+
// Use ZCOUNT to count players with strictly lower times (to handle ties).
263+
// E.g. if 6 players share the same time, ZCOUNT returns 0 for all of them, so they all get rank 1.
262264
cmds := make(rueidis.Commands, len(bestTimes))
263265
for i, bt := range bestTimes {
264266
leaderboardKey := mapLeaderboardKey(bt.MapID, "playtime")
265-
cmds[i] = s.redis.B().Zrank().Key(leaderboardKey).
266-
Member(string(common.UUIDToBin(request.PlayerId))).Build()
267+
roundedPlaytime := int(math.Round(float64(bt.Playtime)/50.0)) * 50
268+
threshold := roundedPlaytime - 25
269+
cmds[i] = s.redis.B().Zcount().Key(leaderboardKey).
270+
Min("-inf").Max(fmt.Sprintf("(%d", threshold)).Build()
267271
}
268272

269273
// Exec pipeline
270274
results := s.redis.DoMulti(ctx, cmds...)
271275

272-
// Collect only entries with valid ranks (!= -1)
276+
// Collect entries - ZCOUNT returns the count of players with better times
273277
type rankedEntry struct {
274278
MapID string
275279
PublishedID int
@@ -279,11 +283,7 @@ func (s *server) GetPlayerTopTimes(ctx context.Context, request GetPlayerTopTime
279283
}
280284
var entries []rankedEntry
281285
for i, resp := range results {
282-
rank, err := resp.AsInt64()
283-
if errors.Is(err, rueidis.Nil) {
284-
// Player not on this leaderboard, skip
285-
continue
286-
}
286+
betterCount, err := resp.AsInt64()
287287
if err != nil {
288288
s.log.Warnw("failed to get rank for map", "mapId", bestTimes[i].MapID, "error", err)
289289
continue
@@ -299,12 +299,14 @@ func (s *server) GetPlayerTopTimes(ctx context.Context, request GetPlayerTopTime
299299
publishedID = *bestTimes[i].PublishedID
300300
}
301301

302+
// Round playtime to 50ms for display (consistent with rank calculation)
303+
roundedPlaytime := int(math.Round(float64(bestTimes[i].Playtime)/50.0)) * 50
302304
entries = append(entries, rankedEntry{
303305
MapID: bestTimes[i].MapID,
304306
PublishedID: publishedID,
305307
MapName: mapName,
306-
Playtime: bestTimes[i].Playtime,
307-
Rank: int(rank) + 1, // Convert 0-indexed to 1-indexed
308+
Playtime: roundedPlaytime,
309+
Rank: int(betterCount) + 1, // Rank = count of better times + 1
308310
})
309311
}
310312

0 commit comments

Comments
 (0)