From bd5851aad0ac0175595b110901907dc02ce66a3e Mon Sep 17 00:00:00 2001 From: Efnilite <35348263+Efnilite@users.noreply.github.com> Date: Mon, 22 Jan 2024 22:03:35 +0100 Subject: [PATCH 1/4] Added score time format --- .../java/dev/efnilite/ip/config/Option.java | 7 ++-- .../ip/generator/ParkourGenerator.java | 34 +++++++++++++++---- .../java/dev/efnilite/ip/hook/PAPIHook.java | 2 +- .../dev/efnilite/ip/leaderboard/Score.java | 11 ++---- .../ip/menu/settings/ParkourSettingsMenu.java | 8 ++--- .../dev/efnilite/ip/player/ParkourUser.java | 2 +- src/main/resources/config.yml | 4 +++ 7 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/main/java/dev/efnilite/ip/config/Option.java b/src/main/java/dev/efnilite/ip/config/Option.java index 1bc008fd..d8d8c475 100644 --- a/src/main/java/dev/efnilite/ip/config/Option.java +++ b/src/main/java/dev/efnilite/ip/config/Option.java @@ -44,7 +44,8 @@ public class Option { public static boolean INVENTORY_SAVING; public static String ALT_INVENTORY_SAVING_COMMAND; - public static int OPTIONS_TIME_FORMAT; + public static int TIME_FORMAT; + public static String SCORE_TIME_FORMAT; public static Map OPTIONS_ENABLED; public static Map OPTIONS_DEFAULTS; @@ -87,7 +88,9 @@ public static void init(boolean firstLoad) { // Options - OPTIONS_TIME_FORMAT = Config.CONFIG.getInt("options.time.format"); + TIME_FORMAT = Config.CONFIG.getInt("options.time.format"); + SCORE_TIME_FORMAT = Config.CONFIG.getString("options.time.score-format"); + HEALTH_HANDLING = Config.CONFIG.getBoolean("options.health-handling"); INVENTORY_SAVING = Config.CONFIG.getBoolean("options.inventory-saving"); ALT_INVENTORY_SAVING_COMMAND = Config.CONFIG.getString("options.alt-inventory-saving-command"); diff --git a/src/main/java/dev/efnilite/ip/generator/ParkourGenerator.java b/src/main/java/dev/efnilite/ip/generator/ParkourGenerator.java index c87d8ec6..7da80741 100644 --- a/src/main/java/dev/efnilite/ip/generator/ParkourGenerator.java +++ b/src/main/java/dev/efnilite/ip/generator/ParkourGenerator.java @@ -39,8 +39,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.time.Duration; import java.time.Instant; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; import java.util.*; /** @@ -513,7 +514,6 @@ public void reset(boolean regenerate) { Leaderboard leaderboard = getMode().getLeaderboard(); int record = leaderboard != null ? leaderboard.get(player.getUUID()).score() : 0; - String time = getTime(); if (profile.get("showFallMessage").asBoolean()) { String message; @@ -532,7 +532,7 @@ int record = leaderboard != null ? leaderboard.get(player.getUUID()).score() : 0 for (ParkourPlayer players : getPlayers()) { players.sendTranslated("settings.parkour_settings.items.fall_message.divider"); players.sendTranslated("settings.parkour_settings.items.fall_message.score", Integer.toString(score)); - players.sendTranslated("settings.parkour_settings.items.fall_message.time", time); + players.sendTranslated("settings.parkour_settings.items.fall_message.time", getFormattedTime()); players.sendTranslated("settings.parkour_settings.items.fall_message.high_score", Integer.toString(record)); players.sendTranslated(message, Integer.toString(number)); players.sendTranslated("settings.parkour_settings.items.fall_message.divider"); @@ -540,7 +540,7 @@ int record = leaderboard != null ? leaderboard.get(player.getUUID()).score() : 0 } if (leaderboard != null && score > record) { - registerScore(getTime(), Double.toString(getDifficultyScore()).substring(0, 3), score); + registerScore(getDetailedTime(), Double.toString(getDifficultyScore()).substring(0, 3), score); } score = 0; @@ -766,10 +766,30 @@ public double getDifficultyScore() { } /** - * @return The current duration of the run. + * @return The time in custom format. */ - public String getTime() { - return Score.timeFromMillis(start != null ? (int) Duration.between(start, Instant.now()).toMillis() : 0); + public String getFormattedTime() { + return getTime(Option.SCORE_TIME_FORMAT); + } + + /** + * @return The current detailed duration of the run. + */ + public String getDetailedTime() { + return getTime("mm:ss:SSS"); + } + + private String getTime(String format) { + var timeMs = Instant.now().minusMillis(start != null ? start.toEpochMilli() : 0); + + try { + return DateTimeFormatter.ofPattern(format) + .withZone(ZoneOffset.UTC) + .format(timeMs); + } catch (IllegalArgumentException ex) { + IP.logging().stack("Invalid score time format %s".formatted(Option.SCORE_TIME_FORMAT), ex); + return ""; + } } /** diff --git a/src/main/java/dev/efnilite/ip/hook/PAPIHook.java b/src/main/java/dev/efnilite/ip/hook/PAPIHook.java index ca31c2e6..5c32c6dd 100644 --- a/src/main/java/dev/efnilite/ip/hook/PAPIHook.java +++ b/src/main/java/dev/efnilite/ip/hook/PAPIHook.java @@ -109,7 +109,7 @@ public String onPlaceholderRequest(Player player, @NotNull String params) { return Integer.toString(generator.score); } case "time", "current_time" -> { - return generator.getTime(); + return generator.getFormattedTime(); } case "blocklead", "lead" -> { return Integer.toString(pp.blockLead); diff --git a/src/main/java/dev/efnilite/ip/leaderboard/Score.java b/src/main/java/dev/efnilite/ip/leaderboard/Score.java index f5d7932a..b306f28b 100644 --- a/src/main/java/dev/efnilite/ip/leaderboard/Score.java +++ b/src/main/java/dev/efnilite/ip/leaderboard/Score.java @@ -12,11 +12,6 @@ */ public record Score(String name, String time, String difficulty, int score) { - /** - * The character used for splitting in strings - */ - private static final String SPLITTER = ","; - /** * Gets a {@link Score} instance from a string * @@ -24,7 +19,7 @@ public record Score(String name, String time, String difficulty, int score) { * @return a {@link Score} instance based off the provided string */ public static Score fromString(String string) { - String[] parts = string.split(SPLITTER); + String[] parts = string.split(","); return new Score(parts[0], parseV1Score(parts[1]), parts[2], Integer.parseInt(parts[3])); } @@ -33,7 +28,7 @@ public static Score fromString(String string) { * @param old The old score format. * @return The new score format. */ - public static String parseV1Score(String old) { + private static String parseV1Score(String old) { if (old.contains(":")) { return old; } @@ -90,6 +85,6 @@ public int getTimeMillis() { @Override public String toString() { - return String.format("%s%s%s%s%s%s%s", name, SPLITTER, time, SPLITTER, difficulty, SPLITTER, score); + return String.format("%s,%s,%s,%s", name, time, difficulty, score); } } \ No newline at end of file diff --git a/src/main/java/dev/efnilite/ip/menu/settings/ParkourSettingsMenu.java b/src/main/java/dev/efnilite/ip/menu/settings/ParkourSettingsMenu.java index 580d12bd..ac9a6f08 100644 --- a/src/main/java/dev/efnilite/ip/menu/settings/ParkourSettingsMenu.java +++ b/src/main/java/dev/efnilite/ip/menu/settings/ParkourSettingsMenu.java @@ -126,16 +126,16 @@ public ParkourSettingsMenu(ParkourOption... disabled) { return new SliderItem() .initial(times.indexOf(player.selectedTime)) .add(0, item.clone() - .modifyLore(line -> line.replace("%s", Option.OPTIONS_TIME_FORMAT == 12 ? "12:00 AM" : "00:00")), + .modifyLore(line -> line.replace("%s", Option.TIME_FORMAT == 12 ? "12:00 AM" : "00:00")), event -> handleSettingChange(player, () -> player.selectedTime = 0)) .add(1, item.clone() - .modifyLore(line -> line.replace("%s", Option.OPTIONS_TIME_FORMAT == 12 ? "6:00 AM" : "6:00")), + .modifyLore(line -> line.replace("%s", Option.TIME_FORMAT == 12 ? "6:00 AM" : "6:00")), event -> handleSettingChange(player, () -> player.selectedTime = 6000)) .add(2, item.clone() - .modifyLore(line -> line.replace("%s", Option.OPTIONS_TIME_FORMAT == 12 ? "12:00 PM" : "12:00")), + .modifyLore(line -> line.replace("%s", Option.TIME_FORMAT == 12 ? "12:00 PM" : "12:00")), event -> handleSettingChange(player, () -> player.selectedTime = 12000)) .add(3, item.clone() - .modifyLore(line -> line.replace("%s", Option.OPTIONS_TIME_FORMAT == 12 ? "6:00 PM" : "18:00")), + .modifyLore(line -> line.replace("%s", Option.TIME_FORMAT == 12 ? "6:00 PM" : "18:00")), event -> handleSettingChange(player, () -> player.selectedTime = 18000)); }, player -> checkOptions(player, ParkourOption.TIME, disabled)); diff --git a/src/main/java/dev/efnilite/ip/player/ParkourUser.java b/src/main/java/dev/efnilite/ip/player/ParkourUser.java index 94af43e4..c52074dc 100644 --- a/src/main/java/dev/efnilite/ip/player/ParkourUser.java +++ b/src/main/java/dev/efnilite/ip/player/ParkourUser.java @@ -283,7 +283,7 @@ private List replace(List s, Score top, Score high, ParkourGener private String replace(String s, Score top, Score high, ParkourGenerator generator) { return Strings.colour(translate(player, s) .replace("%score%", Integer.toString(generator.score)) - .replace("%time%", generator.getTime()) + .replace("%time%", generator.getFormattedTime()) .replace("%difficulty%", Double.toString(generator.getDifficultyScore())) .replace("%top_score%", Integer.toString(top.score())) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0498ea80..075444ff 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -136,6 +136,10 @@ options: # 12 - 12 hour clock. (12:00 AM, 12:00 PM, 11:59 PM) format: 24 + # -= Score time format =- + # H = hours, m = minutes, s = seconds, S = milliseconds + score-format: "mm:ss:SSS" + # -= Inventory handling =- # Toggles the inventory handling system. # True = players' inventories get saved and cleared when they join the parkour and when they leave they get their items back From bef4e63c9afb8ad948440cb64ba8eb698055d244 Mon Sep 17 00:00:00 2001 From: Efnilite <35348263+Efnilite@users.noreply.github.com> Date: Sat, 27 Jan 2024 21:15:48 +0100 Subject: [PATCH 2/4] Update permission in config --- .../dev/efnilite/ip/leaderboard/Score.java | 49 +------------------ .../dev/efnilite/ip/world/WorldManagerMV.java | 2 +- src/main/resources/config.yml | 2 +- src/test/java/dev/efnilite/ip/ScoreTest.java | 14 ------ 4 files changed, 3 insertions(+), 64 deletions(-) diff --git a/src/main/java/dev/efnilite/ip/leaderboard/Score.java b/src/main/java/dev/efnilite/ip/leaderboard/Score.java index a8a36b98..cc46ea90 100644 --- a/src/main/java/dev/efnilite/ip/leaderboard/Score.java +++ b/src/main/java/dev/efnilite/ip/leaderboard/Score.java @@ -1,7 +1,5 @@ package dev.efnilite.ip.leaderboard; -import dev.efnilite.vilib.util.Time; - /** * Represents a record, used to keep track of the score a player may achieve. * @@ -21,52 +19,7 @@ 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], parseV1Score(parts[1]), parts[2], Integer.parseInt(parts[3])); - } - - /** - * Legacy migration. - * @param old The old score format. - * @return The new score format. - */ - private static String parseV1Score(String old) { - if (old.contains(":")) { - return old; - } - - double totalSec = 0; // total duration in ms - - for (String part : old.trim().split(" ")) { - if (part.contains("h")) { - totalSec += Integer.parseInt(part.replace("h", "")) * Time.SECONDS_PER_HOUR; - } else if (part.contains("m")) { - totalSec += Integer.parseInt(part.replace("m", "")) * Time.SECONDS_PER_MINUTE; - } else if (part.contains("s")) { - totalSec += Double.parseDouble(part.replace("s", "")); - } - } - - return timeFromMillis((int) (totalSec * 1000)); - } - - /** - * @param ms The duration in millis. - * @return The formatted time. - */ - public static String timeFromMillis(int ms) { - int m = ms / (60 * 1000); - ms -= (m * 60 * 1000); - - int s = ms / 1000; - ms -= (s * 1000); - - return "%s:%s:%s".formatted(padLeft(Integer.toString(m), (m < 10) ? 1 : 0), - padLeft(Integer.toString(s), (s < 10) ? 1 : 0), - padLeft(Integer.toString(ms), (ms < 100) ? 2 : 0)); - } - - private static String padLeft(String s, int extraZeroes) { - return extraZeroes > 0 ? String.format("%" + (extraZeroes + 1) + "s", s).replace(" ", "0") : s; + return new Score(parts[0], parts[1], parts[2], Integer.parseInt(parts[3])); } /** diff --git a/src/main/java/dev/efnilite/ip/world/WorldManagerMV.java b/src/main/java/dev/efnilite/ip/world/WorldManagerMV.java index 550b2776..5d0c380f 100644 --- a/src/main/java/dev/efnilite/ip/world/WorldManagerMV.java +++ b/src/main/java/dev/efnilite/ip/world/WorldManagerMV.java @@ -29,7 +29,7 @@ public World createWorld() { return null; } - MANAGER.addWorld(Option.WORLD_NAME, World.Environment.NORMAL, null, WorldType.FLAT, false, VoidGenerator.getMultiverseGenerator()); + MANAGER.addWorld(Option.WORLD_NAME, World.Environment.NORMAL, null, WorldType.NORMAL, false, VoidGenerator.getMultiverseGenerator()); MultiverseWorld world = MANAGER.getMVWorld(Option.WORLD_NAME); // optimizations to reduce memory usage diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0ed4afa3..00c735b6 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -178,7 +178,7 @@ permissions: # -= Per style permissions =- # Gives every style a permission. The permission is the name of the style. - # Syntax: ip.option.styles.