From 282ec81af14a0566187f9015f7b1745971f11685 Mon Sep 17 00:00:00 2001 From: Ali Moghnieh Date: Sun, 19 Jun 2016 20:03:54 +0100 Subject: [PATCH] Implement configurable currency formatting. This commit enables users of different countries around the world to configure currency formatting displayed to users in a familiar manner. Prior to this commit US formatting (symbols) was forced upon users. This is now configurable via locale values e.g. en-US, de, fr-ch. This commit adds two new configurations: - currency-format - currency-symbol-format-locale One method ISettings#getCurrencyFormat() --- .../com/earth2me/essentials/ISettings.java | 3 + .../src/com/earth2me/essentials/Settings.java | 56 +++++++++++++++++++ .../earth2me/essentials/utils/NumberUtil.java | 3 + Essentials/src/config.yml | 13 +++++ 4 files changed, 75 insertions(+) diff --git a/Essentials/src/com/earth2me/essentials/ISettings.java b/Essentials/src/com/earth2me/essentials/ISettings.java index c736ad5c2..d84c5a92a 100644 --- a/Essentials/src/com/earth2me/essentials/ISettings.java +++ b/Essentials/src/com/earth2me/essentials/ISettings.java @@ -8,6 +8,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.EventPriority; import java.math.BigDecimal; +import java.text.NumberFormat; import java.util.List; import java.util.Map; import java.util.Set; @@ -243,4 +244,6 @@ public interface ISettings extends IConf { boolean isSendFlyEnableOnJoin(); boolean isWorldTimePermissions(); + + NumberFormat getCurrencyFormat(); } diff --git a/Essentials/src/com/earth2me/essentials/Settings.java b/Essentials/src/com/earth2me/essentials/Settings.java index 413809e26..94532c27d 100644 --- a/Essentials/src/com/earth2me/essentials/Settings.java +++ b/Essentials/src/com/earth2me/essentials/Settings.java @@ -6,6 +6,8 @@ import com.earth2me.essentials.signs.Signs; import com.earth2me.essentials.textreader.IText; import com.earth2me.essentials.textreader.SimpleTextInput; import com.earth2me.essentials.utils.FormatUtil; +import com.earth2me.essentials.utils.NumberUtil; + import net.ess3.api.IEssentials; import org.bukkit.ChatColor; import org.bukkit.configuration.ConfigurationSection; @@ -14,13 +16,22 @@ import org.bukkit.event.EventPriority; import org.bukkit.inventory.ItemStack; import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; import java.util.*; +import java.util.Locale.Category; import java.util.logging.Level; import java.util.logging.Logger; import static com.earth2me.essentials.I18n.tl; +import com.google.common.base.Preconditions; + public class Settings implements net.ess3.api.ISettings { private final transient EssentialsConf config; @@ -532,6 +543,8 @@ public class Settings implements net.ess3.api.ISettings { customQuitMessage = _getCustomQuitMessage(); isCustomQuitMessage = !customQuitMessage.equals("none"); muteCommands = _getMuteCommands(); + + currencyFormat = _getCurrencyFormat(); } private List itemSpawnBl = new ArrayList(); @@ -1163,4 +1176,47 @@ public class Settings implements net.ess3.api.ISettings { public boolean isWorldTimePermissions() { return config.getBoolean("world-time-permissions", false); } + + private NumberFormat currencyFormat; + + private NumberFormat _getCurrencyFormat() { + String currencyFormatString = config.getString("currency-format", "#,##0.00"); + + String symbolLocaleString = config.getString("currency-symbol-format-locale"); + DecimalFormatSymbols decimalFormatSymbols; + if (symbolLocaleString != null) { + decimalFormatSymbols = DecimalFormatSymbols.getInstance(Locale.forLanguageTag(symbolLocaleString)); + } else { + // Fallback to the JVM's default locale + decimalFormatSymbols = DecimalFormatSymbols.getInstance(); + } + + DecimalFormat currencyFormat = new DecimalFormat(currencyFormatString, decimalFormatSymbols); + currencyFormat.setRoundingMode(RoundingMode.FLOOR); + + // Updates NumberUtil#PRETTY_FORMAT field so that all of Essentials + // can follow a single format. + try { + Field field = NumberUtil.class.getDeclaredField("PRETTY_FORMAT"); + field.setAccessible(true); + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + field.set(null, currencyFormat); + modifiersField.setAccessible(false); + field.setAccessible(false); + } catch (NoSuchFieldException | IllegalAccessException e) { + ess.getLogger().severe("Failed to apply custom currency format: " + e.getMessage()); + if (isDebug()) { + e.printStackTrace(); + } + } + + return currencyFormat; + } + + @Override + public NumberFormat getCurrencyFormat() { + return this.currencyFormat; + } } diff --git a/Essentials/src/com/earth2me/essentials/utils/NumberUtil.java b/Essentials/src/com/earth2me/essentials/utils/NumberUtil.java index a9c7d9f75..55f0fa943 100644 --- a/Essentials/src/com/earth2me/essentials/utils/NumberUtil.java +++ b/Essentials/src/com/earth2me/essentials/utils/NumberUtil.java @@ -15,6 +15,9 @@ import static com.earth2me.essentials.I18n.tl; public class NumberUtil { static DecimalFormat twoDPlaces = new DecimalFormat("#,###.##"); static DecimalFormat currencyFormat = new DecimalFormat("#0.00", DecimalFormatSymbols.getInstance(Locale.US)); + + // This field is likely to be modified in com.earth2me.essentials.Settings when loading currency format. + // This ensures that we can supply a constant formatting. static final NumberFormat PRETTY_FORMAT = NumberFormat.getInstance(Locale.US); static { diff --git a/Essentials/src/config.yml b/Essentials/src/config.yml index 5004d8360..e6af2ee0c 100644 --- a/Essentials/src/config.yml +++ b/Essentials/src/config.yml @@ -560,6 +560,19 @@ use-bukkit-permissions: false # Minimum acceptable amount to be used in /pay. minimum-pay-amount: 0.001 +# The format of currency, excluding symbols. See currency-sumbol-format-locale for symbol configuration. +# +# "#,##0.00" is how the majority of countries display currency. +#currency-format: "#,##0.00" + +# Format currency symbols. Some locales use , and . interchangeably. +# Some formats do not display properly in-game due to faulty Minecraft font rendering. +# +# For 1.234,50 use de-DE +# For 1,234.50 use en-US +# For 1'234,50 use fr-ch +#currency-symbol-format-locale: en-US + ############################################################ # +------------------------------------------------------+ # # | EssentialsHelp | #