Skip to content

Commit 2f7bf83

Browse files
Refactor PriceLimiter
Improve code readability Fix free shop price checking Fix digit checking not working other than shop creation Send detail message to player after price check failed
1 parent e722b12 commit 2f7bf83

File tree

9 files changed

+157
-131
lines changed

9 files changed

+157
-131
lines changed

src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterCheckResult.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919

2020
package org.maxgamer.quickshop.api.shop;
2121

22+
import org.bukkit.command.CommandSender;
23+
import org.maxgamer.quickshop.QuickShop;
24+
import org.maxgamer.quickshop.util.MsgUtil;
25+
2226
/**
2327
* Result of PriceLimiter check
2428
*/
@@ -43,4 +47,52 @@ public interface PriceLimiterCheckResult {
4347
* @return Max price
4448
*/
4549
double getMax();
50+
51+
/**
52+
* Get the price max digit should be
53+
*
54+
* @return the max digit limit
55+
*/
56+
default int getMaxDigit() {
57+
return -1;
58+
}
59+
60+
/**
61+
* Get the price should be in this limitation
62+
*
63+
* @return the price after adjusted
64+
*/
65+
default double getPriceShouldBe() {
66+
return getMin();
67+
}
68+
69+
default void sendErrorMsg(QuickShop plugin, CommandSender sender, String input, String itemName) {
70+
boolean decFormat = plugin.getConfig().getBoolean("use-decimal-format");
71+
switch (getStatus()) {
72+
case REACHED_PRICE_MIN_LIMIT:
73+
plugin.text().of(sender, "price-too-cheap",
74+
(decFormat) ? MsgUtil.decimalFormat(getMax())
75+
: Double.toString(getMin())).send();
76+
case REACHED_PRICE_MAX_LIMIT:
77+
plugin.text().of(sender, "price-too-high",
78+
(decFormat) ? MsgUtil.decimalFormat(getMax())
79+
: Double.toString(getMin())).send();
80+
case PRICE_RESTRICTED:
81+
plugin.text().of(sender, "restricted-prices",
82+
itemName,
83+
String.valueOf(getMin()),
84+
String.valueOf(getMax())).send();
85+
case NOT_VALID:
86+
plugin.text().of(sender, "not-a-number", input).send();
87+
case NOT_A_WHOLE_NUMBER:
88+
plugin.text().of(sender, "not-a-integer", input).send();
89+
case REACH_DIGITS_LIMIT:
90+
plugin.text().of(sender, "digits-reach-the-limit", String.valueOf(getMaxDigit()));
91+
default:
92+
plugin.text().of(sender, "restricted-prices",
93+
itemName,
94+
String.valueOf(getMin()),
95+
String.valueOf(getMax())).send();
96+
}
97+
}
4698
}

src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterStatus.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ public enum PriceLimiterStatus {
66
REACHED_PRICE_MIN_LIMIT,
77
PRICE_RESTRICTED,
88
NOT_A_WHOLE_NUMBER,
9-
NOT_VALID
9+
NOT_VALID,
10+
REACH_DIGITS_LIMIT,
1011
}

src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Item.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,10 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not
6464
if (!plugin.isAllowStack() || !QuickShop.getPermissionManager().hasPermission(sender, "quickshop.create.stacks")) {
6565
itemStack.setAmount(1);
6666
}
67-
SimplePriceLimiter limiter = new SimplePriceLimiter(
68-
plugin.getConfig().getDouble("shop.minimum-price"),
69-
plugin.getConfig().getInt("shop.maximum-price"),
70-
plugin.getConfig().getBoolean("shop.allow-free-shop"),
71-
plugin.getConfig().getBoolean("whole-number-prices-only"));
67+
SimplePriceLimiter limiter = new SimplePriceLimiter(plugin);
7268
PriceLimiterCheckResult checkResult = limiter.check(itemStack, shop.getPrice());
7369
if (checkResult.getStatus() != PriceLimiterStatus.PASS) {
74-
plugin.text().of(sender, "restricted-prices", MsgUtil.getTranslateText(shop.getItem()),
75-
String.valueOf(checkResult.getMin()),
76-
String.valueOf(checkResult.getMax())).send();
70+
checkResult.sendErrorMsg(plugin, sender, "", MsgUtil.getTranslateText(shop.getItem()));
7771
return;
7872
}
7973
shop.setItem(itemStack);

src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Price.java

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not
6262
plugin.text().of(sender, "not-a-number", cmdArg[0]).send();
6363
return;
6464
}
65-
// No number input
66-
if (Double.isInfinite(price) || Double.isNaN(price)) {
67-
plugin.text().of(sender, "not-a-number", cmdArg[0]).send();
68-
return;
69-
}
70-
71-
final boolean format = plugin.getConfig().getBoolean("use-decimal-format");
7265

7366
double fee = 0;
7467

@@ -83,11 +76,7 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not
8376
return;
8477
}
8578

86-
SimplePriceLimiter limiter = new SimplePriceLimiter(
87-
plugin.getConfig().getDouble("shop.minimum-price"),
88-
plugin.getConfig().getInt("shop.maximum-price"),
89-
plugin.getConfig().getBoolean("shop.allow-free-shop"),
90-
plugin.getConfig().getBoolean("whole-number-prices-only"));
79+
SimplePriceLimiter limiter = new SimplePriceLimiter(plugin);
9180

9281
while (bIt.hasNext()) {
9382
final Block b = bIt.next();
@@ -107,23 +96,8 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not
10796
}
10897

10998
PriceLimiterCheckResult checkResult = limiter.check(shop.getItem(), price);
110-
if (checkResult.getStatus() == PriceLimiterStatus.REACHED_PRICE_MIN_LIMIT) {
111-
plugin.text().of(sender, "price-too-cheap", (format) ? MsgUtil.decimalFormat(checkResult.getMin()) : Double.toString(checkResult.getMin())).send();
112-
return;
113-
}
114-
if (checkResult.getStatus() == PriceLimiterStatus.REACHED_PRICE_MAX_LIMIT) {
115-
plugin.text().of(sender, "price-too-high", (format) ? MsgUtil.decimalFormat(checkResult.getMax()) : Double.toString(checkResult.getMax())).send();
116-
return;
117-
}
118-
if (checkResult.getStatus() == PriceLimiterStatus.PRICE_RESTRICTED) {
119-
plugin.text().of(sender, "restricted-prices", MsgUtil.getTranslateText(shop.getItem()),
120-
String.valueOf(checkResult.getMin()),
121-
String.valueOf(checkResult.getMax())).send();
122-
return;
123-
}
124-
125-
if (checkResult.getStatus() == PriceLimiterStatus.NOT_A_WHOLE_NUMBER) {
126-
plugin.text().of(sender, "not-a-integer", price).send();
99+
if (checkResult.getStatus() != PriceLimiterStatus.PASS) {
100+
checkResult.sendErrorMsg(plugin, sender, cmdArg[0], MsgUtil.getTranslateText(shop.getItem()));
127101
return;
128102
}
129103

src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Size.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,10 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not
6868
}
6969
ItemStack pendingItemStack = shop.getItem().clone();
7070
pendingItemStack.setAmount(amount);
71-
SimplePriceLimiter limiter = new SimplePriceLimiter(
72-
plugin.getConfig().getDouble("shop.minimum-price"),
73-
plugin.getConfig().getInt("shop.maximum-price"),
74-
plugin.getConfig().getBoolean("shop.allow-free-shop"),
75-
plugin.getConfig().getBoolean("whole-number-prices-only"));
71+
SimplePriceLimiter limiter = new SimplePriceLimiter(plugin);
7672
PriceLimiterCheckResult checkResult = limiter.check(pendingItemStack, shop.getPrice());
7773
if (checkResult.getStatus() != PriceLimiterStatus.PASS) {
78-
plugin.text().of(sender, "restricted-prices", MsgUtil.getTranslateText(shop.getItem()),
79-
String.valueOf(checkResult.getMin()),
80-
String.valueOf(checkResult.getMax())).send();
74+
checkResult.sendErrorMsg(plugin, sender, cmdArg[0], MsgUtil.getTranslateText(shop.getItem()));
8175
return;
8276
}
8377
shop.setItem(pendingItemStack);

src/main/java/org/maxgamer/quickshop/shop/ContainerShop.java

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,27 +1032,9 @@ public void onLoad() {
10321032

10331033
// check price restriction
10341034
PriceLimiterCheckResult priceRestriction = plugin.getShopManager().getPriceLimiter().check(item, price);
1035-
boolean markUpdate = false;
10361035
if (priceRestriction.getStatus() != PriceLimiterStatus.PASS) {
1037-
if (priceRestriction.getStatus() == PriceLimiterStatus.NOT_A_WHOLE_NUMBER) {
1038-
setDirty();
1039-
price = Math.floor(price);
1040-
markUpdate = true;
1041-
} else if (priceRestriction.getStatus() == PriceLimiterStatus.NOT_VALID) {
1042-
setDirty();
1043-
price = priceRestriction.getMin();
1044-
markUpdate = true;
1045-
}
1046-
if (price < priceRestriction.getMin()) {
1047-
setDirty();
1048-
price = priceRestriction.getMin();
1049-
markUpdate = true;
1050-
} else if (price > priceRestriction.getMax()) {
1051-
setDirty();
1052-
price = priceRestriction.getMax();
1053-
markUpdate = true;
1054-
}
1055-
if (markUpdate) {
1036+
if (price != priceRestriction.getPriceShouldBe()) {
1037+
price = priceRestriction.getPriceShouldBe();
10561038
update();
10571039
}
10581040
}

src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiter.java

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020
package org.maxgamer.quickshop.shop;
2121

22-
import lombok.AllArgsConstructor;
2322
import lombok.Data;
23+
import lombok.EqualsAndHashCode;
2424
import org.bukkit.inventory.ItemStack;
2525
import org.jetbrains.annotations.NotNull;
2626
import org.maxgamer.quickshop.QuickShop;
@@ -32,41 +32,84 @@
3232

3333
import java.math.BigDecimal;
3434
import java.math.RoundingMode;
35+
import java.text.DecimalFormat;
3536
import java.util.Map;
3637

37-
@AllArgsConstructor
3838
@Data
3939
public class SimplePriceLimiter implements PriceLimiter {
40+
4041
private double minPrice;
4142
private double maxPrice;
4243
private boolean allowFreeShop;
4344
private boolean wholeNumberOnly;
45+
private int maximumDigitsInPrice;
46+
@EqualsAndHashCode.Exclude
47+
private DecimalFormat decimalFormat;
48+
49+
public SimplePriceLimiter(double minPrice, double maxPrice, boolean allowFreeShop, boolean wholeNumberOnly, int maximumDigitsInPrice) {
50+
this.minPrice = minPrice;
51+
this.maxPrice = maxPrice;
52+
this.allowFreeShop = allowFreeShop;
53+
this.wholeNumberOnly = wholeNumberOnly;
54+
this.maximumDigitsInPrice = maximumDigitsInPrice;
55+
}
56+
57+
public SimplePriceLimiter(QuickShop plugin) {
58+
this(plugin.getConfig().getDouble("shop.minimum-price"),
59+
plugin.getConfig().getInt("shop.maximum-price"),
60+
plugin.getConfig().getBoolean("shop.allow-free-shop"),
61+
plugin.getConfig().getBoolean("whole-number-prices-only"),
62+
plugin.getConfig().getInt("maximum-digits-in-price", -1));
63+
}
64+
65+
private DecimalFormat getDecimalFormat() {
66+
if (decimalFormat == null) {
67+
StringBuilder builder = new StringBuilder("#.");
68+
for (int i = 0; i <= maximumDigitsInPrice; i++) {
69+
builder.append("#");
70+
}
71+
decimalFormat = new DecimalFormat(builder.toString());
72+
}
73+
return decimalFormat;
74+
}
4475

4576
@Override
4677
@NotNull
4778
public PriceLimiterCheckResult check(@NotNull ItemStack stack, double price) {
79+
SimplePriceLimiterCheckResult result = new SimplePriceLimiterCheckResult(PriceLimiterStatus.PASS, minPrice, maxPrice, price, maximumDigitsInPrice);
80+
4881
if (Double.isInfinite(price) || Double.isNaN(price)) {
49-
return new SimplePriceLimiterCheckResult(PriceLimiterStatus.NOT_VALID, minPrice, maxPrice);
82+
return result.status(PriceLimiterStatus.NOT_VALID)
83+
.priceShouldBe(minPrice);
5084
}
51-
if (allowFreeShop) {
52-
if (price != 0 && price < minPrice) {
53-
return new SimplePriceLimiterCheckResult(PriceLimiterStatus.REACHED_PRICE_MIN_LIMIT, minPrice, maxPrice);
85+
if (maximumDigitsInPrice != -1) {
86+
String strFormat = getDecimalFormat().format(Math.abs(price)).replace(",", ".");
87+
String[] processedDouble = strFormat.split("\\.");
88+
if (processedDouble.length > 1) {
89+
if (processedDouble[1].length() > maximumDigitsInPrice) {
90+
return result.status(PriceLimiterStatus.REACH_DIGITS_LIMIT)
91+
.priceShouldBe(Double.parseDouble(processedDouble[0] + "." + processedDouble[1].substring(0, maximumDigitsInPrice)));
92+
}
5493
}
5594
}
5695
if (wholeNumberOnly) {
5796
try {
97+
//noinspection ResultOfMethodCallIgnored
5898
BigDecimal.valueOf(price).setScale(0, RoundingMode.UNNECESSARY);
5999
} catch (ArithmeticException exception) {
60100
Util.debugLog(exception.getMessage());
61-
return new SimplePriceLimiterCheckResult(PriceLimiterStatus.NOT_A_WHOLE_NUMBER, minPrice, maxPrice);
101+
return result.status(PriceLimiterStatus.NOT_A_WHOLE_NUMBER)
102+
.priceShouldBe(Math.floor(price));
62103
}
63104
}
64-
if (price < minPrice) {
65-
return new SimplePriceLimiterCheckResult(PriceLimiterStatus.REACHED_PRICE_MIN_LIMIT, minPrice, maxPrice);
66-
}
67-
if (maxPrice != -1) {
68-
if (price > maxPrice) {
69-
return new SimplePriceLimiterCheckResult(PriceLimiterStatus.REACHED_PRICE_MAX_LIMIT, minPrice, maxPrice);
105+
if (!allowFreeShop || price != 0) {
106+
if (price < minPrice) {
107+
return result.status(PriceLimiterStatus.REACHED_PRICE_MIN_LIMIT)
108+
.priceShouldBe(minPrice);
109+
}
110+
if (maxPrice != -1 && price > maxPrice) {
111+
return result.status(PriceLimiterStatus.REACHED_PRICE_MAX_LIMIT)
112+
.priceShouldBe(maxPrice);
70113
}
71114
}
72115
double perItemPrice;
@@ -77,11 +120,18 @@ public PriceLimiterCheckResult check(@NotNull ItemStack stack, double price) {
77120
}
78121
Map.Entry<Double, Double> materialLimit = Util.getPriceRestriction(stack.getType());
79122
if (materialLimit != null) {
80-
if (perItemPrice < materialLimit.getKey() || perItemPrice > materialLimit.getValue()) {
81-
return new SimplePriceLimiterCheckResult(PriceLimiterStatus.PRICE_RESTRICTED, materialLimit.getKey(), materialLimit.getValue());
123+
//Updating the max and min price
124+
result.max(materialLimit.getKey()).min(materialLimit.getValue());
125+
if (!allowFreeShop || price != 0) {
126+
if (perItemPrice < materialLimit.getKey()) {
127+
return result.status(PriceLimiterStatus.PRICE_RESTRICTED)
128+
.priceShouldBe(materialLimit.getKey());
129+
} else if (perItemPrice > materialLimit.getValue()) {
130+
return result.status(PriceLimiterStatus.PRICE_RESTRICTED)
131+
.priceShouldBe(materialLimit.getValue());
132+
}
82133
}
83-
return new SimplePriceLimiterCheckResult(PriceLimiterStatus.PASS, materialLimit.getKey(), materialLimit.getValue());
84134
}
85-
return new SimplePriceLimiterCheckResult(PriceLimiterStatus.PASS, minPrice, maxPrice);
135+
return result;
86136
}
87137
}

src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiterCheckResult.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,26 @@ public class SimplePriceLimiterCheckResult implements PriceLimiterCheckResult {
3030
PriceLimiterStatus status;
3131
double min;
3232
double max;
33+
double priceShouldBe;
34+
int maxDigit;
35+
36+
public SimplePriceLimiterCheckResult min(double min) {
37+
this.min = min;
38+
return this;
39+
}
40+
41+
public SimplePriceLimiterCheckResult max(double max) {
42+
this.max = max;
43+
return this;
44+
}
45+
46+
public SimplePriceLimiterCheckResult priceShouldBe(double priceShouldBe) {
47+
this.priceShouldBe = priceShouldBe;
48+
return this;
49+
}
50+
51+
public SimplePriceLimiterCheckResult status(PriceLimiterStatus status) {
52+
this.status = status;
53+
return this;
54+
}
3355
}

0 commit comments

Comments
 (0)