From e5dd567ca9342b11745963bcecc07e7d5ec72c90 Mon Sep 17 00:00:00 2001 From: loki Date: Thu, 9 Apr 2026 12:02:01 +0200 Subject: [PATCH] Fix critical bugs and Caffeine ClassNotFoundException - Disabled minimize in shadowJar (was removing Caffeine's dynamic classes) - Fixed Score.fromString() ArrayIndexOutOfBoundsException - Fixed Leaderboard DIFFICULTY sort NumberFormatException - Fixed PAPIHook parsing errors (difficulty, score_until, rank) - Fixed HoloHook parsing errors (rank, difficulty) - Added proper error handling for all Integer/Double.parseX() calls --- build.gradle.kts | 11 ++-- .../dev/loki/loparkour/hook/HoloHook.java | 17 +++++- .../dev/loki/loparkour/hook/PAPIHook.java | 52 +++++++++++++------ .../loparkour/leaderboard/Leaderboard.java | 15 +++++- .../dev/loki/loparkour/leaderboard/Score.java | 10 +++- 5 files changed, 78 insertions(+), 27 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0c678f0..862aa4f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -113,11 +113,12 @@ tasks.shadowJar { relocate("com.google.gson", "dev.loki.loparkour.lib.gson") relocate("org.bstats", "dev.loki.loparkour.lib.bstats") - // Minimize jar size (keep JDBC pool + driver intact) - minimize { - exclude(dependency("com.zaxxer:HikariCP:.*")) - exclude(dependency("com.mysql:mysql-connector-j:.*")) - } + // Don't minimize - causes issues with Caffeine's dynamically generated classes + // minimize { + // exclude(dependency("com.zaxxer:HikariCP:.*")) + // exclude(dependency("com.mysql:mysql-connector-j:.*")) + // exclude(dependency(files("libs/lolib-3.0.0.jar"))) + // } } tasks.named("build") { diff --git a/src/main/java/dev/loki/loparkour/hook/HoloHook.java b/src/main/java/dev/loki/loparkour/hook/HoloHook.java index d48ff02..dffec1b 100644 --- a/src/main/java/dev/loki/loparkour/hook/HoloHook.java +++ b/src/main/java/dev/loki/loparkour/hook/HoloHook.java @@ -47,7 +47,12 @@ public class HoloHook { String type = split[1].toLowerCase(); String rank = split[2].replace("#", ""); - Score score = leaderboard.getScoreAtRank(Integer.parseInt(rank)); + Score score; + try { + score = leaderboard.getScoreAtRank(Integer.parseInt(rank)); + } catch (NumberFormatException e) { + return "?"; + } if (score == null) { return "?"; @@ -69,7 +74,15 @@ public class HoloHook { return "?"; } - double difficulty = Double.parseDouble(string); + try { + double difficulty = Double.parseDouble(string); + return parseDifficultyValue(difficulty); + } catch (NumberFormatException e) { + return "?"; + } + } + + private static String parseDifficultyValue(double difficulty) { if (difficulty <= 0.25) { return "easy"; } else if (difficulty <= 0.5) { diff --git a/src/main/java/dev/loki/loparkour/hook/PAPIHook.java b/src/main/java/dev/loki/loparkour/hook/PAPIHook.java index 672bf24..9d82ccf 100644 --- a/src/main/java/dev/loki/loparkour/hook/PAPIHook.java +++ b/src/main/java/dev/loki/loparkour/hook/PAPIHook.java @@ -74,7 +74,17 @@ public class PAPIHook extends PlaceholderExpansion { return getInfiniteScore(params.replace("difficulty_rank_", ""), Score::difficulty); } else if (params.contains("difficulty_string_rank_")) { return getInfiniteScore(params.replace("difficulty_string_rank_", ""), - score -> parseDifficulty(Double.parseDouble(score.difficulty().contains("?") ? "2" : score.difficulty()))); + score -> { + String diff = score.difficulty(); + if ("?".equals(diff)) { + return parseDifficulty(2.0); + } + try { + return parseDifficulty(Double.parseDouble(diff)); + } catch (NumberFormatException e) { + return parseDifficulty(2.0); + } + }); } // placeholders that require player @@ -132,10 +142,14 @@ public class PAPIHook extends PlaceholderExpansion { default -> { if (params.contains("score_until_")) { String replaced = params.replace("score_until_", ""); - int interval = Integer.parseInt(replaced); - if (interval > 0) { - return Integer.toString(interval - (generator.state.score % interval)); - } else { + try { + int interval = Integer.parseInt(replaced); + if (interval > 0) { + return Integer.toString(interval - (generator.state.score % interval)); + } else { + return "0"; + } + } catch (NumberFormatException e) { return "0"; } } @@ -164,20 +178,24 @@ public class PAPIHook extends PlaceholderExpansion { Leaderboard leaderboard = null; Matcher matcher = INFINITE_REGEX.matcher(rankData); - // use mode-specific format - // x_mode_rank - if (matcher.matches()) { - String name = matcher.group(1); - rank = Integer.parseInt(matcher.group(2)); + try { + // use mode-specific format + // x_mode_rank + if (matcher.matches()) { + String name = matcher.group(1); + rank = Integer.parseInt(matcher.group(2)); - Mode mode = Registry.getMode(name); - if (mode != null) { - leaderboard = mode.getLeaderboard(); + Mode mode = Registry.getMode(name); + if (mode != null) { + leaderboard = mode.getLeaderboard(); + } + // use generic format + // x_rank + } else { + rank = Integer.parseInt(rankData); } - // use generic format - // x_rank - } else { - rank = Integer.parseInt(rankData); + } catch (NumberFormatException e) { + return "?"; } if (leaderboard == null) { diff --git a/src/main/java/dev/loki/loparkour/leaderboard/Leaderboard.java b/src/main/java/dev/loki/loparkour/leaderboard/Leaderboard.java index 3f878fa..f2cd3cb 100644 --- a/src/main/java/dev/loki/loparkour/leaderboard/Leaderboard.java +++ b/src/main/java/dev/loki/loparkour/leaderboard/Leaderboard.java @@ -114,8 +114,19 @@ public class Leaderboard { return Integer.compare(one.getValue().getTimeMillis(), two.getValue().getTimeMillis()); } case DIFFICULTY -> { - return (int) Math.signum(Double.parseDouble(two.getValue().difficulty()) - - Double.parseDouble(one.getValue().difficulty())); + String diff1 = one.getValue().difficulty(); + String diff2 = two.getValue().difficulty(); + + // Handle "?" as lowest difficulty + if ("?".equals(diff1) && "?".equals(diff2)) return 0; + if ("?".equals(diff1)) return 1; + if ("?".equals(diff2)) return -1; + + try { + return (int) Math.signum(Double.parseDouble(diff2) - Double.parseDouble(diff1)); + } catch (NumberFormatException e) { + return 0; + } } default -> throw new IllegalArgumentException("Invalid sort method"); } diff --git a/src/main/java/dev/loki/loparkour/leaderboard/Score.java b/src/main/java/dev/loki/loparkour/leaderboard/Score.java index 0d8e098..327ef20 100644 --- a/src/main/java/dev/loki/loparkour/leaderboard/Score.java +++ b/src/main/java/dev/loki/loparkour/leaderboard/Score.java @@ -19,7 +19,15 @@ public record Score(String name, String time, String difficulty, int score) { public static Score fromString(String string) { String[] parts = string.split(","); - return new Score(parts[0], parts[1], parts[2], Integer.parseInt(parts[3])); + if (parts.length != 4) { + return new Score("?", "?", "?", 0); + } + + try { + return new Score(parts[0], parts[1], parts[2], Integer.parseInt(parts[3])); + } catch (NumberFormatException e) { + return new Score(parts[0], parts[1], parts[2], 0); + } } /**