Skip to content

Commit a758151

Browse files
authored
Merge pull request #3 from MCCitiesNetwork/feat/block-free-shops
Block free (b:0 / s:0) shops; break pre-existing ones on interact
2 parents e47999a + 18012c9 commit a758151

3 files changed

Lines changed: 90 additions & 0 deletions

File tree

plugin/src/main/java/com/Acrobot/ChestShop/ChestShop.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ private void registerPreShopCreationEvents() {
392392
registerEvent(new com.Acrobot.ChestShop.Listeners.PreShopCreation.PermissionChecker());
393393
registerEvent(new com.Acrobot.ChestShop.Listeners.PreShopCreation.ErrorMessageSender());
394394
registerEvent(new PriceChecker());
395+
registerEvent(new FreePriceChecker()); // DC: block free (b:0 / s:0) shops
395396
registerEvent(new QuantityChecker());
396397
registerEvent(new TerrainChecker());
397398
}
@@ -412,6 +413,7 @@ private void registerPreTransactionEvents() {
412413

413414
registerEvent(new InvalidNameIgnorer());
414415
registerEvent(new CreativeModeIgnorer());
416+
registerEvent(new FreeShopBreaker()); // DC: break pre-existing free (b:0 / s:0) shops on interact
415417
registerEvent(new ErrorMessageSender());
416418
registerEvent(new PermissionChecker());
417419
registerEvent(new PriceValidator());
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.Acrobot.ChestShop.Listeners.PreShopCreation;
2+
3+
import com.Acrobot.Breeze.Utils.PriceUtil;
4+
import com.Acrobot.ChestShop.Events.PreShopCreationEvent;
5+
import com.Acrobot.ChestShop.Signs.ChestShopSign;
6+
import org.bukkit.event.EventHandler;
7+
import org.bukkit.event.EventPriority;
8+
import org.bukkit.event.Listener;
9+
10+
import java.math.BigDecimal;
11+
12+
import static com.Acrobot.ChestShop.Events.PreShopCreationEvent.CreationOutcome.INVALID_PRICE;
13+
14+
/**
15+
* DemocracyCraft: free shops are not allowed — a buy or sell price of exactly 0
16+
* (the {@code b:0} / {@code s:0} case). Runs after {@link PriceChecker} (LOWEST)
17+
* has normalised the price line, reads the resulting buy/sell prices, and
18+
* rejects creation if either offered side is priced at 0. An <em>unoffered</em>
19+
* side ({@link PriceUtil#NO_PRICE} / -1) is fine — a buy-only or sell-only shop
20+
* with a non-zero price is unaffected.
21+
*/
22+
public class FreePriceChecker implements Listener {
23+
24+
@EventHandler(priority = EventPriority.NORMAL)
25+
public static void onPreShopCreation(PreShopCreationEvent event) {
26+
String price = ChestShopSign.getPrice(event.getSignLines());
27+
if (isFree(PriceUtil.getExactBuyPrice(price)) || isFree(PriceUtil.getExactSellPrice(price))) {
28+
event.setOutcome(INVALID_PRICE);
29+
}
30+
}
31+
32+
private static boolean isFree(BigDecimal price) {
33+
return price.compareTo(PriceUtil.FREE) == 0;
34+
}
35+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.Acrobot.ChestShop.Listeners.PreTransaction;
2+
3+
import com.Acrobot.Breeze.Utils.PriceUtil;
4+
import com.Acrobot.ChestShop.Events.PreTransactionEvent;
5+
import com.Acrobot.ChestShop.Listeners.Block.Break.SignBreak;
6+
import com.Acrobot.ChestShop.Signs.ChestShopSign;
7+
import org.bukkit.block.Sign;
8+
import org.bukkit.event.EventHandler;
9+
import org.bukkit.event.EventPriority;
10+
import org.bukkit.event.Listener;
11+
12+
import java.math.BigDecimal;
13+
14+
import static com.Acrobot.ChestShop.Events.PreTransactionEvent.TransactionOutcome.INVALID_SHOP;
15+
16+
/**
17+
* DemocracyCraft: free shops (a buy or sell price of exactly 0 — the {@code b:0}
18+
* / {@code s:0} case) are blocked at creation by {@link com.Acrobot.ChestShop.Listeners.PreShopCreation.FreePriceChecker}.
19+
* Any that pre-date that rule are cleaned up the first time someone interacts
20+
* with them: the transaction is cancelled with {@code INVALID_SHOP} — which
21+
* sends the "invalid shop" message via the PreTransaction ErrorMessageSender —
22+
* and the sign is broken (firing a ShopDestroyedEvent so the shop is
23+
* de-registered, then removing the block).
24+
*/
25+
public class FreeShopBreaker implements Listener {
26+
27+
@EventHandler(priority = EventPriority.LOWEST)
28+
public static void onPreTransaction(PreTransactionEvent event) {
29+
if (event.isCancelled()) {
30+
return;
31+
}
32+
33+
Sign sign = event.getSign();
34+
if (sign == null) {
35+
return;
36+
}
37+
38+
String price = ChestShopSign.getPrice(sign);
39+
if (!isFree(PriceUtil.getExactBuyPrice(price)) && !isFree(PriceUtil.getExactSellPrice(price))) {
40+
return;
41+
}
42+
43+
// Cancel the trade (INVALID_SHOP → "invalid shop" message to the client)
44+
// and destroy the offending shop.
45+
event.setCancelled(INVALID_SHOP);
46+
SignBreak.sendShopDestroyedEvent(sign, event.getClient());
47+
sign.getBlock().breakNaturally();
48+
}
49+
50+
private static boolean isFree(BigDecimal price) {
51+
return price.compareTo(PriceUtil.FREE) == 0;
52+
}
53+
}

0 commit comments

Comments
 (0)