summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrakenied <Krakenied1@gmail.com>2024-06-14 18:57:24 +0200
committerKrakenied <46192742+Krakenied@users.noreply.github.com>2024-08-28 11:37:11 +0200
commit16aaa5371942cb689d0be13e96ed31c0d66c4b11 (patch)
tree537b52117d1df4179b3cd6b459345d6c826a4155
parentde2b72083c83a9af9da33f89600aeb20a7225ce3 (diff)
Add number formats
Closes https://github.com/LMBishop/Quests/issues/613
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java124
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java6
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/element/QuestMenuElement.java4
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/itemstack/QItemStack.java9
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java4
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/Format.java20
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/FormatUtils.java59
-rw-r--r--bukkit/src/main/resources/resources/bukkit/config.yml9
8 files changed, 165 insertions, 70 deletions
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java
index 65e9cd07..2cbe540a 100644
--- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java
+++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java
@@ -127,6 +127,7 @@ import com.leonardobishop.quests.bukkit.tasktype.type.dependent.ZNPCsPlusDeliver
import com.leonardobishop.quests.bukkit.tasktype.type.dependent.ZNPCsPlusInteractTaskType;
import com.leonardobishop.quests.bukkit.tasktype.type.dependent.uSkyBlockLevelTaskType;
import com.leonardobishop.quests.bukkit.util.CompatUtils;
+import com.leonardobishop.quests.bukkit.util.FormatUtils;
import com.leonardobishop.quests.bukkit.util.LogHistory;
import com.leonardobishop.quests.common.config.ConfigProblem;
import com.leonardobishop.quests.common.config.ConfigProblemDescriptions;
@@ -303,42 +304,47 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests {
// Setup version specific compatibility layers
int version;
try {
- version = Integer.parseInt(super.getServer().getBukkitVersion().split("\\.", 3)[1]);
- } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
- questsLogger.warning("Failed to resolve server version - some features may not work!");
- version = 0;
- }
+ version = this.getServerVersion();
+ this.questsLogger.info("Your server is running version 1." + version);
+ } catch (final IllegalArgumentException e) {
+ // all server supported versions by Quests fulfill this format,
+ // so we assume that some future version can possibly break it,
+ // and we want to load the latest and not the oldest handler
+ version = Integer.MAX_VALUE;
- questsLogger.info("Your server is running version 1." + version);
+ this.questsLogger.warning("Failed to resolve server version - some features may not work! (" + e.getMessage() + ")");
+ }
// (titles)
- setTitleHandle();
+ this.setTitleHandle();
// (bossbar)
- setBossBarHandle();
+ this.setBossBarHandle();
// (actionbar)
- setActionBarHandle();
+ this.setActionBarHandle();
// (itemstacks)
- setItemGetter();
+ this.setItemGetter();
// (skulls)
- setSkullGetter();
+ this.setSkullGetter();
// (version specific handler)
- // TODO move above to version specific handlers
if (version <= 8) {
- versionSpecificHandler = new VersionSpecificHandler8();
- } else switch (version) {
- case 9, 10 -> versionSpecificHandler = new VersionSpecificHandler9();
- case 11, 12, 13, 14, 15 -> versionSpecificHandler = new VersionSpecificHandler11();
- case 16 -> versionSpecificHandler = new VersionSpecificHandler16();
- case 17, 18, 19 -> versionSpecificHandler = new VersionSpecificHandler17();
- default -> versionSpecificHandler = new VersionSpecificHandler20();
+ this.versionSpecificHandler = new VersionSpecificHandler8();
+ } else {
+ this.versionSpecificHandler = switch (version) {
+ case 9, 10 -> new VersionSpecificHandler9();
+ case 11, 12, 13, 14, 15 -> new VersionSpecificHandler11();
+ case 16 -> new VersionSpecificHandler16();
+ case 17, 18, 19 -> new VersionSpecificHandler17();
+ default -> new VersionSpecificHandler20();
+ };
}
- questsConfig.setItemGetter(itemGetter);
+ // Set item getter to be used by Quests config
+ this.questsConfig.setItemGetter(this.itemGetter);
// Finish module initialisation
this.taskTypeManager = new BukkitTaskTypeManager(this, new HashSet<>(questsConfig.getStringList("options.task-type-exclusions")));
@@ -521,6 +527,33 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests {
});
}
+ /**
+ * Gets the server minor version.
+ *
+ * @return the server minor version
+ * @throws IllegalArgumentException with message set to the bukkit version if it could not be parsed successfully.
+ */
+ private int getServerVersion() throws IllegalArgumentException {
+ final String bukkitVersion = this.getServer().getBukkitVersion();
+
+ final String[] bukkitVersionParts = bukkitVersion.split("\\.", 3);
+ if (bukkitVersionParts.length < 2) {
+ throw new IllegalArgumentException(bukkitVersion, new ArrayIndexOutOfBoundsException());
+ }
+
+ final String minorVersionPart = bukkitVersionParts[1];
+ try {
+ return Integer.parseInt(minorVersionPart);
+ } catch (final NumberFormatException e) {
+ throw new IllegalArgumentException(bukkitVersion, e);
+ }
+ }
+
+ /**
+ * Gets the tasks registration message.
+ *
+ * @return the tasks registration message
+ */
private @NotNull String getRegistrationMessage() {
final int registered = this.taskTypeManager.getRegistered();
final int skipped = this.taskTypeManager.getSkipped();
@@ -613,38 +646,49 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests {
}
private boolean reloadBaseConfiguration() {
- this.validConfiguration = questsConfig.loadConfig();
+ this.validConfiguration = this.questsConfig.loadConfig();
- if (validConfiguration) {
- int loggingLevel = questsConfig.getInt("options.verbose-logging-level", 2);
- questsLogger.setServerLoggingLevel(QuestsLogger.LoggingLevel.fromNumber(loggingLevel));
- boolean logHistoryEnabled = questsConfig.getBoolean("options.record-log-history", true);
- logHistory.setEnabled(logHistoryEnabled);
+ if (this.validConfiguration) {
+ final int loggingLevelNumber = this.questsConfig.getInt("options.verbose-logging-level", 2);
+ final QuestsLogger.LoggingLevel loggingLevel = QuestsLogger.LoggingLevel.fromNumber(loggingLevelNumber);
+ this.questsLogger.setServerLoggingLevel(loggingLevel);
- switch (questsConfig.getString("quest-mode.mode", "normal").toLowerCase()) {
+ final boolean logHistoryEnabled = this.questsConfig.getBoolean("options.record-log-history", true);
+ this.logHistory.setEnabled(logHistoryEnabled);
+
+ //noinspection SwitchStatementWithTooFewBranches
+ switch (this.questsConfig.getString("quest-mode.mode", "normal").toLowerCase()) {
default:
case "normal":
- questController = new NormalQuestController(this);
- //TODO the other one
+ this.questController = new NormalQuestController(this);
+ // TODO the other one
}
- long autoSaveInterval = this.getConfig().getLong("options.performance-tweaking.quest-autosave-interval", 12000);
+ final long autoSaveInterval = this.getConfig().getLong("options.performance-tweaking.quest-autosave-interval", 12000);
try {
- if (questAutoSaveTask != null) questAutoSaveTask.cancel();
- questAutoSaveTask = serverScheduler.runTaskTimer(() -> new QuestsAutoSaveRunnable(this), autoSaveInterval, autoSaveInterval);
- } catch (Exception ex) {
- questsLogger.debug("Cannot cancel and restart quest autosave task");
+ if (this.questAutoSaveTask != null) {
+ this.questAutoSaveTask.cancel();
+ }
+ this.questAutoSaveTask = this.serverScheduler.runTaskTimer(() -> new QuestsAutoSaveRunnable(this), autoSaveInterval, autoSaveInterval);
+ } catch (final Exception e) {
+ this.questsLogger.debug("Cannot cancel and restart quest autosave task");
}
- long queueExecuteInterval = this.getConfig().getLong("options.performance-tweaking.quest-queue-executor-interval", 1);
+ final long queueExecuteInterval = this.getConfig().getLong("options.performance-tweaking.quest-queue-executor-interval", 1);
try {
- if (questQueuePollTask != null) questQueuePollTask.cancel();
- questQueuePollTask = serverScheduler.runTaskTimer(questCompleter, queueExecuteInterval, queueExecuteInterval);
- } catch (Exception ex) {
- questsLogger.debug("Cannot cancel and restart queue executor task");
+ if (this.questQueuePollTask != null) {
+ this.questQueuePollTask.cancel();
+ }
+ this.questQueuePollTask = this.serverScheduler.runTaskTimer(this.questCompleter, queueExecuteInterval, queueExecuteInterval);
+ } catch (final Exception e) {
+ this.questsLogger.debug("Cannot cancel and restart queue executor task");
}
+
+ // Set number formats to be used
+ FormatUtils.setNumberFormats(this);
}
- return validConfiguration;
+
+ return this.validConfiguration;
}
private void generateConfigurations() {
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java
index d0589ee5..6ada4e2a 100644
--- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java
+++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/papi/QuestsPlaceholders.java
@@ -2,7 +2,7 @@ package com.leonardobishop.quests.bukkit.hook.papi;
import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin;
import com.leonardobishop.quests.bukkit.menu.itemstack.QItemStack;
-import com.leonardobishop.quests.bukkit.util.Format;
+import com.leonardobishop.quests.bukkit.util.FormatUtils;
import com.leonardobishop.quests.bukkit.util.Messages;
import com.leonardobishop.quests.bukkit.util.chat.Chat;
import com.leonardobishop.quests.common.enums.QuestStartResult;
@@ -181,7 +181,7 @@ public class QuestsPlaceholders extends PlaceholderExpansion implements Cacheabl
break;
case "cooldown":
if (qPlayer.getQuestProgressFile().getQuestProgress(quest).isCompleted()) {
- final String time = Format.formatTime(TimeUnit.SECONDS.convert(qPlayer.getQuestProgressFile().getCooldownFor(quest), TimeUnit.MILLISECONDS));
+ final String time = FormatUtils.time(TimeUnit.SECONDS.convert(qPlayer.getQuestProgressFile().getCooldownFor(quest), TimeUnit.MILLISECONDS));
if (!time.startsWith("-")) result = time;
} else {
result = "0";
@@ -190,7 +190,7 @@ public class QuestsPlaceholders extends PlaceholderExpansion implements Cacheabl
case "timeleft":
if (qPlayer.hasStartedQuest(quest)) {
long timeLeft = qPlayer.getQuestProgressFile().getTimeRemainingFor(quest);
- result = timeLeft != -1 ? Format.formatTime(TimeUnit.SECONDS.convert(timeLeft, TimeUnit.MILLISECONDS)) : Messages.PLACEHOLDERAPI_NO_TIME_LIMIT.getMessage();
+ result = timeLeft != -1 ? FormatUtils.time(TimeUnit.SECONDS.convert(timeLeft, TimeUnit.MILLISECONDS)) : Messages.PLACEHOLDERAPI_NO_TIME_LIMIT.getMessage();
} else {
result = "0";
}
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/element/QuestMenuElement.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/element/QuestMenuElement.java
index 87e29c87..8b36d01f 100644
--- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/element/QuestMenuElement.java
+++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/element/QuestMenuElement.java
@@ -6,7 +6,7 @@ import com.leonardobishop.quests.bukkit.menu.CancelQMenu;
import com.leonardobishop.quests.bukkit.menu.ClickResult;
import com.leonardobishop.quests.bukkit.menu.QMenu;
import com.leonardobishop.quests.bukkit.menu.itemstack.QItemStack;
-import com.leonardobishop.quests.bukkit.util.Format;
+import com.leonardobishop.quests.bukkit.util.FormatUtils;
import com.leonardobishop.quests.bukkit.util.MenuUtils;
import com.leonardobishop.quests.bukkit.util.Messages;
import com.leonardobishop.quests.bukkit.util.chat.Chat;
@@ -113,7 +113,7 @@ public class QuestMenuElement extends MenuElement {
display = config.getItem("gui.quest-permission-display");
}
} else if (cooldown > 0) {
- placeholders.put("{time}", Format.formatTime(TimeUnit.SECONDS.convert(cooldown, TimeUnit.MILLISECONDS)));
+ placeholders.put("{time}", FormatUtils.time(TimeUnit.SECONDS.convert(cooldown, TimeUnit.MILLISECONDS)));
placeholders.put("{quest}", Chat.legacyStrip(qItemStack.getName()));
placeholders.put("{questid}", quest.getId());
if (plugin.getQItemStackRegistry().hasQuestCooldownItemStack(quest)) {
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/itemstack/QItemStack.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/itemstack/QItemStack.java
index b3a0cade..e5455312 100644
--- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/itemstack/QItemStack.java
+++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/itemstack/QItemStack.java
@@ -1,7 +1,7 @@
package com.leonardobishop.quests.bukkit.menu.itemstack;
import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin;
-import com.leonardobishop.quests.bukkit.util.Format;
+import com.leonardobishop.quests.bukkit.util.FormatUtils;
import com.leonardobishop.quests.bukkit.util.Messages;
import com.leonardobishop.quests.bukkit.util.chat.Chat;
import com.leonardobishop.quests.common.player.QPlayer;
@@ -17,6 +17,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -162,7 +163,9 @@ public class QItemStack {
case "progress" -> {
Object progress = matchedTaskProgress.getProgress();
if (progress instanceof Float || progress instanceof Double || progress instanceof BigDecimal) {
- replacement = String.format("%.2f", ((Number) progress).floatValue());
+ replacement = FormatUtils.floating((Number) progress);
+ } else if (progress instanceof Integer || progress instanceof Long || progress instanceof BigInteger) {
+ replacement = FormatUtils.integral((Number) progress);
} else if (progress != null) {
replacement = String.valueOf(progress);
} else {
@@ -200,7 +203,7 @@ public class QItemStack {
public static String processTimeLeft(String s, Quest quest, QuestProgressFile questProgressFile) {
String timeLeft;
if (quest.isTimeLimitEnabled()) {
- timeLeft = Format.formatTime(TimeUnit.SECONDS.convert(questProgressFile.getTimeRemainingFor(quest), TimeUnit.MILLISECONDS));
+ timeLeft = FormatUtils.time(TimeUnit.SECONDS.convert(questProgressFile.getTimeRemainingFor(quest), TimeUnit.MILLISECONDS));
} else {
timeLeft = Chat.legacyColor(Messages.UI_PLACEHOLDERS_NO_TIME_LIMIT.getMessageLegacyColor());
}
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java
index 3af12c87..5c0356c3 100644
--- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java
+++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java
@@ -10,7 +10,7 @@ import com.leonardobishop.quests.bukkit.api.event.PlayerStopTrackQuestEvent;
import com.leonardobishop.quests.bukkit.api.event.PreStartQuestEvent;
import com.leonardobishop.quests.bukkit.config.BukkitQuestsConfig;
import com.leonardobishop.quests.bukkit.menu.itemstack.QItemStack;
-import com.leonardobishop.quests.bukkit.util.Format;
+import com.leonardobishop.quests.bukkit.util.FormatUtils;
import com.leonardobishop.quests.bukkit.util.Messages;
import com.leonardobishop.quests.bukkit.util.SoundUtils;
import com.leonardobishop.quests.bukkit.util.chat.Chat;
@@ -71,7 +71,7 @@ public class NormalQuestController implements QuestController {
break;
case QUEST_COOLDOWN:
long cooldown = qPlayer.getQuestProgressFile().getCooldownFor(quest);
- questResultMessage = Messages.QUEST_START_COOLDOWN.getMessage().replace("{time}", Format.formatTime(TimeUnit.SECONDS.convert
+ questResultMessage = Messages.QUEST_START_COOLDOWN.getMessage().replace("{time}", FormatUtils.time(TimeUnit.SECONDS.convert
(cooldown, TimeUnit.MILLISECONDS)));
break;
case QUEST_LOCKED:
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/Format.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/Format.java
deleted file mode 100644
index 91a6b265..00000000
--- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/Format.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.leonardobishop.quests.bukkit.util;
-
-public class Format {
-
- public static String formatTime(long sec) {
- long hours = sec / 3600;
- long minutes = (sec % 3600) / 60;
- long seconds = ((sec % 3600) % 60) % 60;
-
- return Messages.TIME_FORMAT.getMessageLegacyColor()
- .replace("{hours}", String.format("%02d", hours))
- .replace("{minutes}", String.format("%02d", minutes))
- .replace("{seconds}", String.format("%02d", seconds));
-// return "{hours}h {minutes}m {seconds}s"
-// .replace("{hours}", String.format("%02d", hours))
-// .replace("{minutes}", String.format("%02d", minutes))
-// .replace("{seconds}", String.format("%02d", seconds));
- }
-
-}
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/FormatUtils.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/FormatUtils.java
new file mode 100644
index 00000000..dd66abc9
--- /dev/null
+++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/FormatUtils.java
@@ -0,0 +1,59 @@
+package com.leonardobishop.quests.bukkit.util;
+
+import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin;
+import com.leonardobishop.quests.common.config.QuestsConfig;
+import org.jetbrains.annotations.NotNull;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+import java.util.logging.Level;
+
+public final class FormatUtils {
+
+ private static DecimalFormat floatingFormat = new DecimalFormat("#,##0.00", DecimalFormatSymbols.getInstance(Locale.US));
+ private static DecimalFormat integralFormat = new DecimalFormat("#,##0", DecimalFormatSymbols.getInstance(Locale.US));
+
+ public static void setNumberFormats(final @NotNull BukkitQuestsPlugin plugin) {
+ floatingFormat = parseFormat(plugin, "floating", floatingFormat);
+ integralFormat = parseFormat(plugin, "integral", integralFormat);
+ }
+
+ private static @NotNull DecimalFormat parseFormat(final @NotNull BukkitQuestsPlugin plugin, final @NotNull String path, final @NotNull DecimalFormat def) {
+ final QuestsConfig config = plugin.getQuestsConfig();
+
+ final String formatString = config.getString("number-formats." + path + ".format", def.toPattern());
+ final String localeString = config.getString("number-formats." + path + ".locale", def.getDecimalFormatSymbols().getLocale().toLanguageTag());
+
+ try {
+ final Locale locale = Locale.forLanguageTag(localeString);
+ final DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
+ return new DecimalFormat(formatString, symbols);
+ } catch (final IllegalArgumentException e) {
+ plugin.getLogger().log(Level.SEVERE, "Could not parse number format: " + formatString, e);
+ return def;
+ }
+ }
+
+ public static @NotNull String floating(final @NotNull Number floating) {
+ return floatingFormat.format(floating);
+ }
+
+ public static @NotNull String integral(final @NotNull Number integral) {
+ return integralFormat.format(integral);
+ }
+
+ public static @NotNull String time(final long totalSeconds) {
+ final long hours = totalSeconds / 3600;
+
+ final long remainingSeconds = totalSeconds % 3600;
+ final long minutes = remainingSeconds / 60;
+ final long seconds = remainingSeconds % 60;
+
+ // {hours}h {minutes}m {seconds}s
+ return Messages.TIME_FORMAT.getMessageLegacyColor()
+ .replace("{hours}", String.format("%02d", hours))
+ .replace("{minutes}", String.format("%02d", minutes))
+ .replace("{seconds}", String.format("%02d", seconds));
+ }
+}
diff --git a/bukkit/src/main/resources/resources/bukkit/config.yml b/bukkit/src/main/resources/resources/bukkit/config.yml
index fc213c26..e22b0566 100644
--- a/bukkit/src/main/resources/resources/bukkit/config.yml
+++ b/bukkit/src/main/resources/resources/bukkit/config.yml
@@ -188,6 +188,15 @@ options:
quest-mode:
mode: "NORMAL" # More modes are a work in progress
+number-formats:
+ # decimal format used for processing float, double and BigDecimal placeholders
+ floating:
+ format: '#,##0.00'
+ locale: 'en-US'
+ # decimal format used for processing int, long and BigInteger placeholders
+ integral:
+ format: '#,##0'
+ locale: 'en-US'
# -----------------------------------------------------------
# Global task configuration