Skip to content

Commit b73cd7d

Browse files
tastybentoclaude
andcommitted
refactor: remove duplicated code in admin economy commands
SonarCloud flagged 40-55% duplication across the admin eco command classes. Extract the shared <player> <amount> scaffolding into AbstractAdminAmountCommand (template method: subclasses supply the money op and success key), and add requireEconomy() and sendBalanceMessage() helpers to the command bases. Give/ take/set/balance and pay now delegate to these instead of repeating the validation and balance-reporting blocks. No behaviour change; 120 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 020aab8 commit b73cd7d

8 files changed

Lines changed: 129 additions & 103 deletions

File tree

src/main/java/com/wasteofplastic/invswitcher/commands/AbstractMoneyCommand.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ protected InvEconomy economy() {
4040
return addon.getEconomy();
4141
}
4242

43+
/**
44+
* Get the economy or send the "no economy" error to the user.
45+
* @param user - command sender
46+
* @return the economy, or null if unavailable (an error has been sent)
47+
*/
48+
protected InvEconomy requireEconomy(User user) {
49+
InvEconomy eco = economy();
50+
if (eco == null) {
51+
user.sendMessage("invswitcher.errors.no-economy");
52+
}
53+
return eco;
54+
}
55+
4356
/**
4457
* Parse a strictly-positive money amount, sending an error message on failure.
4558
* @param user - command sender
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.wasteofplastic.invswitcher.commands.admin;
2+
3+
import java.util.List;
4+
5+
import org.bukkit.OfflinePlayer;
6+
7+
import com.wasteofplastic.invswitcher.economy.InvEconomy;
8+
9+
import net.milkbowl.vault.economy.EconomyResponse;
10+
import world.bentobox.bentobox.api.commands.CompositeCommand;
11+
import world.bentobox.bentobox.api.user.User;
12+
13+
/**
14+
* Base for admin economy commands of the form {@code <command> <player> <amount>} (give, take,
15+
* set). Handles the shared validation, applies the subclass's money operation against the
16+
* command's game mode world, and reports the resulting balance. Subclasses only define the
17+
* operation and the success message.
18+
* @author tastybento
19+
*/
20+
public abstract class AbstractAdminAmountCommand extends AbstractAdminMoneyCommand {
21+
22+
protected AbstractAdminAmountCommand(CompositeCommand parent, String label, String... aliases) {
23+
super(parent, label, aliases);
24+
}
25+
26+
/**
27+
* Perform the money operation on the target for the given world.
28+
* @param eco - the economy
29+
* @param target - the target player
30+
* @param world - the command's game mode world name
31+
* @param amount - the parsed, positive amount
32+
* @return the economy response (a non-success response reports insufficient funds)
33+
*/
34+
protected abstract EconomyResponse apply(InvEconomy eco, OfflinePlayer target, String world, double amount);
35+
36+
/**
37+
* @return the locale key of the success message, which receives [name] and [number]
38+
*/
39+
protected abstract String successKey();
40+
41+
@Override
42+
public boolean execute(User user, String label, List<String> args) {
43+
if (args.size() != 2) {
44+
this.showHelp(this, user);
45+
return false;
46+
}
47+
InvEconomy eco = requireEconomy(user);
48+
if (eco == null) {
49+
return false;
50+
}
51+
User target = resolveTarget(user, args.get(0));
52+
if (target == null) {
53+
return false;
54+
}
55+
Double amount = parseAmount(user, args.get(1));
56+
if (amount == null) {
57+
return false;
58+
}
59+
String world = getWorld().getName();
60+
EconomyResponse response = apply(eco, target.getOfflinePlayer(), world, amount);
61+
if (!response.transactionSuccess()) {
62+
user.sendMessage("invswitcher.errors.insufficient-funds");
63+
return false;
64+
}
65+
sendBalanceMessage(user, successKey(), target, world);
66+
return true;
67+
}
68+
}

src/main/java/com/wasteofplastic/invswitcher/commands/admin/AbstractAdminMoneyCommand.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ protected User resolveTarget(User user, String name) {
3636
return target;
3737
}
3838

39+
/**
40+
* Send a message reporting the target's balance for the given world, with [name] and [number].
41+
* @param user - command sender
42+
* @param messageKey - locale key of the message
43+
* @param target - the target player
44+
* @param world - the world to report the balance for
45+
*/
46+
protected void sendBalanceMessage(User user, String messageKey, User target, String world) {
47+
user.sendMessage(messageKey, TextVariables.NAME, target.getName(),
48+
TextVariables.NUMBER, economy().format(economy().getBalance(target.getOfflinePlayer(), world)));
49+
}
50+
3951
/**
4052
* Tab-complete the player parameter (the first argument of these commands) with the names of
4153
* online players. The command tree is {@code <admin> eco <sub> <player> [amount]}, so the

src/main/java/com/wasteofplastic/invswitcher/commands/admin/AdminBalanceCommand.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@
22

33
import java.util.List;
44

5-
import com.wasteofplastic.invswitcher.economy.InvEconomy;
6-
75
import world.bentobox.bentobox.api.commands.CompositeCommand;
8-
import world.bentobox.bentobox.api.localization.TextVariables;
96
import world.bentobox.bentobox.api.user.User;
107

118
/**
12-
* Shows an admin another player's balance for the world that player is currently in (or was last in).
9+
* Shows an admin another player's balance for this command's game mode world.
1310
* @author tastybento
1411
*/
1512
public class AdminBalanceCommand extends AbstractAdminMoneyCommand {
@@ -31,18 +28,14 @@ public boolean execute(User user, String label, List<String> args) {
3128
this.showHelp(this, user);
3229
return false;
3330
}
34-
InvEconomy eco = economy();
35-
if (eco == null) {
36-
user.sendMessage("invswitcher.errors.no-economy");
31+
if (requireEconomy(user) == null) {
3732
return false;
3833
}
3934
User target = resolveTarget(user, args.get(0));
4035
if (target == null) {
4136
return false;
4237
}
43-
user.sendMessage("invswitcher.commands.admin.balance.balance",
44-
TextVariables.NAME, target.getName(),
45-
TextVariables.NUMBER, eco.format(eco.getBalance(target.getOfflinePlayer(), getWorld().getName())));
38+
sendBalanceMessage(user, "invswitcher.commands.admin.balance.balance", target, getWorld().getName());
4639
return true;
4740
}
4841
}
Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.wasteofplastic.invswitcher.commands.admin;
22

3-
import java.util.List;
3+
import org.bukkit.OfflinePlayer;
44

55
import com.wasteofplastic.invswitcher.economy.InvEconomy;
66

7+
import net.milkbowl.vault.economy.EconomyResponse;
78
import world.bentobox.bentobox.api.commands.CompositeCommand;
8-
import world.bentobox.bentobox.api.localization.TextVariables;
9-
import world.bentobox.bentobox.api.user.User;
109

1110
/**
12-
* Gives money to a player in the world they are currently in (or were last in).
11+
* Gives money to a player in this command's game mode world.
1312
* @author tastybento
1413
*/
15-
public class AdminGiveCommand extends AbstractAdminMoneyCommand {
14+
public class AdminGiveCommand extends AbstractAdminAmountCommand {
1615

1716
public AdminGiveCommand(CompositeCommand parent) {
1817
super(parent, "give");
@@ -26,29 +25,12 @@ public void setup() {
2625
}
2726

2827
@Override
29-
public boolean execute(User user, String label, List<String> args) {
30-
if (args.size() != 2) {
31-
this.showHelp(this, user);
32-
return false;
33-
}
34-
InvEconomy eco = economy();
35-
if (eco == null) {
36-
user.sendMessage("invswitcher.errors.no-economy");
37-
return false;
38-
}
39-
User target = resolveTarget(user, args.get(0));
40-
if (target == null) {
41-
return false;
42-
}
43-
Double amount = parseAmount(user, args.get(1));
44-
if (amount == null) {
45-
return false;
46-
}
47-
String world = getWorld().getName();
48-
eco.depositPlayer(target.getOfflinePlayer(), world, amount);
49-
user.sendMessage("invswitcher.commands.admin.give.success",
50-
TextVariables.NAME, target.getName(),
51-
TextVariables.NUMBER, eco.format(eco.getBalance(target.getOfflinePlayer(), world)));
52-
return true;
28+
protected EconomyResponse apply(InvEconomy eco, OfflinePlayer target, String world, double amount) {
29+
return eco.depositPlayer(target, world, amount);
30+
}
31+
32+
@Override
33+
protected String successKey() {
34+
return "invswitcher.commands.admin.give.success";
5335
}
5436
}
Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.wasteofplastic.invswitcher.commands.admin;
22

3-
import java.util.List;
3+
import org.bukkit.OfflinePlayer;
44

55
import com.wasteofplastic.invswitcher.economy.InvEconomy;
66

7+
import net.milkbowl.vault.economy.EconomyResponse;
78
import world.bentobox.bentobox.api.commands.CompositeCommand;
8-
import world.bentobox.bentobox.api.localization.TextVariables;
9-
import world.bentobox.bentobox.api.user.User;
109

1110
/**
12-
* Sets a player's balance in the world they are currently in (or were last in).
11+
* Sets a player's balance in this command's game mode world.
1312
* @author tastybento
1413
*/
15-
public class AdminSetCommand extends AbstractAdminMoneyCommand {
14+
public class AdminSetCommand extends AbstractAdminAmountCommand {
1615

1716
public AdminSetCommand(CompositeCommand parent) {
1817
super(parent, "set");
@@ -26,29 +25,12 @@ public void setup() {
2625
}
2726

2827
@Override
29-
public boolean execute(User user, String label, List<String> args) {
30-
if (args.size() != 2) {
31-
this.showHelp(this, user);
32-
return false;
33-
}
34-
InvEconomy eco = economy();
35-
if (eco == null) {
36-
user.sendMessage("invswitcher.errors.no-economy");
37-
return false;
38-
}
39-
User target = resolveTarget(user, args.get(0));
40-
if (target == null) {
41-
return false;
42-
}
43-
Double amount = parseAmount(user, args.get(1));
44-
if (amount == null) {
45-
return false;
46-
}
47-
String world = getWorld().getName();
48-
eco.setBalance(target.getOfflinePlayer(), world, amount);
49-
user.sendMessage("invswitcher.commands.admin.set.success",
50-
TextVariables.NAME, target.getName(),
51-
TextVariables.NUMBER, eco.format(eco.getBalance(target.getOfflinePlayer(), world)));
52-
return true;
28+
protected EconomyResponse apply(InvEconomy eco, OfflinePlayer target, String world, double amount) {
29+
return eco.setBalance(target, world, amount);
30+
}
31+
32+
@Override
33+
protected String successKey() {
34+
return "invswitcher.commands.admin.set.success";
5335
}
5436
}
Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
package com.wasteofplastic.invswitcher.commands.admin;
22

3-
import java.util.List;
3+
import org.bukkit.OfflinePlayer;
44

55
import com.wasteofplastic.invswitcher.economy.InvEconomy;
66

77
import net.milkbowl.vault.economy.EconomyResponse;
88
import world.bentobox.bentobox.api.commands.CompositeCommand;
9-
import world.bentobox.bentobox.api.localization.TextVariables;
10-
import world.bentobox.bentobox.api.user.User;
119

1210
/**
13-
* Takes money from a player in the world they are currently in (or were last in).
11+
* Takes money from a player in this command's game mode world.
1412
* @author tastybento
1513
*/
16-
public class AdminTakeCommand extends AbstractAdminMoneyCommand {
14+
public class AdminTakeCommand extends AbstractAdminAmountCommand {
1715

1816
public AdminTakeCommand(CompositeCommand parent) {
1917
super(parent, "take");
@@ -27,33 +25,12 @@ public void setup() {
2725
}
2826

2927
@Override
30-
public boolean execute(User user, String label, List<String> args) {
31-
if (args.size() != 2) {
32-
this.showHelp(this, user);
33-
return false;
34-
}
35-
InvEconomy eco = economy();
36-
if (eco == null) {
37-
user.sendMessage("invswitcher.errors.no-economy");
38-
return false;
39-
}
40-
User target = resolveTarget(user, args.get(0));
41-
if (target == null) {
42-
return false;
43-
}
44-
Double amount = parseAmount(user, args.get(1));
45-
if (amount == null) {
46-
return false;
47-
}
48-
String world = getWorld().getName();
49-
EconomyResponse response = eco.withdrawPlayer(target.getOfflinePlayer(), world, amount);
50-
if (!response.transactionSuccess()) {
51-
user.sendMessage("invswitcher.errors.insufficient-funds");
52-
return false;
53-
}
54-
user.sendMessage("invswitcher.commands.admin.take.success",
55-
TextVariables.NAME, target.getName(),
56-
TextVariables.NUMBER, eco.format(eco.getBalance(target.getOfflinePlayer(), world)));
57-
return true;
28+
protected EconomyResponse apply(InvEconomy eco, OfflinePlayer target, String world, double amount) {
29+
return eco.withdrawPlayer(target, world, amount);
30+
}
31+
32+
@Override
33+
protected String successKey() {
34+
return "invswitcher.commands.admin.take.success";
5835
}
5936
}

src/main/java/com/wasteofplastic/invswitcher/commands/user/PayCommand.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ public boolean execute(User user, String label, List<String> args) {
3737
this.showHelp(this, user);
3838
return false;
3939
}
40-
InvEconomy eco = economy();
40+
InvEconomy eco = requireEconomy(user);
4141
if (eco == null) {
42-
user.sendMessage("invswitcher.errors.no-economy");
4342
return false;
4443
}
4544
User target = getPlayers().getUser(args.get(0));

0 commit comments

Comments
 (0)