diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyEconomyHandler.java b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyEconomyHandler.java index 5956c3ab8c..07fc0975d3 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/TownyEconomyHandler.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/TownyEconomyHandler.java @@ -2,14 +2,14 @@ import com.palmergames.bukkit.config.ConfigNodes; import com.palmergames.bukkit.towny.event.economy.TownyPreTransactionEvent; -import com.palmergames.bukkit.towny.event.economy.TownyTransactionEvent; import com.palmergames.bukkit.towny.object.economy.adapter.ReserveEconomyAdapter; import com.palmergames.bukkit.towny.object.Nation; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; -import com.palmergames.bukkit.towny.object.Transaction; -import com.palmergames.bukkit.towny.object.TransactionType; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; +import com.palmergames.bukkit.towny.object.economy.Account; import com.palmergames.bukkit.towny.object.economy.TownyServerAccount; +import com.palmergames.bukkit.towny.object.economy.TownyServerAccountEconomyHandler; import com.palmergames.bukkit.towny.object.economy.adapter.EconomyAdapter; import com.palmergames.bukkit.towny.object.economy.adapter.VaultEconomyAdapter; import com.palmergames.bukkit.util.BukkitTools; @@ -18,9 +18,7 @@ import net.milkbowl.vault.economy.Economy; import net.tnemc.core.Reserve; -import org.bukkit.Bukkit; import org.bukkit.World; -import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.RegisteredServiceProvider; import org.jetbrains.annotations.Nullable; @@ -98,6 +96,12 @@ public static void initialize(Towny plugin) { TownyEconomyHandler.plugin = plugin; } + public static TownyServerAccount initializeTownyServerAccount() { + TownyServerAccountEconomyHandler economyHandler = new TownyServerAccount(); + TownyServerAccount account = new TownyServerAccount(economyHandler); + return account; + } + /** * @return the economy type we have detected. */ @@ -211,36 +215,30 @@ public static boolean hasEnough(String accountName, double amount, World world) private static boolean runPreChecks(Transaction transaction, String accountName) { TownyPreTransactionEvent preEvent = new TownyPreTransactionEvent(transaction); - if (BukkitTools.isEventCancelled(preEvent)) { - TownyMessaging.sendErrorMsg(transaction.getPlayer(), preEvent.getCancelMessage()); + if (BukkitTools.isEventCancelled(preEvent) && transaction.getSendingPlayer() != null) { + TownyMessaging.sendErrorMsg(transaction.getSendingPlayer(), preEvent.getCancelMessage()); return false; } checkNewAccount(accountName); return true; } - /** * Attempts to remove an amount from an account * - * @param accountName name of the account to modify + * @param account the Account losing money. * @param amount amount of currency to remove from the account * @param world name of the world in which to check in (TNE Reserve) * @return true if successful */ - public static boolean subtract(String accountName, double amount, World world) { + public static boolean subtract(Account account, double amount, World world) { - Player player = Bukkit.getServer().getPlayerExact(accountName); - Transaction transaction = new Transaction(TransactionType.SUBTRACT, player, amount); - TownyTransactionEvent event = new TownyTransactionEvent(transaction); - - if (!runPreChecks(transaction, accountName)) { + if (!runPreChecks(Transaction.subtract(amount).paidBy(account).build(), account.getName())) { return false; } - if (economy.subtract(accountName, amount, world)) { - BukkitTools.fireEvent(event); + if (economy.subtract(account.getName(), amount, world)) { return true; } @@ -250,23 +248,18 @@ public static boolean subtract(String accountName, double amount, World world) { /** * Add funds to an account. * - * @param accountName account to add funds to + * @param account the Account receiving money. * @param amount amount of currency to add * @param world name of world (for TNE Reserve) * @return true if successful */ - public static boolean add(String accountName, double amount, World world) { + public static boolean add(Account account, double amount, World world) { - Player player = Bukkit.getServer().getPlayerExact(accountName); - Transaction transaction = new Transaction(TransactionType.ADD, player, amount); - TownyTransactionEvent event = new TownyTransactionEvent(transaction); - - if (!runPreChecks(transaction, accountName)) { + if (!runPreChecks(Transaction.add(amount).paidTo(account).build(), account.getName())) { return false; } - if (economy.add(accountName, amount, world)) { - BukkitTools.fireEvent(event); + if (economy.add(account.getName(), amount, world)) { return true; } @@ -297,27 +290,6 @@ public static String getFormattedBalance(double balance) { } - /** - * Adds money to the server account (used for towny closed economy.) - * - * @param amount The amount to deposit. - * @param world The world of the deposit. - * @return A boolean indicating success. - */ - public static boolean addToServer(double amount, World world) { - return add(getServerAccount(), amount, world); - } - - /** - * Removes money to the server account (used for towny closed economy.) - * - * @param amount The amount to withdraw. - * @param world The world of the withdraw. - * @return A boolean indicating success. - */ - public static boolean subtractFromServer(double amount, World world) { - return subtract(getServerAccount(), amount, world); - } private static void checkNewAccount(String accountName) { // Check if the account exists, if not create one. diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java index ba5896ac12..75a2900bad 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/command/TownyAdminCommand.java @@ -41,10 +41,9 @@ import com.palmergames.bukkit.towny.object.TownBlockType; import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import com.palmergames.bukkit.towny.object.TownyWorld; -import com.palmergames.bukkit.towny.object.Transaction; -import com.palmergames.bukkit.towny.object.TransactionType; import com.palmergames.bukkit.towny.object.Translatable; import com.palmergames.bukkit.towny.object.WorldCoord; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import com.palmergames.bukkit.towny.object.jail.UnJailReason; import com.palmergames.bukkit.towny.object.metadata.CustomDataField; import com.palmergames.bukkit.towny.permissions.PermissionNodes; @@ -1293,7 +1292,7 @@ public void parseAdminTownCommand(CommandSender sender, String[] split) throws T int deposit = MathUtil.getIntOrThrow(split[2]); if (town.getAccount().deposit(deposit, "Admin Deposit")) { - BukkitTools.fireEvent(new TownTransactionEvent(town, new Transaction(TransactionType.DEPOSIT, sender, deposit))); + BukkitTools.fireEvent(new TownTransactionEvent(town, Transaction.deposit(deposit).paidTo(town).build())); // Send notifications Translatable depositMessage = Translatable.of("msg_xx_deposited_xx", getSenderFormatted(sender), deposit, Translatable.of("town_sing")); TownyMessaging.sendMsg(sender, depositMessage); @@ -1314,7 +1313,7 @@ public void parseAdminTownCommand(CommandSender sender, String[] split) throws T int withdraw = MathUtil.getIntOrThrow(split[2]); if (town.getAccount().withdraw(withdraw, "Admin Withdraw")) { - BukkitTools.fireEvent(new TownTransactionEvent(town, new Transaction(TransactionType.WITHDRAW, sender, withdraw))); + BukkitTools.fireEvent(new TownTransactionEvent(town, Transaction.withdraw(withdraw).paidBy(town).build())); // Send notifications Translatable withdrawMessage = Translatable.of("msg_xx_withdrew_xx", getSenderFormatted(sender), withdraw, Translatable.of("town_sing")); TownyMessaging.sendMsg(sender, withdrawMessage); @@ -1737,7 +1736,7 @@ public void parseAdminNationCommand(CommandSender sender, String[] split) throws int deposit = MathUtil.getPositiveIntOrThrow(split[2]); - BukkitTools.fireEvent(new NationTransactionEvent(nation, new Transaction(TransactionType.DEPOSIT, sender, deposit))); + BukkitTools.fireEvent(new NationTransactionEvent(nation, Transaction.deposit(deposit).paidTo(nation).build())); nation.getAccount().deposit(deposit, "Admin Deposit"); // Send notifications @@ -1755,7 +1754,7 @@ public void parseAdminNationCommand(CommandSender sender, String[] split) throws int withdraw = MathUtil.getPositiveIntOrThrow(split[2]); - BukkitTools.fireEvent(new NationTransactionEvent(nation, new Transaction(TransactionType.WITHDRAW, sender, withdraw))); + BukkitTools.fireEvent(new NationTransactionEvent(nation, Transaction.withdraw(withdraw).paidBy(nation).build())); nation.getAccount().withdraw(withdraw, "Admin Withdraw"); // Send notifications diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/BankTransactionEvent.java b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/BankTransactionEvent.java index 7cfd13022d..ab9691a69e 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/BankTransactionEvent.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/BankTransactionEvent.java @@ -2,7 +2,7 @@ import com.palmergames.bukkit.towny.object.economy.Account; import com.palmergames.bukkit.towny.object.economy.BankAccount; -import com.palmergames.bukkit.towny.object.Transaction; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/NationPreTransactionEvent.java b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/NationPreTransactionEvent.java index b4ff2d30d6..d4d67a5651 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/NationPreTransactionEvent.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/NationPreTransactionEvent.java @@ -2,7 +2,7 @@ import com.palmergames.bukkit.towny.event.CancellableTownyEvent; import com.palmergames.bukkit.towny.object.Nation; -import com.palmergames.bukkit.towny.object.Transaction; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import com.palmergames.bukkit.towny.object.economy.BankAccount; import org.bukkit.event.HandlerList; diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/NationTransactionEvent.java b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/NationTransactionEvent.java index 1824f05289..a17f5a9037 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/NationTransactionEvent.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/NationTransactionEvent.java @@ -1,7 +1,7 @@ package com.palmergames.bukkit.towny.event.economy; import com.palmergames.bukkit.towny.object.Nation; -import com.palmergames.bukkit.towny.object.Transaction; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import com.palmergames.bukkit.towny.object.economy.BankAccount; /** diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownPreTransactionEvent.java b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownPreTransactionEvent.java index 3c9eae19ce..74a4f84172 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownPreTransactionEvent.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownPreTransactionEvent.java @@ -2,7 +2,7 @@ import com.palmergames.bukkit.towny.event.CancellableTownyEvent; import com.palmergames.bukkit.towny.object.Town; -import com.palmergames.bukkit.towny.object.Transaction; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import com.palmergames.bukkit.towny.object.economy.BankAccount; import org.bukkit.event.HandlerList; diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownTransactionEvent.java b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownTransactionEvent.java index 00ed52100e..d0c1d101e7 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownTransactionEvent.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownTransactionEvent.java @@ -1,7 +1,7 @@ package com.palmergames.bukkit.towny.event.economy; import com.palmergames.bukkit.towny.object.Town; -import com.palmergames.bukkit.towny.object.Transaction; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import com.palmergames.bukkit.towny.object.economy.BankAccount; /** diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownyPreTransactionEvent.java b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownyPreTransactionEvent.java index 9a7322e56e..27b0947bf7 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownyPreTransactionEvent.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownyPreTransactionEvent.java @@ -1,8 +1,7 @@ package com.palmergames.bukkit.towny.event.economy; -import com.palmergames.bukkit.towny.TownyEconomyHandler; import com.palmergames.bukkit.towny.event.CancellableTownyEvent; -import com.palmergames.bukkit.towny.object.Transaction; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import com.palmergames.bukkit.towny.object.economy.Account; import org.bukkit.event.HandlerList; @@ -40,19 +39,11 @@ public Transaction getTransaction() { * @return the future balance of the {@link Account} if this event is not * cancelled. */ - public int getNewBalance() { - switch (transaction.getType()) { - case ADD: - return (int) (TownyEconomyHandler.getBalance(transaction.getPlayer().getName(), - transaction.getPlayer().getWorld()) + transaction.getAmount()); - case SUBTRACT: - return (int) (TownyEconomyHandler.getBalance(transaction.getPlayer().getName(), - transaction.getPlayer().getWorld()) - transaction.getAmount()); - default: - break; - } - - return 0; + public double getNewBalance() { + return switch (transaction.getType()) { + case ADD, DEPOSIT -> transaction.getReceivingAccount().getHoldingBalance() + transaction.getAmount(); + case SUBTRACT, WITHDRAW -> transaction.getReceivingAccount().getHoldingBalance() - transaction.getAmount(); + }; } public static HandlerList getHandlerList() { diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownyTransactionEvent.java b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownyTransactionEvent.java index 089ae790eb..b32ae4182a 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownyTransactionEvent.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/event/economy/TownyTransactionEvent.java @@ -1,6 +1,6 @@ package com.palmergames.bukkit.towny.event.economy; -import com.palmergames.bukkit.towny.object.Transaction; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/EconomyAccount.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/EconomyAccount.java index 35e739af6c..8b6da4617c 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/EconomyAccount.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/EconomyAccount.java @@ -2,37 +2,36 @@ import com.palmergames.bukkit.towny.TownyEconomyHandler; import com.palmergames.bukkit.towny.object.economy.Account; -import com.palmergames.bukkit.towny.object.economy.TownyServerAccount; +import com.palmergames.bukkit.towny.object.economy.BankAccount; import org.bukkit.World; /** - * Economy object which provides an interface with the Economy Handler. + * An Account object representing a Player's account. In contrast to the + * {@link BankAccount} that represents Towns' and Nations' Accounts. * * @author ElgarL * @author Shade * @author Suneet Tipirneni (Siris) + * @author LlmDl */ public class EconomyAccount extends Account { - public static final TownyServerAccount SERVER_ACCOUNT = new TownyServerAccount(); private World world; - protected EconomyAccount(String name, World world) { - super(name); + protected EconomyAccount(Resident resident, String name, World world) { + super(resident, name); this.world = world; } @Override protected synchronized boolean addMoney(double amount) { - return TownyEconomyHandler.add(getName(), amount, world); + + return TownyEconomyHandler.add(this, amount, world); + } @Override protected synchronized boolean subtractMoney(double amount) { - return TownyEconomyHandler.subtract(getName(), amount, world); - } - - protected EconomyAccount(String name) { - super(name); + return TownyEconomyHandler.subtract(this, amount, world); } public World getWorld() { diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Government.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Government.java index 07d7e5652e..fc4e892b20 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Government.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Government.java @@ -266,7 +266,7 @@ public final synchronized void depositToBank(Resident resident, int amount) thro if (!TownyEconomyHandler.isActive()) { throw new TownyException(Translation.of("msg_err_no_economy")); } - if (!resident.getAccount().payTo(amount, getAccount(), "Deposit from " + resident.getName())) { + if (!resident.getAccount().payTo(amount, this, "Deposit from " + resident.getName())) { throw new TownyException(Translation.of("msg_insuf_funds")); } } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Resident.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Resident.java index 32b5ba4c21..cba6581f1e 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Resident.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Resident.java @@ -819,7 +819,7 @@ public Account getAccount() { world = BukkitTools.getWorlds().get(0); } - account = new EconomyAccount(accountName, world); + account = new EconomyAccount(this, accountName, world); } return account; diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Transaction.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Transaction.java index b870451f34..8c8abda690 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/Transaction.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/Transaction.java @@ -4,6 +4,11 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; + +/** + * @deprecated since 0.100.4.0 use {@link com.palmergames.bukkit.towny.object.economy.transaction.Transaction} instead. + */ +@Deprecated public class Transaction { private final TransactionType type; private final CommandSender sender; diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/TransactionType.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/TransactionType.java index bd1723cfb3..59ca08c526 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/TransactionType.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/TransactionType.java @@ -1,5 +1,10 @@ package com.palmergames.bukkit.towny.object; + +/** + * @deprecated since 0.100.4.0 use {@link com.palmergames.bukkit.towny.object.economy.transaction.TransactionType} instead. + */ +@Deprecated public enum TransactionType { DEPOSIT("Deposit"), WITHDRAW("Withdraw"), ADD("Add"), SUBTRACT("Subtract"); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/Account.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/Account.java index e946474ccc..17753445f1 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/Account.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/Account.java @@ -7,6 +7,7 @@ import com.palmergames.bukkit.towny.object.EconomyAccount; import com.palmergames.bukkit.towny.object.EconomyHandler; import com.palmergames.bukkit.towny.object.Nameable; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import com.palmergames.bukkit.util.BukkitTools; import org.bukkit.World; @@ -24,17 +25,20 @@ * @see EconomyAccount */ public abstract class Account implements Nameable { + public static final TownyServerAccount SERVER_ACCOUNT = TownyEconomyHandler.initializeTownyServerAccount(); private static final long CACHE_TIMEOUT = TownySettings.getCachedBankTimeout(); private static final AccountObserver GLOBAL_OBSERVER = new GlobalAccountObserver(); private final List observers = new ArrayList<>(); + private final EconomyHandler economyHandler; private AccountAuditor auditor; protected CachedBalance cachedBalance = null; String name; World world; - public Account(String name) { + public Account(EconomyHandler economyHandler, String name) { this.name = name; + this.economyHandler = economyHandler; // ALL account transactions will route auditing data through this // central auditor. @@ -49,8 +53,8 @@ public Account(String name) { } } - public Account(String name, World world) { - this(name); + public Account(EconomyHandler economyHandler, String name, World world) { + this(economyHandler, name); this.world = world; } @@ -72,6 +76,7 @@ public synchronized boolean deposit(double amount, String reason) { if (TownySettings.getBoolean(ConfigNodes.ECO_CLOSED_ECONOMY_ENABLED)) return payFromServer(amount, reason); + BukkitTools.fireEvent(Transaction.add(amount).paidTo(this).asTownyTransactionEvent()); return true; } @@ -92,6 +97,7 @@ public synchronized boolean withdraw(double amount, String reason) { if (TownySettings.getBoolean(ConfigNodes.ECO_CLOSED_ECONOMY_ENABLED)) return payToServer(amount, reason); + BukkitTools.fireEvent(Transaction.subtract(amount).paidBy(this).asTownyTransactionEvent()); return true; } @@ -111,15 +117,19 @@ public synchronized boolean payTo(double amount, EconomyHandler collector, Strin } protected synchronized boolean payToServer(double amount, String reason) { - notifyObserversDeposit(EconomyAccount.SERVER_ACCOUNT, amount, reason); // Put it back into the server. - return TownyEconomyHandler.addToServer(amount, getBukkitWorld()); + boolean success = Account.SERVER_ACCOUNT.addToServer(this, amount, getBukkitWorld()); + if (success) + notifyObserversDeposit(Account.SERVER_ACCOUNT, amount, reason); + return success; } protected synchronized boolean payFromServer(double amount, String reason) { - notifyObserversWithdraw(EconomyAccount.SERVER_ACCOUNT, amount, reason); // Remove it from the server economy. - return TownyEconomyHandler.subtractFromServer(amount, getBukkitWorld()); + boolean success = Account.SERVER_ACCOUNT.subtractFromServer(this, amount, getBukkitWorld()); + if (success) + notifyObserversWithdraw(Account.SERVER_ACCOUNT, amount, reason); + return success; } /** @@ -136,7 +146,10 @@ public synchronized boolean payTo(double amount, Account collector, String reaso return false; } - return withdraw(amount, reason) && collector.deposit(amount, reason); + boolean success = withdraw(amount, reason) && collector.deposit(amount, reason); + if (success) + BukkitTools.fireEvent(Transaction.add(amount).paidBy(this).paidTo(collector).asTownyTransactionEvent()); + return success; } /** @@ -214,11 +227,19 @@ public void removeAccount() { if (TownySettings.isEcoClosedEconomyEnabled()) { double balance = TownyEconomyHandler.getBalance(getName(), getBukkitWorld()); if (balance > 0) - TownyEconomyHandler.addToServer(balance, getBukkitWorld()); + Account.SERVER_ACCOUNT.addToServer(this, balance, getBukkitWorld()); } TownyEconomyHandler.removeAccount(getName()); } + /** + * @return the EconomyHandler that this Account represents. Could be a Resident, + * Town, Nation or the TownyServerAccount. + */ + public EconomyHandler getEconomyHandler() { + return economyHandler; + } + @Override public String getName() { return name; diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/BankAccount.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/BankAccount.java index b4e21c66ff..42b7c95623 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/BankAccount.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/BankAccount.java @@ -32,7 +32,7 @@ public class BankAccount extends Account { * @param government Town or Nation that is getting a BankAccount. */ public BankAccount(String name, World world, Government government) { - super(name, world); + super(government, name, world); this.government = government; } @@ -71,7 +71,7 @@ protected synchronized boolean subtractMoney(double amount) { } // Otherwise continue like normal. - return TownyEconomyHandler.subtract(getName(), amount, world); + return TownyEconomyHandler.subtract(this, amount, world); } @Override @@ -84,7 +84,7 @@ protected synchronized boolean addMoney(double amount) { return removeDebt(amount); // Otherwise continue like normal. - return TownyEconomyHandler.add(getName(), amount, world); + return TownyEconomyHandler.add(this, amount, world); } @Override diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/BankTransaction.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/BankTransaction.java index d4e1e4d054..28bd373f1e 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/BankTransaction.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/BankTransaction.java @@ -2,7 +2,7 @@ import java.text.SimpleDateFormat; -import com.palmergames.bukkit.towny.object.TransactionType; +import com.palmergames.bukkit.towny.object.economy.transaction.TransactionType; public class BankTransaction { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM d ''yy '@' HH:mm:ss"); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/GovernmentAccountAuditor.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/GovernmentAccountAuditor.java index 010202f99c..c43d67824d 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/GovernmentAccountAuditor.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/GovernmentAccountAuditor.java @@ -7,7 +7,7 @@ import com.palmergames.bukkit.util.Colors; import com.palmergames.bukkit.towny.Towny; import com.palmergames.bukkit.towny.TownyEconomyHandler; -import com.palmergames.bukkit.towny.object.TransactionType; +import com.palmergames.bukkit.towny.object.economy.transaction.TransactionType; public class GovernmentAccountAuditor implements AccountAuditor { diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/TownyServerAccount.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/TownyServerAccount.java index d85b6417dd..7dbab58661 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/TownyServerAccount.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/TownyServerAccount.java @@ -2,19 +2,28 @@ import java.util.UUID; +import org.bukkit.World; + import com.palmergames.bukkit.config.ConfigNodes; import com.palmergames.bukkit.towny.TownyEconomyHandler; import com.palmergames.bukkit.towny.TownySettings; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; +import com.palmergames.bukkit.util.BukkitTools; /** * For internal use only. */ -public class TownyServerAccount extends Account { +public class TownyServerAccount extends Account implements TownyServerAccountEconomyHandler { + private final static UUID uuid = UUID.fromString("a73f39b0-1b7c-4930-b4a3-ce101812d926"); private final static String name = TownySettings.getString(ConfigNodes.ECO_CLOSED_ECONOMY_SERVER_ACCOUNT); public TownyServerAccount() { - super(name); + super(null, name); + } + + public TownyServerAccount(TownyServerAccountEconomyHandler economyHandler) { + super(economyHandler, name); } public static UUID getUUID() { @@ -23,11 +32,51 @@ public static UUID getUUID() { @Override protected synchronized boolean addMoney(double amount) { - return TownyEconomyHandler.add(getName(), amount, world); + return TownyEconomyHandler.add(this, amount, world); } @Override protected synchronized boolean subtractMoney(double amount) { - return TownyEconomyHandler.subtract(getName(), amount, world); + return TownyEconomyHandler.subtract(this, amount, world); + } + + + /** + * Adds money to the server account (used for towny closed economy.) + * + * @param account Account sending money to the server. + * @param amount The amount to deposit. + * @param world The world of the deposit. + * @return A boolean indicating success. + */ + @Override + public boolean addToServer(Account account, double amount, World world) { + boolean success = TownyEconomyHandler.add(this, amount, world); + if (success) + BukkitTools.fireEvent(Transaction.add(amount).paidBy(account).paidToServer().asTownyTransactionEvent()); + + return success; } + + /** + * Removes money to the server account (used for towny closed economy.) + * + * @param amount The amount to withdraw. + * @param world The world of the withdraw. + * @return A boolean indicating success. + */ + @Override + public boolean subtractFromServer(Account account, double amount, World world) { + boolean success = TownyEconomyHandler.subtract(this, amount, world); + if (success) + BukkitTools.fireEvent(Transaction.subtract(amount).paidByServer().paidTo(account).asTownyTransactionEvent()); + + return success; + } + + @Override + public Account getAccount() { + return this; + } + } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/TownyServerAccountEconomyHandler.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/TownyServerAccountEconomyHandler.java new file mode 100644 index 0000000000..247063dc44 --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/TownyServerAccountEconomyHandler.java @@ -0,0 +1,23 @@ +package com.palmergames.bukkit.towny.object.economy; + +import org.bukkit.World; + +import com.palmergames.bukkit.towny.object.EconomyHandler; + +/** + * Defines methods necessary for the TownyServerAccount, used mainly in the + * closed economy feature. + */ +public interface TownyServerAccountEconomyHandler extends EconomyHandler { + /** + * Gets the account associated with the TownyServerAccount + * + * @return The TownyServerAccount + */ + @Override + Account getAccount(); // Covariant return type of Account from superinterface + + public boolean addToServer(Account account, double amount, World world); + + public boolean subtractFromServer(Account account, double amount, World world); +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/transaction/Transaction.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/transaction/Transaction.java new file mode 100644 index 0000000000..8f80a46626 --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/transaction/Transaction.java @@ -0,0 +1,77 @@ +package com.palmergames.bukkit.towny.object.economy.transaction; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; + +import com.palmergames.bukkit.towny.object.Resident; +import com.palmergames.bukkit.towny.object.economy.Account; + +public class Transaction { + private final TransactionType type; + private final Account receivingAccount; + private final Account sendingAccount; + private final double amount; + + public Transaction(TransactionBuilder builder) { + this.type = builder.type; + this.receivingAccount = builder.receivingAccount; + this.sendingAccount = builder.sendingAccount; + this.amount = builder.amount; + } + + public static TransactionBuilder add(double amount) { + return new TransactionBuilder(amount, TransactionType.ADD); + } + + public static TransactionBuilder subtract(double amount) { + return new TransactionBuilder(amount, TransactionType.SUBTRACT); + } + + public static TransactionBuilder deposit(double amount) { + return new TransactionBuilder(amount, TransactionType.DEPOSIT); + } + + public static TransactionBuilder withdraw(double amount) { + return new TransactionBuilder(amount, TransactionType.WITHDRAW); + } + + public TransactionType getType() { + return type; + } + + @Nullable + public Account getReceivingAccount() { + return receivingAccount; + } + + public boolean hasReceiverAccount() { + return receivingAccount != null; + } + + @Nullable + public Account getSendingAccount() { + return sendingAccount; + } + + public boolean hasSenderAccount() { + return sendingAccount != null; + } + + /** + * In the case of a Transaction where a player deposits money into a town or + * nation bank, this will return the player, or null if it is not a transaction + * where a player sent money. + * + * @return the Player that sent money or null. + */ + @Nullable + public Player getSendingPlayer() { + if (hasSenderAccount() && getSendingAccount().getEconomyHandler() instanceof Resident resident) + return resident.getPlayer(); + return null; + } + + public double getAmount() { + return amount; + } +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/transaction/TransactionBuilder.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/transaction/TransactionBuilder.java new file mode 100644 index 0000000000..fc66862cc1 --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/transaction/TransactionBuilder.java @@ -0,0 +1,55 @@ +package com.palmergames.bukkit.towny.object.economy.transaction; + +import com.palmergames.bukkit.towny.event.economy.TownyTransactionEvent; +import com.palmergames.bukkit.towny.object.EconomyHandler; +import com.palmergames.bukkit.towny.object.economy.Account; + +public class TransactionBuilder { + TransactionType type; + Account receivingAccount; + Account sendingAccount; + double amount; + + public TransactionBuilder(double amount, TransactionType type) { + this.amount = amount; + this.type = type; + } + + public TransactionBuilder paidTo(Account account) { + this.receivingAccount = account; + return this; + } + + public TransactionBuilder paidTo(EconomyHandler handler) { + this.receivingAccount = handler.getAccount(); + return this; + } + + public TransactionBuilder paidToServer() { + this.receivingAccount = Account.SERVER_ACCOUNT; + return this; + } + + public TransactionBuilder paidBy(Account account) { + this.sendingAccount = account; + return this; + } + + public TransactionBuilder paidBy(EconomyHandler handler) { + this.sendingAccount = handler.getAccount(); + return this; + } + + public TransactionBuilder paidByServer() { + this.sendingAccount = Account.SERVER_ACCOUNT; + return this; + } + + public Transaction build() { + return new Transaction(this); + } + + public TownyTransactionEvent asTownyTransactionEvent() { + return new TownyTransactionEvent(new Transaction(this)); + } +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/transaction/TransactionType.java b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/transaction/TransactionType.java new file mode 100644 index 0000000000..7ec99af9c4 --- /dev/null +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/object/economy/transaction/TransactionType.java @@ -0,0 +1,15 @@ +package com.palmergames.bukkit.towny.object.economy.transaction; + +public enum TransactionType { + DEPOSIT("Deposit"), WITHDRAW("Withdraw"), ADD("Add"), SUBTRACT("Subtract"); + + private final String name; + + TransactionType(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java index b4ad7f9784..f4ee800f72 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java @@ -353,7 +353,7 @@ private String processTownPaysNationTax(Town town, Nation nation) { private void payNationTaxToTown(Nation nation, Town town, double tax) { if (!nation.getAccount().canPayFromHoldings(tax)) return; - nation.getAccount().payTo(tax, town.getAccount(), "Nation Tax Payment To Town"); + nation.getAccount().payTo(tax, town, "Nation Tax Payment To Town"); taxCollected += tax; } @@ -510,7 +510,7 @@ private boolean collectTownTaxFromResident(double tax, Resident resident, Town t private void payTownTaxToResidents(Town town, Resident resident, double tax) { if (!town.getAccount().canPayFromHoldings(tax)) return; - town.getAccount().payTo(tax, resident.getAccount(), "Town Tax Payment To Resident"); + town.getAccount().payTo(tax, resident, "Town Tax Payment To Resident"); taxCollected += tax; } @@ -596,7 +596,7 @@ private boolean collectPlotTaxFromResident(double tax, Resident resident, Town t private void payPlotTaxToResidents(double tax, Resident resident, Town town, String typeName) { if (!town.getAccount().canPayFromHoldings(tax)) return; - town.getAccount().payTo(tax, resident.getAccount(), String.format("Plot Tax Payment To Resident (%s)", typeName)); + town.getAccount().payTo(tax, resident, String.format("Plot Tax Payment To Resident (%s)", typeName)); taxCollected += tax; } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/TeleportWarmupTimerTask.java b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/TeleportWarmupTimerTask.java index e30707d4a3..b91581c10f 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/TeleportWarmupTimerTask.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/tasks/TeleportWarmupTimerTask.java @@ -135,7 +135,7 @@ public static boolean abortTeleportRequest(@Nullable Resident resident, Cancelle return false; if (request.teleportCost() != 0 && TownyEconomyHandler.isActive() && request.teleportAccount() != null) { - TownyEconomyHandler.economyExecutor().execute(() -> request.teleportAccount().payTo(request.teleportCost(), resident.getAccount(), Translation.of("msg_cost_spawn_refund"))); + TownyEconomyHandler.economyExecutor().execute(() -> request.teleportAccount().payTo(request.teleportCost(), resident, Translation.of("msg_cost_spawn_refund"))); TownyMessaging.sendMsg(resident, Translatable.of("msg_cost_spawn_refund")); } diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/MoneyUtil.java b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/MoneyUtil.java index ca17d9a8d8..e4fc02f695 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/MoneyUtil.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/MoneyUtil.java @@ -29,8 +29,7 @@ import com.palmergames.bukkit.towny.object.TownBlockType; import com.palmergames.bukkit.towny.object.TownBlockTypeCache.CacheType; import com.palmergames.bukkit.towny.object.statusscreens.StatusScreen; -import com.palmergames.bukkit.towny.object.Transaction; -import com.palmergames.bukkit.towny.object.TransactionType; +import com.palmergames.bukkit.towny.object.economy.transaction.Transaction; import com.palmergames.bukkit.util.BukkitTools; import net.kyori.adventure.text.Component; @@ -59,9 +58,9 @@ public static void townWithdraw(Player player, Resident resident, Town town, int try { commonTests(amount, resident, town, player.getLocation(), false, true); - - Transaction transaction = new Transaction(TransactionType.WITHDRAW, player, amount); - + + Transaction transaction = Transaction.withdraw(amount).paidBy(town).paidTo(resident).build(); + BukkitTools.ifCancelledThenThrow(new TownPreTransactionEvent(town, transaction)); // Withdraw from bank. @@ -81,8 +80,8 @@ public static void townDeposit(Player player, Resident resident, Town town, Nati try { commonTests(amount, resident, town, player.getLocation(), false, false); - Transaction transaction = new Transaction(TransactionType.DEPOSIT, player, amount); - + Transaction transaction = Transaction.deposit(amount).paidBy(resident).paidTo(town).build(); + BukkitTools.ifCancelledThenThrow(new TownPreTransactionEvent(town, transaction)); if (nation == null) { @@ -108,7 +107,7 @@ public static void nationWithdraw(Player player, Resident resident, Nation natio try { commonTests(amount, resident, nation.getCapital(), player.getLocation(), true, true); - Transaction transaction = new Transaction(TransactionType.WITHDRAW, player, amount); + Transaction transaction = Transaction.withdraw(amount).paidBy(nation).paidTo(resident).build(); BukkitTools.ifCancelledThenThrow(new NationPreTransactionEvent(nation, transaction)); @@ -128,7 +127,7 @@ public static void nationDeposit(Player player, Resident resident, Nation nation try { commonTests(amount, resident, nation.getCapital(), player.getLocation(), true, false); - Transaction transaction = new Transaction(TransactionType.DEPOSIT, player, amount); + Transaction transaction = Transaction.deposit(amount).paidBy(resident).paidTo(nation).build(); BukkitTools.ifCancelledThenThrow(new NationPreTransactionEvent(nation, transaction)); diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/SpawnUtil.java b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/SpawnUtil.java index d92b483db5..9d372bcc03 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/SpawnUtil.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/SpawnUtil.java @@ -37,7 +37,6 @@ import com.palmergames.bukkit.towny.object.SpawnType; import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.TownBlock; -import com.palmergames.bukkit.towny.object.EconomyAccount; import com.palmergames.bukkit.towny.object.TownyObject; import com.palmergames.bukkit.towny.permissions.PermissionNodes; import com.palmergames.bukkit.towny.tasks.CooldownTimerTask; @@ -101,7 +100,7 @@ public static void sendToTownySpawn(Player player, String[] split, TownyObject t if (spawnInfo.travelCost > 0) { // Get paymentMsg for the money.csv and the Account being paid. final String paymentMsg = getPaymentMsg(spawnInfo.townSpawnLevel, spawnInfo.nationSpawnLevel, spawnType); - final Account payee = TownySettings.isTownSpawnPaidToTown() ? getPayee(town, nation, spawnType) : EconomyAccount.SERVER_ACCOUNT; + final Account payee = TownySettings.isTownSpawnPaidToTown() ? getPayee(town, nation, spawnType) : Account.SERVER_ACCOUNT; initiateCostedSpawn(player, resident, spawnLoc, spawnInfo.travelCost, payee, paymentMsg, ignoreWarn, spawnInfo.cooldown); // No Cost so skip confirmation system. } else @@ -615,7 +614,7 @@ private static String getPaymentMsg(TownSpawnLevel townSpawnLevel, NationSpawnLe */ private static Account getPayee(Town town, Nation nation, SpawnType spawnType) { return switch(spawnType) { - case RESIDENT -> town == null ? EconomyAccount.SERVER_ACCOUNT : town.getAccount(); + case RESIDENT -> town == null ? Account.SERVER_ACCOUNT : town.getAccount(); case TOWN -> town.getAccount(); case NATION -> nation.getAccount(); }; diff --git a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/TownRuinUtil.java b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/TownRuinUtil.java index 0b41795ad0..1a758472b5 100644 --- a/Towny/src/main/java/com/palmergames/bukkit/towny/utils/TownRuinUtil.java +++ b/Towny/src/main/java/com/palmergames/bukkit/towny/utils/TownRuinUtil.java @@ -83,7 +83,7 @@ public static void putTownIntoRuinedState(Town town) { if (nation != null) { double bankBalance = town.getAccount().getHoldingBalance(); if (TownySettings.areRuinedTownsBanksPaidToNation() && bankBalance > 0) - town.getAccount().payTo(bankBalance, nation.getAccount(), String.format("Ruined Town (%s) Paid Remaining Bank To Nation", town.getName())); + town.getAccount().payTo(bankBalance, nation, String.format("Ruined Town (%s) Paid Remaining Bank To Nation", town.getName())); town.removeNation(); }