diff --git a/build.gradle.kts b/build.gradle.kts index ecb8003..4be6dce 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,11 +1,11 @@ plugins { java - id("xyz.jpenilla.run-paper") version "2.3.0" - id("com.gradleup.shadow") version "9.3.1" + id("xyz.jpenilla.run-paper") version "3.0.2" + id("com.gradleup.shadow") version "9.6.1" } group = "io.github.md5sha256" -version = "1.0.1-SNAPSHOT" +version = "1.1.0-SNAPSHOT" repositories { mavenCentral() @@ -48,7 +48,7 @@ repositories { dependencies { compileOnly("io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT") compileOnly("com.arcaniax:HeadDatabase-API:1.3.2") - compileOnly("com.github.MilkBowl:VaultAPI:1.7") { + compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") { exclude(group = "org.bukkit", module = "bukkit") exclude(group = "org.spigotmc", module = "spigot-api") exclude(group = "io.papermc.paper", module = "paper-api") @@ -59,24 +59,24 @@ dependencies { exclude(group = "io.papermc.paper", module = "paper-api") } // Provided by spigot library - compileOnly("org.mariadb.jdbc:mariadb-java-client:3.4.0") - compileOnly("com.zaxxer:HikariCP:5.1.0") + compileOnly("org.mariadb.jdbc:mariadb-java-client:3.5.10") + compileOnly("com.zaxxer:HikariCP:7.1.0") // Shaded libs implementation("de.themoep:inventorygui:1.6.1-SNAPSHOT") - implementation("org.spongepowered:configurate-yaml:4.1.2") - implementation("org.spongepowered:configurate-gson:4.1.2") - implementation("org.incendo:cloud-paper:2.0.0-beta.10") { + implementation("org.spongepowered:configurate-yaml:4.2.0") + implementation("org.spongepowered:configurate-gson:4.2.0") + implementation("org.incendo:cloud-paper:2.0.0") { exclude("com.google.guava") } implementation("org.incendo:cloud-processors-confirmation:1.0.0-rc.1") { exclude("com.google.guava") } - implementation("org.incendo:cloud-annotations:2.0.0") { + implementation("org.incendo:cloud-annotations:2.1.0") { exclude("com.google.guava") } - testImplementation(platform("org.junit:junit-bom:5.10.2")) + testImplementation(platform("org.junit:junit-bom:6.1.2")) testImplementation("org.junit.jupiter:junit-jupiter") - testRuntimeOnly("org.junit.vintage:junit-vintage-engine") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") } val targetJavaVersion = 21 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e644113..8bdaf60 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2dcec85..a351597 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a4..ef07e01 100644 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -203,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -211,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 25da30d..db3a6ac 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/main/java/io/github/md5sha256/democracypost/PostSettings.java b/src/main/java/io/github/md5sha256/democracypost/PostSettings.java index 57fc08d..af8ebbe 100644 --- a/src/main/java/io/github/md5sha256/democracypost/PostSettings.java +++ b/src/main/java/io/github/md5sha256/democracypost/PostSettings.java @@ -5,7 +5,11 @@ import org.spongepowered.configurate.objectmapping.meta.Setting; import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.time.Duration; +import java.util.Locale; @ConfigSerializable public record PostSettings( @@ -13,9 +17,28 @@ public record PostSettings( @Setting @Required long returnPackageExpirySeconds, @Setting @Required long expiryNotificationExpiryThresholdSeconds, @Setting @Required double postPrice, - @Setting @Required boolean skipUndeserializableItems + @Setting @Required boolean skipUndeserializableItems, + @Setting @Nullable String priceFormatPattern ) { + /** + * Pattern used when none is configured. Any literal prefix/suffix in the pattern is used + * verbatim, so the currency symbol can be replaced by editing the pattern. + */ + public static final String DEFAULT_PRICE_FORMAT_PATTERN = "$#,##0.00"; + + /** + * Formats the given amount using the configured {@link #priceFormatPattern()}. + */ + @Nonnull + public String formatPrice(double amount) { + String pattern = this.priceFormatPattern == null || this.priceFormatPattern.isEmpty() + ? DEFAULT_PRICE_FORMAT_PATTERN + : this.priceFormatPattern; + DecimalFormat format = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance(Locale.ROOT)); + return format.format(amount); + } + @Nonnull public Duration packageExpiryDuration() { return Duration.ofSeconds(this.packageExpirySeconds); diff --git a/src/main/java/io/github/md5sha256/democracypost/ui/PostOfficeMenu.java b/src/main/java/io/github/md5sha256/democracypost/ui/PostOfficeMenu.java index 108eac0..25209ca 100644 --- a/src/main/java/io/github/md5sha256/democracypost/ui/PostOfficeMenu.java +++ b/src/main/java/io/github/md5sha256/democracypost/ui/PostOfficeMenu.java @@ -40,8 +40,6 @@ import javax.annotation.Nonnull; import java.sql.SQLException; import java.text.DateFormat; -import java.text.DecimalFormat; -import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.ArrayDeque; import java.util.ArrayList; @@ -53,7 +51,6 @@ import java.util.function.Consumer; public class PostOfficeMenu { - private static final NumberFormat PRICE_FORMAT = NumberFormat.getCurrencyInstance(); private final JavaPlugin plugin; private final ConversationFactory conversationFactory; @@ -285,8 +282,7 @@ private ItemStack createSendPackageIcon() { Component displayName = this.messageContainer.messageFor("menu.parcel.post-parcel") .decoration(TextDecoration.ITALIC, false); meta.displayName(displayName); - double price = this.postSettings.postPrice(); - String formattedPrice = PRICE_FORMAT.format(price); + String formattedPrice = this.postSettings.formatPrice(this.postSettings.postPrice()); Component priceIndicator = this.messageContainer.messageFor("menu.parcel.post-parcel-price") .replaceText(builder -> builder.matchLiteral("%price%").replacement(formattedPrice)) .decoration(TextDecoration.ITALIC, false); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 090e619..9d1688b 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -15,5 +15,5 @@ commands: permission: "democracypost.view" libraries: - - 'org.mariadb.jdbc:mariadb-java-client:3.4.0' - - 'com.zaxxer:HikariCP:5.1.0' \ No newline at end of file + - 'org.mariadb.jdbc:mariadb-java-client:3.5.10' + - 'com.zaxxer:HikariCP:7.1.0' \ No newline at end of file diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml index d624596..9674aa0 100644 --- a/src/main/resources/settings.yml +++ b/src/main/resources/settings.yml @@ -14,6 +14,9 @@ post-settings: expiry-notification-expiry-threshold-seconds: 259200 post-price: 0.50 skip-undeserializable-items: true + # java.text.DecimalFormat pattern used to render prices. + # Any literal text around the number is kept as-is, so replace the '$' to change the currency symbol. + price-format-pattern: '$#,##0.00' save-duration-seconds: 600 join-message-delay-seconds: 10