SaneEconomy/SaneEconomyCore/src/main/java/org/appledash/saneeconomy/economy/EconomyManager.java

227 lines
7.8 KiB
Java
Raw Normal View History

2016-06-14 05:06:58 +02:00
package org.appledash.saneeconomy.economy;
import org.appledash.saneeconomy.ISaneEconomy;
2016-06-14 05:06:58 +02:00
import org.appledash.saneeconomy.economy.backend.EconomyStorageBackend;
import org.appledash.saneeconomy.economy.economable.Economable;
2016-09-21 10:16:36 +02:00
import org.appledash.saneeconomy.economy.transaction.Transaction;
import org.appledash.saneeconomy.economy.transaction.TransactionResult;
import org.appledash.saneeconomy.event.SaneEconomyTransactionEvent;
import org.appledash.saneeconomy.utils.MapUtil;
2016-06-15 01:47:14 +02:00
import org.appledash.saneeconomy.utils.NumberUtils;
2016-07-12 02:22:07 +02:00
import org.bukkit.Bukkit;
2016-06-15 01:19:00 +02:00
import org.bukkit.OfflinePlayer;
2016-06-14 05:06:58 +02:00
2016-07-12 02:22:07 +02:00
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
2016-06-14 05:06:58 +02:00
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*
* Represents our EconomyManager, which manages players' balances.
*/
public class EconomyManager {
2016-09-18 11:11:22 +02:00
private final ISaneEconomy saneEconomy;
2016-06-14 10:59:16 +02:00
private final Currency currency;
private final EconomyStorageBackend backend;
2017-02-14 17:28:04 +01:00
private final String serverAccountName;
2016-06-14 05:06:58 +02:00
2017-02-14 17:28:04 +01:00
public EconomyManager(ISaneEconomy saneEconomy, Currency currency, EconomyStorageBackend backend, String serverAccountName) {
this.saneEconomy = saneEconomy;
2016-06-14 05:06:58 +02:00
this.currency = currency;
this.backend = backend;
2017-02-14 17:28:04 +01:00
this.serverAccountName = serverAccountName;
2016-06-14 05:06:58 +02:00
}
/**
* Get the Currency we're using/
* @return Currency
*/
public Currency getCurrency() {
return currency;
}
/**
* Get the balance of a player, formatted according to our Currency's format.
* @param player Player
* @return Formatted balance
*/
public String getFormattedBalance(Economable player) {
2016-06-14 05:06:58 +02:00
return currency.formatAmount(backend.getBalance(player));
}
/**
* Check whether a player has used the economy system before.
* @param player Player to check
* @return True if they have used the economy system before, false otherwise
*/
public boolean accountExists(Economable player) {
return backend.accountExists(player);
}
2016-06-14 05:06:58 +02:00
/**
* Get a player's balance.
* @param targetPlayer Player to get balance of
* @return Player's balance
*/
public double getBalance(Economable targetPlayer) {
2016-09-21 10:16:36 +02:00
if (targetPlayer == Economable.CONSOLE) {
return Double.MAX_VALUE;
}
2016-06-14 05:06:58 +02:00
return backend.getBalance(targetPlayer);
}
2016-06-15 01:19:00 +02:00
2016-06-14 05:06:58 +02:00
/**
* Check if a player has a certain amount of money.
* @param targetPlayer Player to check balance of
* @param requiredBalance How much money we're checking for
* @return True if they have requiredBalance or more, false otherwise
*/
public boolean hasBalance(Economable targetPlayer, double requiredBalance) {
2017-11-21 20:01:52 +01:00
return (targetPlayer == Economable.CONSOLE) || (getBalance(targetPlayer) >= requiredBalance);
2016-09-21 10:16:36 +02:00
2016-06-14 05:06:58 +02:00
}
/**
* Add to a player's balance.
* @param targetPlayer Player to add to
* @param amount Amount to add
* @throws IllegalArgumentException If amount is negative
*/
2016-09-21 23:37:51 +02:00
private void addBalance(Economable targetPlayer, double amount) {
amount = NumberUtils.filterAmount(currency, amount);
2016-06-15 01:47:14 +02:00
2016-06-14 05:06:58 +02:00
if (amount < 0) {
throw new IllegalArgumentException("Cannot add a negative amount!");
}
2016-09-21 10:16:36 +02:00
if (targetPlayer == Economable.CONSOLE) {
2016-09-21 23:37:51 +02:00
return;
2016-09-21 10:16:36 +02:00
}
double newAmount = backend.getBalance(targetPlayer) + amount;
2016-09-21 10:16:36 +02:00
setBalance(targetPlayer, newAmount);
2016-06-14 05:06:58 +02:00
}
/**
* Subtract from a player's balance.
* If the subtraction would result in a negative balance, the balance is instead set to 0.
* @param targetPlayer Player to subtract from
* @param amount Amount to subtract
* @throws IllegalArgumentException If amount is negative
*/
2016-09-21 23:37:51 +02:00
private void subtractBalance(Economable targetPlayer, double amount) {
amount = NumberUtils.filterAmount(currency, amount);
2016-06-15 01:47:14 +02:00
2016-06-14 05:06:58 +02:00
if (amount < 0) {
throw new IllegalArgumentException("Cannot subtract a negative amount!");
}
2016-09-21 10:16:36 +02:00
if (targetPlayer == Economable.CONSOLE) {
2016-09-21 23:37:51 +02:00
return;
2016-09-21 10:16:36 +02:00
}
double newAmount = backend.getBalance(targetPlayer) - amount;
2016-06-14 05:06:58 +02:00
/* Subtracting that much would result in a negative balance - don't do that */
if (newAmount <= 0.0D) {
newAmount = 0.0D;
2016-06-14 05:06:58 +02:00
}
2016-09-21 10:16:36 +02:00
setBalance(targetPlayer, newAmount);
2016-06-14 05:06:58 +02:00
}
/**
2016-09-21 10:16:36 +02:00
* Set a player's balance. This does NOT log.
2016-06-14 05:06:58 +02:00
* @param targetPlayer Player to set balance of
* @param amount Amount to set balance to
* @throws IllegalArgumentException If amount is negative
*/
2016-09-21 10:16:36 +02:00
public void setBalance(Economable targetPlayer, double amount) {
amount = NumberUtils.filterAmount(currency, amount);
2016-06-15 01:47:14 +02:00
2016-06-14 05:06:58 +02:00
if (amount < 0) {
2016-09-22 09:54:46 +02:00
throw new IllegalArgumentException("Cannot subtract a negative amount!");
2016-06-14 05:06:58 +02:00
}
2016-09-21 10:16:36 +02:00
if (targetPlayer == Economable.CONSOLE) {
return;
}
2016-06-14 05:06:58 +02:00
backend.setBalance(targetPlayer, amount);
}
/**
2016-09-22 09:54:46 +02:00
* Perform a transaction - a transfer of funds from one entity to another.
2016-09-21 10:16:36 +02:00
* @param transaction Transaction to perform.
2016-09-22 09:54:46 +02:00
* @return TransactionResult describing success or failure of the Transaction.
2016-06-14 05:06:58 +02:00
*/
2016-09-21 10:16:36 +02:00
public TransactionResult transact(Transaction transaction) {
Economable sender = transaction.getSender();
Economable receiver = transaction.getReceiver();
2016-09-22 09:54:46 +02:00
double amount = transaction.getAmount(); // This amount is validated upon creation of Transaction
2016-09-21 10:16:36 +02:00
if (Bukkit.getServer().getPluginManager() != null) { // Bukkit.getServer() == null from our JUnit tests.
2017-07-05 15:59:34 +02:00
SaneEconomyTransactionEvent evt = new SaneEconomyTransactionEvent(transaction);
Bukkit.getServer().getPluginManager().callEvent(evt);
if (evt.isCancelled()) {
return new TransactionResult(transaction, TransactionResult.Status.CANCELLED_BY_PLUGIN);
}
}
2016-10-02 17:33:30 +02:00
if (transaction.isSenderAffected()) { // Sender should have balance taken from them
if (!hasBalance(sender, amount)) {
2016-09-22 09:54:46 +02:00
return new TransactionResult(transaction, TransactionResult.Status.ERR_NOT_ENOUGH_FUNDS);
2016-09-21 10:16:36 +02:00
}
2016-06-14 05:06:58 +02:00
2016-09-21 10:16:36 +02:00
subtractBalance(sender, amount);
2016-06-14 05:06:58 +02:00
}
2016-10-02 17:33:30 +02:00
if (transaction.isReceiverAffected()) { // Receiver should have balance added to them
2016-10-02 10:27:47 +02:00
addBalance(receiver, amount);
}
2016-06-14 05:06:58 +02:00
saneEconomy.getTransactionLogger().ifPresent((logger) -> logger.logTransaction(transaction));
2016-09-21 10:16:36 +02:00
return new TransactionResult(transaction, getBalance(sender), getBalance(receiver));
2016-06-14 05:06:58 +02:00
}
2016-07-12 02:22:07 +02:00
/**
* Get the players who have the most money.
* @param amount Maximum number of players to show.
* @return Map of OfflinePlayer to Double
*/
public Map<OfflinePlayer, Double> getTopPlayerBalances(int amount, int offset) {
Map<UUID, Double> uuidBalances = backend.getTopPlayerBalances();
LinkedHashMap<OfflinePlayer, Double> playerBalances = new LinkedHashMap<>();
2016-07-12 02:22:07 +02:00
uuidBalances.forEach((uuid, balance) -> {
OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(uuid);
if (offlinePlayer != null) {
2017-11-21 20:01:52 +01:00
if ((this.saneEconomy.getVaultHook() == null) || !this.saneEconomy.getVaultHook().hasPermission(offlinePlayer, "saneeconomy.balancetop.hide")) {
playerBalances.put(Bukkit.getServer().getOfflinePlayer(uuid), balance);
}
}
});
2016-07-12 02:22:07 +02:00
return MapUtil.skipAndTake(playerBalances, offset, amount);
2016-07-12 02:22:07 +02:00
}
public EconomyStorageBackend getBackend() {
return backend;
}
2017-02-14 17:28:04 +01:00
/**
* Get the name of the "Server" economy account. This account has an infinite balance and deposits do nothing.
* @return Server economy account, or null if none.
*/
public String getServerAccountName() {
return serverAccountName;
}
2016-06-14 05:06:58 +02:00
}