/* * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT). * * Copyright (c) JCThePants (www.jcwhatever.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.jcwhatever.nucleus.providers.economy; import com.jcwhatever.nucleus.Nucleus; import com.jcwhatever.nucleus.utils.PreCon; import com.jcwhatever.nucleus.utils.observer.future.FutureResultAgent; import com.jcwhatever.nucleus.utils.observer.future.IFutureResult; import javax.annotation.Nullable; import java.util.List; import java.util.UUID; /** * Static convenience functions for accessing the economy provider. */ public final class Economy { private Economy() {} /** * Create a new transaction to perform multiple operations on before executing them. * * <p>If the transaction fails, the economy operations performed in it are undone.</p> */ public static IEconomyTransaction createTransaction() { return getProvider().createTransaction(); } /** * Get the economy providers currency. */ public static ICurrency getCurrency() { return getProvider().getCurrency(); } /** * Get a players global account. * * @param playerId The ID of the player. */ public static IAccount getAccount(UUID playerId) { PreCon.notNull(playerId); return getProvider().getAccount(playerId); } /** * Get a players global account balance. * * <p>The currency of the balance is the economy providers default currency.</p> * * @param playerId The ID of the player. */ public static double getBalance(UUID playerId) { PreCon.notNull(playerId); IAccount account = getProvider().getAccount(playerId); if (account == null) return 0; return account.getBalance(); } /** * Get a players global account balance. * * @param playerId The ID of the player. * @param currency The currency to return the amount in. */ public static double getBalance(UUID playerId, ICurrency currency) { PreCon.notNull(playerId); IAccount account = getProvider().getAccount(playerId); if (account == null) return 0; return account.getBalance(currency); } /** * Transfer money between two players global accounts. * * @param giverPlayerId The ID of the player who is giving money * @param receiverPlayerId The ID of the player who is receiving money * @param amount The amount of money to transfer. * * @return A {@link IFutureResult} that returns the result of the transaction. */ public static IFutureResult<IEconomyTransaction> transfer( UUID giverPlayerId, UUID receiverPlayerId, double amount) { return transfer(giverPlayerId, receiverPlayerId, amount, getCurrency()); } /** * Transfer money between two players global accounts. * * @param giverPlayerId The ID of the player who is giving money * @param receiverPlayerId The ID of the player who is receiving money * @param amount The amount of money to transfer. * * @return A {@link IFutureResult} that returns the result of the transaction. */ public static IFutureResult<IEconomyTransaction> transfer( UUID giverPlayerId, UUID receiverPlayerId, double amount, ICurrency currency) { PreCon.notNull(giverPlayerId); PreCon.notNull(receiverPlayerId); PreCon.positiveNumber(amount); PreCon.notNull(currency); IAccount fromAccount = getProvider().getAccount(giverPlayerId); if (fromAccount == null) { return new FutureResultAgent<IEconomyTransaction>() .error(null, "Failed to find giving players account."); } IAccount toAccount = getProvider().getAccount(receiverPlayerId); if (toAccount == null) { return new FutureResultAgent<IEconomyTransaction>() .error(null, "Failed to find receiving players account."); } return transfer(fromAccount, toAccount, amount, currency); } /** * Transfer money between two accounts. * * <p>The currency of the amount transferred is the economy providers default currency.</p> * * @param fromAccount The account to transfer money out of. * @param toAccount The account to transfer money into. * @param amount The amount to transfer. * * @return A {@link IFutureResult} that returns the result of the transaction. */ public static IFutureResult<IEconomyTransaction> transfer( IAccount fromAccount, IAccount toAccount, double amount) { return transfer(fromAccount, toAccount, amount, getCurrency()); } /** * Transfer money between two accounts. * * @param fromAccount The account to transfer money out of. * @param toAccount The account to transfer money into. * @param amount The amount to transfer. * @param currency The currency of the amount. * * @return A {@link IFutureResult} that returns the result of the transaction. */ public static IFutureResult<IEconomyTransaction> transfer( IAccount fromAccount, IAccount toAccount, double amount, ICurrency currency) { PreCon.notNull(fromAccount); PreCon.notNull(toAccount); PreCon.positiveNumber(amount); PreCon.notNull(currency); IEconomyTransaction transaction = createTransaction(); if (!transaction.withdraw(fromAccount, amount, currency)) return FutureResultAgent.errorResult(null, "Insufficient funds"); if (!transaction.deposit(toAccount, amount, currency)) return FutureResultAgent.errorResult(null, "Unable to deposit."); return transaction.commit(); } /** * Deposit money into a players global account. * * <p>The currency of the amount is the economy providers default currency.</p> * * @param playerId The ID of the player to give money to. * @param amount The amount to give the player. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> deposit(UUID playerId, double amount) { return deposit(playerId, amount, getCurrency()); } /** * Deposit money into a players global account. * * @param playerId The ID of the player to give money to. * @param amount The amount to give the player. * @param currency The currency of the amount. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> deposit( UUID playerId, double amount, ICurrency currency) { PreCon.notNull(playerId); PreCon.positiveNumber(amount); PreCon.notNull(currency); IAccount account = getProvider().getAccount(playerId); if (account == null) { return new FutureResultAgent<IEconomyTransaction>() .error(null, "Failed to retrieve account " + playerId); } return deposit(account, amount, currency); } /** * Deposit money into a players global account. * * <p>The currency of the amount is the economy providers default currency.</p> * * @param account The account to give money to. * @param amount The amount to give the player. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> deposit(IAccount account, double amount) { return deposit(account, amount, getCurrency()); } /** * Deposit money into a players global account. * * @param account The account to give money to. * @param amount The amount to give the player. * @param currency The currency of the amount. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> deposit( IAccount account, double amount, ICurrency currency) { PreCon.notNull(account); PreCon.positiveNumber(amount); PreCon.notNull(currency); IEconomyTransaction transaction = getProvider().createTransaction(); if (!transaction.deposit(account, amount, currency)) return FutureResultAgent.errorResult(null, "Failed to deposit."); return transaction.commit(); } /** * Withdraw money from a players global account. * * <p>The currency of the amount is the economy providers default currency.</p> * * @param playerId The ID of the player to take money from. * @param amount The amount to take. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> withdraw(UUID playerId, double amount) { return withdraw(playerId, amount, getCurrency()); } /** * Withdraw money from a players global account. * * @param playerId The ID of the player to take money from. * @param amount The amount to take. * @param currency The currency of the amount. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> withdraw(UUID playerId, double amount, ICurrency currency) { PreCon.notNull(playerId); PreCon.positiveNumber(amount); PreCon.notNull(currency); IAccount account = getProvider().getAccount(playerId); if (account == null) { return new FutureResultAgent<IEconomyTransaction>() .error(null, "Failed to retrieve account for " + playerId); } return withdraw(account, amount, currency); } /** * Withdraw money from a players global account. * * <p>The currency of the amount is the economy providers default currency.</p> * * @param account The account to take money from. * @param amount The amount to take. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> withdraw(IAccount account, double amount) { return withdraw(account, amount, getCurrency()); } /** * Withdraw money from a players global account. * * @param account The account to take money from. * @param amount The amount to take. * @param currency The currency of the amount. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> withdraw( IAccount account, double amount, ICurrency currency) { PreCon.notNull(account); PreCon.positiveNumber(amount); PreCon.notNull(currency); IEconomyTransaction transaction = getProvider().createTransaction(); if (!transaction.withdraw(account, amount, currency)) return FutureResultAgent.errorResult(null, "Insufficient funds."); return transaction.commit(); } /** * Deposit or withdraw money from a players global account depending on the value provided. * * <p>The currency of the amount is the economy providers default currency.</p> * * <p>Positive values are deposited, negative values are withdrawn.</p> * * @param playerId The ID of the player. * @param amount The amount to deposit or withdraw. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> depositOrWithdraw(UUID playerId, double amount) { PreCon.notNull(playerId); IAccount account = getProvider().getAccount(playerId); if (account == null) { return new FutureResultAgent<IEconomyTransaction>() .error(null, "Failed to find account for " + playerId); } return depositOrWithdraw(account, amount, getCurrency()); } /** * Deposit or withdraw money from a players global account depending on the value provided. * * <p>Positive values are deposited, negative values are withdrawn.</p> * * @param playerId The ID of the player. * @param amount The amount to deposit or withdraw. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> depositOrWithdraw( UUID playerId, double amount, ICurrency currency) { PreCon.notNull(playerId); PreCon.notNull(currency); IAccount account = getProvider().getAccount(playerId); if (account == null) { return new FutureResultAgent<IEconomyTransaction>() .error(null, "Failed to find account for " + playerId); } return depositOrWithdraw(account, amount, currency); } /** * Deposit or withdraw money from an account depending on the value provided. * * <p>The currency of the amount is the economy providers default currency.</p> * * <p>Positive values are deposited, negative values are withdrawn.</p> * * @param account The account. * @param amount The amount to deposit or withdraw. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> depositOrWithdraw(IAccount account, double amount) { return depositOrWithdraw(account, amount, getCurrency()); } /** * Deposit or withdraw money from an account depending on the value provided. * * <p>Positive values are deposited, negative values are withdrawn.</p> * * @param account The account. * @param amount The amount to deposit or withdraw. * @param currency The currency of the amount. * * @return A {@link IFutureResult} to retrieve the result of the transaction. */ public static IFutureResult<IEconomyTransaction> depositOrWithdraw( IAccount account, double amount, ICurrency currency) { PreCon.notNull(account); PreCon.notNull(currency); IEconomyTransaction transaction = getProvider().createTransaction(); if (amount >= 0) { if (!transaction.deposit(account, amount, currency)) return FutureResultAgent.errorResult(null, "Failed to deposit."); } else if (amount < 0) { if (!transaction.withdraw(account, -amount, currency)) return FutureResultAgent.errorResult(null, "Insufficient funds."); } return transaction.commit(); } /** * Determine if the economy provider has bank support. */ public static boolean hasBankSupport() { return getProvider() instanceof IBankEconomyProvider; } /** * Get a bank by name. * * @param bankName The name of the bank. * * @return Null if the bank was not found. * * @throws java.lang.UnsupportedOperationException if {@link #hasBankSupport} returns false. */ @Nullable public static IBank getBank(String bankName) { return getBankProvider().getBank(bankName); } /** * Get a list of banks. * * @throws java.lang.UnsupportedOperationException if {@link #hasBankSupport} returns false. */ public static List<IBank> getBanks() { return getBankProvider().getBanks(); } /** * Create a new bank account. * * @param bankName The name of the bank. * * @return Null if the bank was not created. * * @throws java.lang.UnsupportedOperationException if {@link #hasBankSupport} returns false. */ @Nullable public static IBank createBank(String bankName) { return getBankProvider().createBank(bankName); } /** * Create a new bank account with the specified player as the owner. * * @param bankName The name of the bank. * @param ownerId The ID of the bank owner. * * @return Null if the bank was not created. * * @throws java.lang.UnsupportedOperationException if {@link #hasBankSupport} returns false. */ @Nullable public static IBank createBank(String bankName, UUID ownerId) { return getBankProvider().createBank(bankName, ownerId); } /** * Delete a bank. * * @param bankName The name of the bank. * * @return True if the bank was found and deleted. * * @throws java.lang.UnsupportedOperationException if {@link #hasBankSupport} returns false. */ public static boolean deleteBank(String bankName) { return getBankProvider().deleteBank(bankName); } /** * Get the economy provider. */ public static IEconomyProvider getProvider() { return Nucleus.getProviders().getEconomy(); } /** * Get the bank interface for the economy provider. * * <p>Check {@link #hasBankSupport} method first before calling.</p> * * @throws java.lang.UnsupportedOperationException */ public static IBankEconomyProvider getBankProvider() { IBankEconomyProvider provider = (IBankEconomyProvider)getProvider(); if (provider == null) throw new UnsupportedOperationException(); return provider; } }