Skip to content

Commit

Permalink
Added '/peco convert' feature
Browse files Browse the repository at this point in the history
  • Loading branch information
SoKnight committed Sep 19, 2021
1 parent 4760c45 commit 4b98340
Show file tree
Hide file tree
Showing 14 changed files with 699 additions and 42 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>ru.soknight</groupId>
<artifactId>peconomy</artifactId>
<version>2.5.0</version>
<version>2.6.0</version>
<packaging>jar</packaging>

<name>PEconomy</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ public CommandPeconomy(
super("peconomy", messages);

super.setExecutor("help", new CommandHelp(messages));
super.setExecutor("info", new CommandInfo(plugin, messages, databaseManager, currenciesManager));
super.setExecutor("history", new CommandHistory(plugin, messages, databaseManager, currenciesManager));
super.setExecutor("add", new CommandAdd(messages, databaseManager, currenciesManager));
super.setExecutor("set", new CommandSet(messages, databaseManager, currenciesManager));
super.setExecutor("reset", new CommandReset(messages, databaseManager, currenciesManager));
super.setExecutor("take", new CommandTake(messages, databaseManager, currenciesManager));
super.setExecutor("info", new CommandInfo(plugin, messages, databaseManager, currenciesManager));
super.setExecutor("history", new CommandHistory(plugin, messages, databaseManager, currenciesManager));
super.setExecutor("convert", new CommandConvert(messages, databaseManager, currenciesManager));
super.setExecutor("reload", new CommandReload(plugin, messages));

super.register(plugin, true);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
package ru.soknight.peconomy.command.peconomy;

import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import ru.soknight.lib.argument.CommandArguments;
import ru.soknight.lib.command.preset.subcommand.ArgumentableSubcommand;
import ru.soknight.lib.configuration.Messages;
import ru.soknight.peconomy.api.PEconomyAPI;
import ru.soknight.peconomy.configuration.CurrenciesManager;
import ru.soknight.peconomy.configuration.CurrencyInstance;
import ru.soknight.peconomy.database.DatabaseManager;
import ru.soknight.peconomy.database.model.TransactionModel;
import ru.soknight.peconomy.database.model.WalletModel;
import ru.soknight.peconomy.format.Formatter;
import ru.soknight.peconomy.transaction.TransactionCause;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

public final class CommandConvert extends ArgumentableSubcommand {

private final Messages messages;
private final DatabaseManager databaseManager;
private final CurrenciesManager currenciesManager;

public CommandConvert(Messages messages, DatabaseManager databaseManager, CurrenciesManager currenciesManager) {
super("peco.command.convert", 3, messages);

this.messages = messages;
this.databaseManager = databaseManager;
this.currenciesManager = currenciesManager;
}

@Override
protected void executeCommand(CommandSender sender, CommandArguments args) {
float amount = args.getAsFloat(0);
if(amount <= 0F) {
messages.sendFormatted(sender, "error.arg-is-not-float", "%arg%", args.get(0));
return;
}

CurrencyInstance firstCurrency = currenciesManager.getCurrency(args.get(1));
if(firstCurrency == null) {
messages.sendFormatted(sender, "error.unknown-currency", "%currency%", args.get(1));
return;
}

CurrencyInstance secondCurrency = currenciesManager.getCurrency(args.get(2));
if(secondCurrency == null) {
messages.sendFormatted(sender, "error.unknown-currency", "%currency%", args.get(2));
return;
}

if(firstCurrency.getId().equals(secondCurrency.getId())) {
messages.getAndSend(sender, "convert.failed.same-named-currency");
return;
}

if(!firstCurrency.isConvertableTo(secondCurrency)) {
messages.sendFormatted(sender, "convert.failed.unconvertable",
"%currency_first_name%", firstCurrency.getName(),
"%currency_first%", firstCurrency.getSymbol(),
"%currency_second_name%", secondCurrency.getName(),
"%currency_second%", secondCurrency.getSymbol()
);
return;
}

String walletHolder0 = null;
if(args.size() > 3 && sender.hasPermission("peco.command.convert.other"))
walletHolder0 = args.get(3);

if(walletHolder0 == null) {
if(!isPlayer(sender)) {
messages.getAndSend(sender, "error.wrong-syntax");
return;
}

walletHolder0 = sender.getName();
}

String walletHolder = walletHolder0;
boolean other = !isPlayer(sender) || !walletHolder.equals(sender.getName());

CompletableFuture<WalletModel> walletFuture = other
? databaseManager.getWallet(walletHolder)
: databaseManager.getOrCreateWallet(walletHolder);

Formatter formatter = PEconomyAPI.get().getFormatter();
walletFuture.thenAccept(wallet -> {
if(wallet == null) {
messages.sendFormatted(sender, "convert.failed.empty-wallet", "%player%", walletHolder);
return;
}

float firstCurrencyBalancePre = wallet.getAmount(firstCurrency.getId());
float firstCurrencyBalancePost = firstCurrencyBalancePre - amount;

if(firstCurrencyBalancePost < 0F) {
if(other)
messages.sendFormatted(sender, "convert.failed.not-enough.other",
"%player%", walletHolder,
"%amount%", formatter.formatAmount(firstCurrencyBalancePre),
"%requested%", formatter.formatAmount(amount),
"%currency%", firstCurrency.getSymbol()
);
else
messages.sendFormatted(sender, "convert.failed.not-enough.self",
"%amount%", formatter.formatAmount(firstCurrencyBalancePre),
"%requested%", formatter.formatAmount(amount),
"%currency%", firstCurrency.getSymbol()
);
return;
}

float converted = firstCurrency.convert(secondCurrency, amount);

float secondCurrencyBalancePre = wallet.getAmount(secondCurrency.getId());
float secondCurrencyBalancePost = secondCurrencyBalancePre + converted;

float limit = secondCurrency.getLimit();
if(limit > 0F && secondCurrencyBalancePost > limit) {
messages.sendFormatted(sender, "convert.failed.limit-reached",
"%limit%", formatter.formatAmount(limit),
"%currency%", secondCurrency.getSymbol()
);
return;
}

wallet.takeAmount(firstCurrency.getId(), amount);
wallet.addAmount(secondCurrency.getId(), converted);

databaseManager.saveWallet(wallet).join();

String operator = isPlayer(sender) ? sender.getName() : null;

TransactionModel firstTransaction = new TransactionModel(
walletHolder,
firstCurrency.getId(),
firstCurrencyBalancePre,
firstCurrencyBalancePost,
operator,
TransactionCause.CONVERTATION
);

TransactionModel secondTransaction = new TransactionModel(
walletHolder,
secondCurrency.getId(),
secondCurrencyBalancePre,
secondCurrencyBalancePost,
operator,
TransactionCause.CONVERTATION
);

databaseManager.saveTransaction(firstTransaction).join();
databaseManager.saveTransaction(secondTransaction).join();

if(!other) {
messages.sendFormatted(sender, "convert.success.operator.self",
"%amount_first%", formatter.formatAmount(amount),
"%currency_first%", firstCurrency.getSymbol(),
"%amount_second%", formatter.formatAmount(converted),
"%currency_second%", secondCurrency.getSymbol(),
"%currency_first_name%", firstCurrency.getName(),
"%amount_first_from%", formatter.formatAmount(firstCurrencyBalancePre),
"%amount_first_to%", formatter.formatAmount(firstCurrencyBalancePost),
"%id_first%", firstTransaction.getId(),
"%currency_second_name%", secondCurrency.getName(),
"%amount_second_from%", formatter.formatAmount(secondCurrencyBalancePre),
"%amount_second_to%", formatter.formatAmount(secondCurrencyBalancePost),
"%id_second%", secondTransaction.getId()
);
return;
}

messages.sendFormatted(sender, "convert.success.operator.other",
"%player%", walletHolder,
"%amount_first%", formatter.formatAmount(amount),
"%currency_first%", firstCurrency.getSymbol(),
"%amount_second%", formatter.formatAmount(converted),
"%currency_second%", secondCurrency.getSymbol(),
"%currency_first_name%", firstCurrency.getName(),
"%amount_first_from%", formatter.formatAmount(firstCurrencyBalancePre),
"%amount_first_to%", formatter.formatAmount(firstCurrencyBalancePost),
"%id_first%", firstTransaction.getId(),
"%currency_second_name%", secondCurrency.getName(),
"%amount_second_from%", formatter.formatAmount(secondCurrencyBalancePre),
"%amount_second_to%", formatter.formatAmount(secondCurrencyBalancePost),
"%id_second%", secondTransaction.getId()
);

Player onlineHolder = Bukkit.getPlayer(walletHolder);
if(onlineHolder != null && onlineHolder.isOnline())
messages.sendFormatted(onlineHolder, "convert.success.holder",
"%amount_first%", formatter.formatAmount(amount),
"%currency_first%", firstCurrency.getSymbol(),
"%amount_second%", formatter.formatAmount(converted),
"%currency_second%", secondCurrency.getSymbol(),
"%currency_first_name%", firstCurrency.getName(),
"%amount_first_from%", formatter.formatAmount(firstCurrencyBalancePre),
"%amount_first_to%", formatter.formatAmount(firstCurrencyBalancePost),
"%id_first%", firstTransaction.getId(),
"%currency_second_name%", secondCurrency.getName(),
"%amount_second_from%", formatter.formatAmount(secondCurrencyBalancePre),
"%amount_second_to%", formatter.formatAmount(secondCurrencyBalancePost),
"%id_second%", secondTransaction.getId()
);
});
}

@Override
protected List<String> executeTabCompletion(CommandSender sender, CommandArguments args) {
if(args.size() < 2 || args.size() > 4)
return null;

if(args.size() > 3 && !sender.hasPermission("peco.command.convert.other"))
return null;

String arg = getLastArgument(args, true);
if(args.size() == 2) {
return currenciesManager.getCurrenciesIDs().stream()
.filter(id -> id.toLowerCase().startsWith(arg))
.collect(Collectors.toList());
}

CurrencyInstance firstCurrency = currenciesManager.getCurrency(args.get(1));
if(firstCurrency == null)
return null;

if(args.size() == 3) {
return firstCurrency.getConvertationSetup().getCurrenciesIDs().stream()
.filter(id -> id.toLowerCase().startsWith(arg))
.collect(Collectors.toList());
}

if(!currenciesManager.isCurrency(args.get(2)))
return null;

return Bukkit.getOnlinePlayers().stream()
.map(Player::getName)
.filter(n -> n.toLowerCase().startsWith(arg))
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,7 @@ public CommandHelp(Messages messages) {
super.factory()
.helpLineFormatFrom("help.body")
.permissionFormat("peco.command.%s")

// /peco help
.newLine()
.command("peco help")
.descriptionFrom("help")
.permission("help")
.add()

// /balance [player]
.newLine()
.command("balance", true)
Expand All @@ -32,6 +26,12 @@ public CommandHelp(Messages messages) {
.command("pay", true)
.argumentsFrom("player-req", "amount", "currency")
.add()
// /peco help
.newLine()
.command("peco help")
.descriptionFrom("help")
.permission("help")
.add()
// /peco add <player> <amount> <currency>
.newLine()
.command("peco add")
Expand Down Expand Up @@ -74,6 +74,13 @@ public CommandHelp(Messages messages) {
.descriptionFrom("history")
.permission("history")
.add()
// /peco convert <amount> <from> <to> [player]
.newLine()
.command("peco convert")
.argumentsFrom("amount", "currency-first", "currency-second", "player-opt")
.descriptionFrom("convert")
.permission("convert")
.add()
// /peco reload
.newLine()
.command("peco reload")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
import ru.soknight.lib.configuration.AbstractConfiguration;
import ru.soknight.lib.configuration.Configuration;
import ru.soknight.lib.task.PluginTask;
import ru.soknight.peconomy.balancetop.BalanceTop;
import ru.soknight.peconomy.balancetop.BalanceTopPlace;
import ru.soknight.peconomy.PEconomy;
import ru.soknight.peconomy.api.PEconomyAPI;
import ru.soknight.peconomy.balancetop.BalanceTop;
import ru.soknight.peconomy.balancetop.BalanceTopPlace;
import ru.soknight.peconomy.convertation.ConvertationSetup;
import ru.soknight.peconomy.task.BalanceTopUpdateTask;

import java.util.*;
Expand All @@ -28,8 +29,8 @@ public CurrenciesManager(@NotNull PEconomy plugin, @NotNull Configuration config
super(plugin, "currencies.yml");

this.config = config;
this.currencies = new HashMap<>();
this.updateTasks = new HashMap<>();
this.currencies = new LinkedHashMap<>();
this.updateTasks = new LinkedHashMap<>();

refreshCurrencies();
}
Expand Down Expand Up @@ -58,35 +59,45 @@ public void refreshCurrencies() {
return;
}

String name = colorize(currencyConfig.getString("name", currencyId));
String symbol = colorize(currencyConfig.getString("symbol"));

float limit = (float) currencyConfig.getDouble("max-amount", 0F);
float newbie = (float) currencyConfig.getDouble("newbie-amount", 0F);

boolean visible = currencyConfig.getBoolean("visible", true);
boolean transferable = currencyConfig.getBoolean("transferable", true);

ConvertationSetup convertationSetup = new ConvertationSetup(currencyId);
BalanceTopSetup balanceTopSetup = parseBalanceTopSetup(currencyConfig.getConfigurationSection("balance-top"));
BalanceTop balanceTop = null;

if(balanceTopSetup != null && balanceTopSetup.isValid())
if (balanceTopSetup != null && balanceTopSetup.isValid())
balanceTop = BalanceTop.create(
getPlugin(),
currencyId,
balanceTopSetup.getMaxSize(),
place -> formatPlace(balanceTopSetup, place)
);

CurrencyInstance currency = new CurrencyInstance(currencyId, name, symbol, limit, newbie, visible, transferable, balanceTopSetup, balanceTop);
CurrencyInstance currency = CurrencyInstance.builder(currencyId)
.setName(colorize(currencyConfig.getString("name", currencyId)))
.setSymbol(colorize(currencyConfig.getString("symbol")))
.setLimit(Math.max((float) currencyConfig.getDouble("max-amount", 0F), 0F))
.setNewbieAmount(Math.max((float) currencyConfig.getDouble("newbie-amount", 0F), 0F))
.setVisible(currencyConfig.getBoolean("visible", true))
.setTransferable(currencyConfig.getBoolean("transferable", true))
.setConvertationSetup(convertationSetup)
.setBalanceTopSetup(balanceTopSetup)
.setBalanceTop(balanceTop)
.create();

currencies.put(currencyId, currency);

if(balanceTop != null) {
if (balanceTop != null) {
PluginTask updateTask = new BalanceTopUpdateTask(getPlugin(), currency, balanceTop);
updateTask.start();
updateTasks.put(currencyId, updateTask);
}
});

currencies.forEach((currencyId, currency) -> {
ConfigurationSection currencyConfig = currenciesConfig.getConfigurationSection(currencyId);
ConfigurationSection convertationConfig = currencyConfig.getConfigurationSection("convertation");
if (convertationConfig != null)
currency.getConvertationSetup().load(this, convertationConfig);
});

if (config.getBoolean("hooks.vault.enabled")) {
String vault = getFileConfig().getString("vault.currency");
Expand Down
Loading

0 comments on commit 4b98340

Please sign in to comment.