diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbuy.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbuy.java new file mode 100644 index 00000000000..90a4bc3541c --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandbuy.java @@ -0,0 +1,149 @@ +package com.earth2me.essentials.commands; + +import com.earth2me.essentials.Trade; +import com.earth2me.essentials.User; +import com.earth2me.essentials.craftbukkit.Inventories; +import com.earth2me.essentials.adventure.AdventureUtil; +import com.earth2me.essentials.utils.NumberUtil; +import com.google.common.collect.Lists; +import net.ess3.api.TranslatableException; +import net.ess3.api.events.UserBalanceUpdateEvent; +import org.bukkit.ChatColor; +import org.bukkit.Server; +import org.bukkit.inventory.ItemStack; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.logging.Level; + +import static com.earth2me.essentials.I18n.tlLiteral; + +// The file commandsell.java has been used as a "template" +// Most of the code in this file is therefor a one-to-one copy from that file +public class Commandbuy extends EssentialsCommand { + public Commandbuy() { + super("buy"); + } + + // Starting point for when the command is run + @Override + public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception { + BigDecimal totalWorth = BigDecimal.ZERO; + // Throw an error if the user has not specified enough arguments. + if (args.length < 1) { + throw new NotEnoughArgumentsException(); + } + + // Let's check if the user is authorized to buy more of the stuff in hand + // Consider removing the first if. + if (args[0].equalsIgnoreCase("hand") && !user.isAuthorized("essentials.buy.hand")) { + throw new TranslatableException("buyHandPermission"); + } else if ((args[0].equalsIgnoreCase("inventory") || args[0].equalsIgnoreCase("invent") || args[0].equalsIgnoreCase("all")) && !user.isAuthorized("essentials.buy.bulk")) { + throw new TranslatableException("buyBulkPermission"); + } + + final List is = ess.getItemDb().getMatching(user, args); + int count = 0; + + final boolean isBulk = is.size() > 1; + + final List notBought = new ArrayList<>(); + for (ItemStack stack : is) { + if (!ess.getSettings().isAllowBuyNamedItems()) { + if (stack.getItemMeta() != null && stack.getItemMeta().hasDisplayName()) { + if (isBulk) { + notBought.add(stack); + continue; + } + throw new TranslatableException("cannotBuyNamedItem"); + } + } + try { + if (stack.getAmount() > 0) { + totalWorth = totalWorth.add(buyItem(user, stack, args, isBulk)); + stack = stack.clone(); + count++; + for (final ItemStack zeroStack : is) { + if (zeroStack.isSimilar(stack)) { + zeroStack.setAmount(0); + } + } + } + } catch (final Exception e) { + if (!isBulk) { + throw e; + } + } + } + if (!notBought.isEmpty()) { + final List names = new ArrayList<>(); + for (final ItemStack stack : notBought { + if (stack.getItemMeta() != null) { //This was already validated but IDE still freaks out + names.add(stack.getItemMeta().getDisplayName()); + } + } + ess.showError(user.getSource(), new TranslatableException("cannotBuyTheseNamedItems", String.join(ChatColor.RESET + ", ", names)), commandLabel); + } + if (count != 1) { + final AdventureUtil.ParsedPlaceholder totalWorthStr = AdventureUtil.parsed(NumberUtil.displayCurrency(totalWorth, ess)); + if (args[0].equalsIgnoreCase("blocks")) { + user.sendTl("totalWorthBlocks", totalWorthStr, totalWorthStr); + } else { + user.sendTl("totalWorthAll", totalWorthStr, totalWorthStr); + } + } + } + + private BigDecimal buyItem(final User user, final ItemStack is, final String[] args, final boolean isBulkBuy) throws Exception { + final int amount = ess.getWorth().getAmount(ess, user, is, args, isBulkBuy); + final BigDecimal originalWorth = ess.getWorth().getPrice(ess, is); + final BigDecimal worth = originalWorth == null ? null : originalWorth.multiply(ess.getSettings().getMultiplier(user)); + + if (worth == null) { + throw new TranslatableException("itemCannotBeBought"); + } + + if (amount <= 0) { + if (!isBulkSell) { + user.sendTl("itemBought", AdventureUtil.parsed(NumberUtil.displayCurrency(BigDecimal.ZERO, ess)), BigDecimal.ZERO, is.getType().toString().toLowerCase(Locale.ENGLISH), NumberUtil.displayCurrency(worth, ess)); + } + return BigDecimal.ZERO; + } + + final BigDecimal result = worth.multiply(BigDecimal.valueOf(amount)); + + //TODO: Prices for Enchantments + final ItemStack ris = is.clone(); + ris.setAmount(amount); + // This statement is for checking if more items that is in inventory is trying to be sold. Should never happen. + // Needs to be rewritten into a check about if more gold is consumed. + if (!Inventories.containsAtLeast(user.getBase(), ris, amount)) { + // This should never happen. + throw new IllegalStateException("Trying to remove more items than are available."); + } + Inventories.removeItemAmount(user.getBase(), ris, ris.getAmount()); + user.getBase().updateInventory(); + Trade.log("Command", "Buy", "Item", user.getName(), new Trade(ris, ess), user.getName(), new Trade(result, ess), user.getLocation(), user.getMoney(), ess); + // Needs to be changed to a method for taking money + user.takeMoney(result, null, UserBalanceUpdateEvent.Cause.COMMAND_BUY); + final String typeName = is.getType().toString().toLowerCase(Locale.ENGLISH); + final AdventureUtil.ParsedPlaceholder worthDisplay = AdventureUtil.parsed(NumberUtil.displayCurrency(worth, ess)); + user.sendTl("itemBought", AdventureUtil.parsed(NumberUtil.displayCurrency(result, ess)), amount, typeName, worthDisplay); + ess.getLogger().log(Level.INFO, ess.getAdventureFacet().miniToLegacy(tlLiteral("itemBoughtConsole", user.getName(), typeName, ess.getAdventureFacet().miniToLegacy(NumberUtil.displayCurrency(result, ess)), amount, ess.getAdventureFacet().miniToLegacy(worthDisplay.toString()), user.getDisplayName()))); + return result; + } + + @Override + protected List getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) { + if (args.length == 1) { + return getMatchingItems(args[0]); + } else if (args.length == 2) { + return Lists.newArrayList("1", "64"); + } else { + return Collections.emptyList(); + } + } +}