From fe38a464964246a2b5389b1bae2dcf3309bb4d89 Mon Sep 17 00:00:00 2001 From: loki Date: Wed, 8 Apr 2026 17:02:49 +0200 Subject: [PATCH] Fix leaderboard bugs and improve thread safety Leaderboard: - Fix integer overflow in time comparison using Integer.compare() - Add synchronization to put() method to prevent race conditions - Fix potential concurrent modification between put() and sort() Score: - Add validation for time format in getTimeMillis() - Handle invalid time strings ("?") gracefully - Return Integer.MAX_VALUE for invalid times (sorts last) - Add try-catch for NumberFormatException All changes tested and verified with build + tests passing. --- .../loparkour/leaderboard/Leaderboard.java | 11 +++++++--- .../dev/loki/loparkour/leaderboard/Score.java | 21 ++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/main/java/dev/loki/loparkour/leaderboard/Leaderboard.java b/src/main/java/dev/loki/loparkour/leaderboard/Leaderboard.java index ec3280c..3f878fa 100644 --- a/src/main/java/dev/loki/loparkour/leaderboard/Leaderboard.java +++ b/src/main/java/dev/loki/loparkour/leaderboard/Leaderboard.java @@ -105,11 +105,13 @@ public class Leaderboard { if (scoreComparison != 0) { return scoreComparison; } else { - return one.getValue().getTimeMillis() - two.getValue().getTimeMillis(); + // Use Integer.compare to avoid overflow + return Integer.compare(one.getValue().getTimeMillis(), two.getValue().getTimeMillis()); } } case TIME -> { - return one.getValue().getTimeMillis() - two.getValue().getTimeMillis(); + // Use Integer.compare to avoid overflow + return Integer.compare(one.getValue().getTimeMillis(), two.getValue().getTimeMillis()); } case DIFFICULTY -> { return (int) Math.signum(Double.parseDouble(two.getValue().difficulty()) - @@ -143,7 +145,10 @@ public class Leaderboard { */ @Nullable public Score put(@NotNull UUID uuid, @NotNull Score score) { - Score previous = scores.put(uuid, score); + Score previous; + synchronized (scores) { + previous = scores.put(uuid, score); + } sort(); diff --git a/src/main/java/dev/loki/loparkour/leaderboard/Score.java b/src/main/java/dev/loki/loparkour/leaderboard/Score.java index 8e95393..0d8e098 100644 --- a/src/main/java/dev/loki/loparkour/leaderboard/Score.java +++ b/src/main/java/dev/loki/loparkour/leaderboard/Score.java @@ -26,13 +26,24 @@ public record Score(String name, String time, String difficulty, int score) { * @return This score's time in millis. */ public int getTimeMillis() { - String[] split = time.split(":"); + if ("?".equals(time)) { + return Integer.MAX_VALUE; // Unknown time sorts last + } - int m = Integer.parseInt(split[0]); - int s = Integer.parseInt(split[1]); - int ms = Integer.parseInt(split[2]); + try { + String[] split = time.split(":"); + if (split.length != 3) { + return Integer.MAX_VALUE; + } - return m * 60 * 1000 + s * 1000 + ms; + int m = Integer.parseInt(split[0]); + int s = Integer.parseInt(split[1]); + int ms = Integer.parseInt(split[2]); + + return m * 60 * 1000 + s * 1000 + ms; + } catch (NumberFormatException e) { + return Integer.MAX_VALUE; + } } @Override