diff options
Diffstat (limited to 'bukkit/src')
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 |
