Skip to content

Commit 3f0a412

Browse files
KyriakumJRoy
andauthored
Add locale based comma support for /pay (#5962)
Co-authored-by: JRoy <10731363+JRoy@users.noreply.github.com>
1 parent 9590d4c commit 3f0a412

File tree

3 files changed

+133
-32
lines changed

3 files changed

+133
-32
lines changed

Essentials/src/main/java/com/earth2me/essentials/commands/Commandpay.java

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@
1818
import java.util.concurrent.atomic.AtomicBoolean;
1919

2020
public class Commandpay extends EssentialsLoopCommand {
21-
private static final BigDecimal THOUSAND = new BigDecimal(1000);
22-
private static final BigDecimal MILLION = new BigDecimal(1_000_000);
23-
private static final BigDecimal BILLION = new BigDecimal(1_000_000_000);
24-
private static final BigDecimal TRILLION = new BigDecimal(1_000_000_000_000L);
25-
2621
public Commandpay() {
2722
super("pay");
2823
}
@@ -45,34 +40,13 @@ public void run(final Server server, final User user, final String commandLabel,
4540
throw new NotEnoughArgumentsException();
4641
}
4742

48-
BigDecimal tempAmount = new BigDecimal(sanitizedString);
49-
switch (ogStr.replace(sanitizedString, "")) {
50-
case "": {
51-
break;
52-
}
53-
case "k": {
54-
tempAmount = tempAmount.multiply(THOUSAND);
55-
break;
56-
}
57-
case "m": {
58-
tempAmount = tempAmount.multiply(MILLION);
59-
break;
60-
}
61-
case "b": {
62-
tempAmount = tempAmount.multiply(BILLION);
63-
break;
64-
}
65-
case "t": {
66-
tempAmount = tempAmount.multiply(TRILLION);
67-
break;
68-
}
69-
default: {
70-
throw new InvalidModifierException();
71-
}
43+
final BigDecimal amount;
44+
if (ess.getSettings().isPerPlayerLocale()) {
45+
amount = NumberUtil.parseStringToBDecimal(ogStr, user.getPlayerLocale(ess.getPlayerLocaleProvider().getLocale(user.getBase())));
46+
} else {
47+
amount = NumberUtil.parseStringToBDecimal(ogStr);
7248
}
7349

74-
final BigDecimal amount = tempAmount;
75-
7650
if (amount.compareTo(ess.getSettings().getMinimumPayAmount()) < 0) { // Check if amount is less than minimum-pay-amount
7751
throw new TranslatableException("minimumPayAmount", AdventureUtil.parsed(NumberUtil.displayCurrencyExactly(ess.getSettings().getMinimumPayAmount(), ess)));
7852
}

Essentials/src/main/java/com/earth2me/essentials/utils/NumberUtil.java

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
11
package com.earth2me.essentials.utils;
22

3+
import com.earth2me.essentials.commands.InvalidModifierException;
34
import net.ess3.api.IEssentials;
45

56
import java.math.BigDecimal;
67
import java.math.RoundingMode;
78
import java.text.DecimalFormat;
89
import java.text.DecimalFormatSymbols;
910
import java.text.NumberFormat;
11+
import java.text.ParseException;
1012
import java.util.Locale;
1113

1214
import static com.earth2me.essentials.I18n.tlLiteral;
1315

1416
public final class NumberUtil {
1517

18+
private static final BigDecimal THOUSAND = new BigDecimal(1000);
19+
private static final BigDecimal MILLION = new BigDecimal(1_000_000);
20+
private static final BigDecimal BILLION = new BigDecimal(1_000_000_000);
21+
private static final BigDecimal TRILLION = new BigDecimal(1_000_000_000_000L);
22+
1623
private static final DecimalFormat twoDPlaces = new DecimalFormat("#,###.##");
1724
private static final DecimalFormat currencyFormat = new DecimalFormat("#0.00", DecimalFormatSymbols.getInstance(Locale.US));
1825

1926
// This field is likely to be modified in com.earth2me.essentials.Settings when loading currency format.
2027
// This ensures that we can supply a constant formatting.
21-
private static NumberFormat PRETTY_FORMAT = NumberFormat.getInstance(Locale.US);
28+
private static Locale PRETTY_LOCALE = Locale.US;
29+
private static NumberFormat PRETTY_FORMAT = NumberFormat.getInstance(PRETTY_LOCALE);
2230

2331
static {
2432
twoDPlaces.setRoundingMode(RoundingMode.HALF_UP);
@@ -139,6 +147,52 @@ public static boolean isHexadecimal(final String sNum) {
139147
}
140148
}
141149

150+
public static BigDecimal parseStringToBDecimal(final String sArg, final Locale locale) throws ParseException, InvalidModifierException {
151+
if (sArg.isEmpty()) {
152+
throw new IllegalArgumentException();
153+
}
154+
155+
final String sanitizedString = sArg.replaceAll("[^0-9.,]", "");
156+
BigDecimal multiplier = null;
157+
158+
switch (sArg.replace(sanitizedString, "").toUpperCase()) {
159+
case "": {
160+
break;
161+
}
162+
case "K": {
163+
multiplier = THOUSAND;
164+
break;
165+
}
166+
case "M": {
167+
multiplier = MILLION;
168+
break;
169+
}
170+
case "B": {
171+
multiplier = BILLION;
172+
break;
173+
}
174+
case "T": {
175+
multiplier = TRILLION;
176+
break;
177+
}
178+
default:
179+
throw new InvalidModifierException();
180+
}
181+
182+
final NumberFormat format = NumberFormat.getInstance(locale);
183+
final Number parsed = format.parse(sanitizedString);
184+
BigDecimal amount = new BigDecimal(parsed.toString());
185+
186+
if (multiplier != null) {
187+
amount = amount.multiply(multiplier);
188+
}
189+
return amount;
190+
}
191+
192+
public static BigDecimal parseStringToBDecimal(final String sArg) throws ParseException, InvalidModifierException {
193+
return parseStringToBDecimal(sArg, PRETTY_LOCALE);
194+
}
195+
142196
/**
143197
* Backport from Guava.
144198
*/
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.earth2me.essentials.utils;
2+
3+
import com.earth2me.essentials.commands.InvalidModifierException;
4+
import org.junit.Test;
5+
6+
import java.math.BigDecimal;
7+
import java.text.ParseException;
8+
import java.util.Locale;
9+
10+
import static org.junit.Assert.assertEquals;
11+
import static org.junit.Assert.assertNotEquals;
12+
import static org.junit.Assert.assertThrows;
13+
14+
public class NumberUtilTest {
15+
16+
@Test
17+
public void testStringParseBDecimal() throws ParseException, InvalidModifierException {
18+
19+
final BigDecimal decimal = NumberUtil.parseStringToBDecimal("10,000,000.5");
20+
assertEquals("10000000.5", decimal.toString());
21+
22+
final BigDecimal decimal2 = NumberUtil.parseStringToBDecimal("10.000.000,5");
23+
assertNotEquals("10000000.5", decimal2.toString());
24+
25+
final BigDecimal decimal3 = NumberUtil.parseStringToBDecimal("10000000,5");
26+
assertNotEquals("10000000.5", decimal3.toString());
27+
28+
final BigDecimal decimal4 = NumberUtil.parseStringToBDecimal("10000000.5");
29+
assertEquals("10000000.5", decimal4.toString());
30+
31+
final BigDecimal decimal5 = NumberUtil.parseStringToBDecimal("10000000.50000");
32+
assertEquals("10000000.5", decimal5.toString());
33+
34+
final BigDecimal decimal6 = NumberUtil.parseStringToBDecimal(".50000");
35+
assertEquals("0.5", decimal6.toString());
36+
37+
final BigDecimal decimal7 = NumberUtil.parseStringToBDecimal("00000.50000");
38+
assertEquals("0.5", decimal7.toString());
39+
40+
final BigDecimal decimal8 = NumberUtil.parseStringToBDecimal(",50000");
41+
assertEquals("50000", decimal8.toString());
42+
43+
assertThrows(InvalidModifierException.class, ()-> NumberUtil.parseStringToBDecimal("abc"));
44+
45+
assertThrows(IllegalArgumentException.class, ()-> NumberUtil.parseStringToBDecimal(""));
46+
47+
assertThrows(ParseException.class, ()-> NumberUtil.parseStringToBDecimal("M"));
48+
}
49+
50+
@Test
51+
public void testStringParseBDecimalLocale() throws ParseException, InvalidModifierException {
52+
53+
final Locale locale = Locale.GERMANY;
54+
55+
final BigDecimal decimal = NumberUtil.parseStringToBDecimal("10,000,000.5", locale);
56+
assertNotEquals("10000000.5", decimal.toString());
57+
58+
final BigDecimal decimal2 = NumberUtil.parseStringToBDecimal("10.000.000,5", locale);
59+
assertEquals("10000000.5", decimal2.toString());
60+
61+
final BigDecimal decimal3 = NumberUtil.parseStringToBDecimal("10000000,5", locale);
62+
assertEquals("10000000.5", decimal3.toString());
63+
64+
final BigDecimal decimal4 = NumberUtil.parseStringToBDecimal("10000000.5", locale);
65+
assertNotEquals("10000000.5", decimal4.toString());
66+
67+
final BigDecimal decimal5 = NumberUtil.parseStringToBDecimal(",5", locale);
68+
assertEquals("0.5", decimal5.toString());
69+
70+
final BigDecimal decimal6 = NumberUtil.parseStringToBDecimal(".50000", locale);
71+
assertEquals("50000", decimal6.toString());
72+
}
73+
}

0 commit comments

Comments
 (0)