Bumped version to 1.2.

Added `/balance` and `/pay` commands and a config option to enable them.

Added safeIs method to Config to match values without case sensitivity.

Added getCurrencyText method to Config to generate a formatted string from a currency amount.

Value 'format' from config file now supports amount-name replacement.

Main now stores the instance of VaultLayer for further use.
This commit is contained in:
天クマ 2026-01-02 20:55:50 -03:00
commit 717f1b9a1a
8 changed files with 266 additions and 98 deletions

View file

@ -3,6 +3,7 @@ package io.github.adrianvic.itemeconomy;
import org.bukkit.Material;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class Config {
@ -12,10 +13,11 @@ public class Config {
public static void loadConfig(UnrealConfig conf) {
uConf = conf;
entries.put("item", "diamond");
entries.put("format", "{}$");
entries.put("format", "{} $");
entries.put("plural", "diamonds");
entries.put("singular", "diamond");
entries.put("ender_chest", "balance");
entries.put("commands", "true");
Map<String, String> missingValues = new HashMap<>();
@ -44,6 +46,16 @@ public class Config {
return entries.get(entry).equals(value);
}
public static boolean safeIs(String entry, String value) {
return is(entry.toLowerCase(Locale.ROOT), value.toLowerCase(Locale.ROOT));
}
public static String getCurrencyText(int amount) {
return entries.get("format")
.replace("{}", String.valueOf(amount))
.replace("$", (amount != 1) ? entries.get("plural") : entries.get("singular"));
}
public static UnrealConfig getuConf() {
return uConf;
}

View file

@ -2,6 +2,8 @@ package io.github.adrianvic.itemeconomy;
import java.util.*;
import io.github.adrianvic.itemeconomy.commands.Balance;
import io.github.adrianvic.itemeconomy.commands.Pay;
import io.github.adrianvic.itemeconomy.commands.Reload;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
@ -13,111 +15,117 @@ import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin {
private static Main instance;
private static Main instance;
private static Economy economy;
public void onEnable() {
instance = this;
Config.loadConfig(new UnrealConfig(this, this.getDataFolder(), "config.yml"));
Bukkit.getServicesManager().register(Economy.class, new VaultLayer(), this, ServicePriority.High);
getCommand("itecoreload").setExecutor(new Reload());
}
public void onEnable() {
instance = this;
Config.loadConfig(new UnrealConfig(this, this.getDataFolder(), "config.yml"));
economy = new VaultLayer();
Bukkit.getServicesManager().register(Economy.class, economy, this, ServicePriority.High);
public static JavaPlugin getInstance() {
return instance;
}
getCommand("itecoreload").setExecutor(new Reload());
if (Config.safeIs("commands", "true")) {
getCommand("balance").setExecutor(new Balance());
getCommand("pay").setExecutor(new Pay());
}
}
public void onDisable() {
super.onDisable();
}
public void onDisable() {
super.onDisable();
}
public enum InventoryID {
INVENTORY,
ENDER_CHEST
}
public static JavaPlugin getInstance() {
return instance;
}
public static Inventory getInventory(Player player, InventoryID inventory) {
Inventory inv = player.getInventory();
public static Economy getEconomy() {
return economy;
}
switch (inventory) {
case INVENTORY -> {
inv = player.getInventory();
}
case ENDER_CHEST -> {
if (Config.is("ender_chest", "balance")) {
inv = player.getEnderChest();
} else {
inv = getInstance().getServer().createInventory(null, 9);
public enum InventoryID {
INVENTORY,
ENDER_CHEST
}
public static Inventory getInventory(Player player, InventoryID inventory) {
Inventory inv = player.getInventory();
switch (inventory) {
case INVENTORY -> inv = player.getInventory();
case ENDER_CHEST -> {
if (Config.is("ender_chest", "balance")) {
inv = player.getEnderChest();
} else {
inv = getInstance().getServer().createInventory(null, 9);
}
}
}
}
}
return inv;
}
return inv;
}
public static List<ItemStack> getInventoryList(Player player, InventoryID inventory) {
Inventory inv = getInventory(player, inventory);
return Arrays.stream(inv.getContents()).map((o) -> o == null ? new ItemStack(Material.AIR) : o).toList();
}
public static List<ItemStack> getInventoryList(Player player, InventoryID inventory) {
Inventory inv = getInventory(player, inventory);
return Arrays.stream(inv.getContents()).map((o) -> o == null ? new ItemStack(Material.AIR) : o).toList();
}
public static List<ItemStack> getInventoryList(Player player) {
return getInventoryList(player, InventoryID.INVENTORY);
}
public static List<ItemStack> getInventoryList(Player player) {
return getInventoryList(player, InventoryID.INVENTORY);
}
public static double getBalance(Player player, InventoryID inventory) {
return (double) getInventoryList(player, inventory).stream().filter(Objects::nonNull).filter((i) -> {
return i.getType().equals(Config.ecoItem());
}).mapToInt(ItemStack::getAmount).sum();
}
public static double getBalance(Player player, InventoryID inventory) {
return getInventoryList(player, inventory).stream().filter(Objects::nonNull).filter((i) -> i.getType().equals(Config.ecoItem())).mapToInt(ItemStack::getAmount).sum();
}
public static double getBalance(Player player) {
Double total = 0.0D;
public static double getBalance(Player player) {
double total = 0.0D;
for (InventoryID id : InventoryID.values()) {
total += getBalance(player, id);
}
for (InventoryID id : InventoryID.values()) {
total += getBalance(player, id);
}
return total;
}
return total;
}
public static double getBalance(String player) {
return getBalance(Bukkit.getPlayer(player));
}
public static double getBalance(String player) {
return getBalance(Bukkit.getPlayer(player));
}
public static boolean removeItems(Player player, Material type, int amount) {
int remaining = amount;
public static boolean removeItems(Player player, Material type, int amount) {
int remaining = amount;
remaining = removeFrom(player.getInventory(), type, remaining);
if (remaining > 0) {
remaining = removeFrom(player.getEnderChest(), type, remaining);
}
remaining = removeFrom(player.getInventory(), type, remaining);
if (remaining > 0) {
remaining = removeFrom(player.getEnderChest(), type, remaining);
}
return remaining == 0;
}
return remaining == 0;
}
private static int removeFrom(Inventory inv, Material type, int amount) {
if (amount <= 0) return 0;
private static int removeFrom(Inventory inv, Material type, int amount) {
if (amount <= 0) return 0;
for (ItemStack stack : inv.all(type).values()) {
int take = Math.min(stack.getAmount(), amount);
stack.setAmount(stack.getAmount() - take);
amount -= take;
if (amount == 0) break;
}
for (ItemStack stack : inv.all(type).values()) {
int take = Math.min(stack.getAmount(), amount);
stack.setAmount(stack.getAmount() - take);
amount -= take;
if (amount == 0) break;
}
return amount;
}
return amount;
}
public static void addItems(Player player, Material type, int amount) {
HashMap<Integer, ItemStack> invOverflow = getInventory(player, InventoryID.INVENTORY).addItem(new ItemStack(type, amount));
HashMap<Integer, ItemStack> echestOverflow = getInventory(player, InventoryID.ENDER_CHEST).addItem(new ItemStack(type, invOverflow.values()
.stream()
.mapToInt(ItemStack::getAmount)
.sum()));
public static void addItems(Player player, Material type, int amount) {
HashMap<Integer, ItemStack> invOverflow = getInventory(player, InventoryID.INVENTORY).addItem(new ItemStack(type, amount));
HashMap<Integer, ItemStack> echestOverflow = getInventory(player, InventoryID.ENDER_CHEST).addItem(new ItemStack(type, invOverflow.values()
.stream()
.mapToInt(ItemStack::getAmount)
.sum()));
for (ItemStack overflow : echestOverflow.values()){
player.getWorld().dropItemNaturally(player.getLocation(), overflow);
}
}
for (ItemStack overflow : echestOverflow.values()) {
player.getWorld().dropItemNaturally(player.getLocation(), overflow);
}
}
}

View file

@ -26,7 +26,7 @@ public class VaultLayer implements Economy {
}
public String format(double amount) {
return Config.get("format").replace("{}", String.valueOf(amount));
return Config.getCurrencyText((int) amount);
}
public String currencyNamePlural() {

View file

@ -0,0 +1,49 @@
package io.github.adrianvic.itemeconomy.commands;
import io.github.adrianvic.itemeconomy.Config;
import io.github.adrianvic.itemeconomy.Main;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.stream.Collectors;
public class Balance implements CommandExecutor, TabCompleter {
@Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) {
if ((commandSender.isOp() || commandSender.hasPermission("iteco.balance.others")) && strings.length > 0) {
double amount = Main.getEconomy().getBalance(strings[0]);
commandSender.sendMessage("%s has %s.".formatted(
strings[0],
Config.getCurrencyText((int) amount)
));
} else {
if (commandSender instanceof Player player) {
double amount = Main.getEconomy().getBalance(player);
commandSender.sendMessage("You have %s.".formatted(
Config.getCurrencyText((int) amount)
));
} else {
commandSender.sendMessage("One must be a player to have a balance.");
}
}
return true;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) {
if ((sender.isOp() || sender.hasPermission("iteco.balance.others")) && args.length == 1) {
return Bukkit.getOnlinePlayers()
.stream()
.map(Player::getName)
.collect(Collectors.toList());
}
return List.of();
}
}

View file

@ -0,0 +1,74 @@
package io.github.adrianvic.itemeconomy.commands;
import io.github.adrianvic.itemeconomy.Config;
import io.github.adrianvic.itemeconomy.Main;
import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.stream.Collectors;
public class Pay implements CommandExecutor, TabCompleter {
@Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) {
if (strings.length < 2) {
commandSender.sendMessage(command.getUsage());
return false;
}
int amount;
try {
amount = Integer.parseInt(strings[1]);
String amountString = Config.getCurrencyText(amount);
if (commandSender instanceof Player player && Main.getEconomy().has(player, amount)) {
if (Bukkit.getPlayer(strings[0]) instanceof Player target) {
EconomyResponse withdrawResponse = Main.getEconomy().withdrawPlayer(player.getName(), amount);
if (withdrawResponse.transactionSuccess()) {
EconomyResponse depositResponse = Main.getEconomy().depositPlayer(target.getName(), amount);
if (depositResponse.transactionSuccess()) {
commandSender.sendMessage("Transaction of %s to %s was successfully realized.".formatted(amountString, target.getName()));
target.sendMessage("You received %s from %s.".formatted(amountString, player.getName()));
} else {
commandSender.sendMessage("Could not realize transaction: %s".formatted(depositResponse.errorMessage));
Main.getEconomy().depositPlayer(player.getName(), amount);
}
} else {
commandSender.sendMessage("Could not realize transaction: %s".formatted(withdrawResponse.errorMessage));
}
} else {
commandSender.sendMessage("Could not find target player.");
}
} else {
commandSender.sendMessage("You don't have enough money.");
}
} catch (NumberFormatException nfe) {
commandSender.sendMessage("The amount you tried to pay is not valid.");
return true;
}
return true;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) {
if (sender instanceof Player player) {
if (args.length == 1) {
return Bukkit.getOnlinePlayers()
.stream()
.map(Player::getName)
.collect(Collectors.toList());
}
}
return List.of();
}
}