278 lines
12 KiB
Java
278 lines
12 KiB
Java
package com.librewiki.coalgov.command;
|
|
|
|
import com.librewiki.coalgov.CoalGovPlugin;
|
|
import com.librewiki.coalgov.model.Fine;
|
|
import com.librewiki.coalgov.util.CoalMoney;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.command.Command;
|
|
import org.bukkit.command.CommandExecutor;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import java.sql.SQLException;
|
|
import java.util.List;
|
|
|
|
public final class CoalCommand implements CommandExecutor {
|
|
private final CoalGovPlugin plugin;
|
|
|
|
public CoalCommand(CoalGovPlugin plugin) {
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
@Override
|
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
|
if (!(sender instanceof Player player)) {
|
|
sender.sendMessage("Players only.");
|
|
return true;
|
|
}
|
|
if (args.length == 0) {
|
|
player.sendMessage(plugin.messages().text("&eUsage: /coal <balance|deposit|withdraw|pay|fines|networth|lottery>"));
|
|
return true;
|
|
}
|
|
try {
|
|
plugin.economyService().ensurePlayer(player);
|
|
switch (args[0].toLowerCase()) {
|
|
case "balance" -> balance(player);
|
|
case "deposit" -> deposit(player);
|
|
case "withdraw" -> withdraw(player, args);
|
|
case "pay" -> pay(player, args);
|
|
case "fines" -> fines(player, args);
|
|
case "networth" -> networth(player);
|
|
case "lottery" -> lottery(player, args);
|
|
default -> player.sendMessage(plugin.messages().text("&eUsage: /coal <balance|deposit|withdraw|pay|fines|networth|lottery>"));
|
|
}
|
|
} catch (SQLException exception) {
|
|
plugin.getLogger().warning("Coal command failed: " + exception.getMessage());
|
|
player.sendMessage(plugin.messages().text("&cCoal ledger unavailable."));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void balance(Player player) throws SQLException {
|
|
player.sendMessage(plugin.messages().text("&eBalance: &f" + CoalMoney.format(plugin.economyService().balance(player.getUniqueId()))));
|
|
}
|
|
|
|
private void networth(Player player) throws SQLException {
|
|
long balance = plugin.economyService().balance(player.getUniqueId());
|
|
long inventory = 0L;
|
|
for (ItemStack item : player.getInventory().getStorageContents()) {
|
|
if (item == null || item.getType().isAir()) {
|
|
continue;
|
|
}
|
|
Double price = plugin.marketService().basePrices().get(item.getType());
|
|
if (price != null) {
|
|
inventory += CoalMoney.fromCoal(price * item.getAmount());
|
|
}
|
|
}
|
|
long claims = plugin.claimService().list(player.getUniqueId()).stream()
|
|
.mapToLong(plugin.claimService()::claimPurchaseCost)
|
|
.filter(value -> value > 0L)
|
|
.sum();
|
|
long total = balance + inventory + claims;
|
|
player.sendMessage(plugin.messages().text("&eNet worth: &f" + CoalMoney.format(total)));
|
|
player.sendMessage(plugin.messages().text("&7Balance: &f" + CoalMoney.format(balance)
|
|
+ " &7Inventory: &f" + CoalMoney.format(inventory)
|
|
+ " &7Claims: &f" + CoalMoney.format(claims)));
|
|
}
|
|
|
|
private void deposit(Player player) throws SQLException {
|
|
boolean coalEnabled = plugin.getConfig().getBoolean("economy.deposit_coal", true);
|
|
boolean blocksEnabled = plugin.getConfig().getBoolean("economy.deposit_coal_blocks", true);
|
|
long credit = 0;
|
|
for (ItemStack item : player.getInventory().getContents()) {
|
|
if (item == null) {
|
|
continue;
|
|
}
|
|
if (coalEnabled && item.getType() == Material.COAL) {
|
|
credit += item.getAmount() * CoalMoney.CENTS_PER_COAL;
|
|
item.setAmount(0);
|
|
} else if (blocksEnabled && item.getType() == Material.COAL_BLOCK) {
|
|
credit += item.getAmount() * 9L * CoalMoney.CENTS_PER_COAL;
|
|
item.setAmount(0);
|
|
}
|
|
}
|
|
if (credit <= 0) {
|
|
player.sendMessage(plugin.messages().text("&cNo depositable coal found."));
|
|
return;
|
|
}
|
|
plugin.economyService().deposit(player.getUniqueId(), credit);
|
|
player.sendMessage(plugin.messages().text("&aDeposited &f" + CoalMoney.format(credit) + "&a."));
|
|
}
|
|
|
|
private void withdraw(Player player, String[] args) throws SQLException {
|
|
if (args.length != 2) {
|
|
player.sendMessage(plugin.messages().text("&eUsage: /coal withdraw <amount>"));
|
|
return;
|
|
}
|
|
long amount = CoalMoney.parsePositive(args[1]);
|
|
if (amount <= 0) {
|
|
player.sendMessage(plugin.messages().text("&cAmount must be greater than zero."));
|
|
return;
|
|
}
|
|
if (amount % CoalMoney.CENTS_PER_COAL != 0L) {
|
|
player.sendMessage(plugin.messages().text("&cWithdrawals must be whole coal because they create coal items."));
|
|
return;
|
|
}
|
|
long coalItems = amount / CoalMoney.CENTS_PER_COAL;
|
|
if (plugin.economyService().balance(player.getUniqueId()) < amount) {
|
|
player.sendMessage(plugin.messages().text("&cBalance too low."));
|
|
return;
|
|
}
|
|
if (!canFitCoal(player, coalItems)) {
|
|
player.sendMessage(plugin.messages().text("&cYou need more inventory space."));
|
|
return;
|
|
}
|
|
if (!plugin.economyService().withdraw(player.getUniqueId(), amount)) {
|
|
player.sendMessage(plugin.messages().text("&cBalance too low."));
|
|
return;
|
|
}
|
|
long remaining = coalItems;
|
|
while (remaining > 0) {
|
|
int stack = (int) Math.min(Material.COAL.getMaxStackSize(), remaining);
|
|
player.getInventory().addItem(new ItemStack(Material.COAL, stack));
|
|
remaining -= stack;
|
|
}
|
|
player.sendMessage(plugin.messages().text("&aWithdrew &f" + CoalMoney.format(amount) + "&a."));
|
|
}
|
|
|
|
private void pay(Player player, String[] args) throws SQLException {
|
|
if (args.length != 3) {
|
|
player.sendMessage(plugin.messages().text("&eUsage: /coal pay <player> <amount>"));
|
|
return;
|
|
}
|
|
Player target = Bukkit.getPlayerExact(args[1]);
|
|
if (target == null) {
|
|
player.sendMessage(plugin.messages().text("&cThat player must be online."));
|
|
return;
|
|
}
|
|
long amount = CoalMoney.parsePositive(args[2]);
|
|
if (amount <= 0) {
|
|
player.sendMessage(plugin.messages().text("&cAmount must be greater than zero."));
|
|
return;
|
|
}
|
|
plugin.economyService().ensurePlayer(target);
|
|
if (!plugin.economyService().pay(player.getUniqueId(), target.getUniqueId(), amount)) {
|
|
player.sendMessage(plugin.messages().text("&cPayment failed. Check your balance."));
|
|
return;
|
|
}
|
|
player.sendMessage(plugin.messages().text("&aPaid &f" + CoalMoney.format(amount) + " &ato " + target.getName() + "."));
|
|
target.sendMessage(plugin.messages().text("&aReceived &f" + CoalMoney.format(amount) + " &afrom " + player.getName() + "."));
|
|
}
|
|
|
|
private void fines(Player player, String[] args) throws SQLException {
|
|
if (args.length == 1 || (args.length == 2 && args[1].equalsIgnoreCase("list"))) {
|
|
List<Fine> fines = plugin.governmentService().unpaidFines(player.getUniqueId());
|
|
if (fines.isEmpty()) {
|
|
player.sendMessage(plugin.messages().text("&aYou have no unpaid fines."));
|
|
return;
|
|
}
|
|
long total = fines.stream().mapToLong(Fine::amount).sum();
|
|
player.sendMessage(plugin.messages().text("&eUnpaid fines: &f" + CoalMoney.format(total) + " &etotal"));
|
|
for (Fine fine : fines) {
|
|
player.sendMessage(plugin.messages().raw("&7#" + fine.id() + " &f" + CoalMoney.format(fine.amount()) + " &7" + fine.reason()));
|
|
}
|
|
player.sendMessage(plugin.messages().text("&7Use &f/coal fines pay <id|all>&7."));
|
|
return;
|
|
}
|
|
if (args.length == 3 && args[1].equalsIgnoreCase("pay")) {
|
|
if (args[2].equalsIgnoreCase("all")) {
|
|
var result = plugin.governmentService().payAllFines(player.getUniqueId());
|
|
if (!result.success()) {
|
|
player.sendMessage(plugin.messages().text("&c" + result.message()));
|
|
return;
|
|
}
|
|
player.sendMessage(plugin.messages().text("&aPaid &f" + CoalMoney.format(result.amount()) + " &ain fines."));
|
|
return;
|
|
}
|
|
long id = parsePositive(args[2]);
|
|
if (id <= 0L) {
|
|
player.sendMessage(plugin.messages().text("&cInvalid fine id."));
|
|
return;
|
|
}
|
|
var result = plugin.governmentService().payFine(player.getUniqueId(), id);
|
|
if (!result.success()) {
|
|
player.sendMessage(plugin.messages().text("&c" + result.message()));
|
|
return;
|
|
}
|
|
player.sendMessage(plugin.messages().text("&aPaid fine #" + id + " for &f" + CoalMoney.format(result.amount()) + "&a."));
|
|
return;
|
|
}
|
|
player.sendMessage(plugin.messages().text("&eUsage: /coal fines [list|pay <id|all>]"));
|
|
}
|
|
|
|
private void lottery(Player player, String[] args) throws SQLException {
|
|
if (args.length == 1 || (args.length == 2 && args[1].equalsIgnoreCase("status"))) {
|
|
var status = plugin.lotteryService().status();
|
|
player.sendMessage(plugin.messages().text("&eLottery round #" + status.round()
|
|
+ ": &f" + status.tickets() + " &etickets from &f" + status.players()
|
|
+ " &eplayers. Pot: &f" + CoalMoney.format(status.pot())));
|
|
return;
|
|
}
|
|
if (args.length == 2 && args[1].equalsIgnoreCase("buy")) {
|
|
buyLottery(player, 1);
|
|
return;
|
|
}
|
|
if (args.length == 3 && args[1].equalsIgnoreCase("buy")) {
|
|
int tickets = (int) parsePositive(args[2]);
|
|
buyLottery(player, tickets);
|
|
return;
|
|
}
|
|
if (args.length == 2 && args[1].equalsIgnoreCase("draw")) {
|
|
if (!player.hasPermission("coalgov.admin")) {
|
|
player.sendMessage(plugin.messages().text("&cOnly CoalGov admins can draw the lottery."));
|
|
return;
|
|
}
|
|
var result = plugin.lotteryService().draw();
|
|
if (!result.success()) {
|
|
player.sendMessage(plugin.messages().text("&c" + result.message()));
|
|
return;
|
|
}
|
|
Bukkit.broadcastMessage(plugin.messages().text("&6Lottery round #" + result.round()
|
|
+ " won by &f" + result.winnerName()
|
|
+ " &6for &f" + CoalMoney.format(result.pot())
|
|
+ " &6from &f" + result.tickets() + " &6tickets."));
|
|
return;
|
|
}
|
|
player.sendMessage(plugin.messages().text("&eUsage: /coal lottery <status|buy [tickets]|draw>"));
|
|
}
|
|
|
|
private void buyLottery(Player player, int tickets) throws SQLException {
|
|
var result = plugin.lotteryService().buy(player, tickets);
|
|
if (!result.success()) {
|
|
player.sendMessage(plugin.messages().text("&c" + result.message()));
|
|
return;
|
|
}
|
|
player.sendMessage(plugin.messages().text("&aBought &f" + result.tickets()
|
|
+ " &alottery ticket(s) for &f" + CoalMoney.format(result.cost())
|
|
+ " &ain round #" + result.round() + "."));
|
|
}
|
|
|
|
private boolean canFitCoal(Player player, long amount) {
|
|
if (amount > Integer.MAX_VALUE) {
|
|
return false;
|
|
}
|
|
long capacity = 0;
|
|
for (ItemStack item : player.getInventory().getStorageContents()) {
|
|
if (item == null || item.getType().isAir()) {
|
|
capacity += Material.COAL.getMaxStackSize();
|
|
} else if (item.getType() == Material.COAL) {
|
|
capacity += Material.COAL.getMaxStackSize() - item.getAmount();
|
|
}
|
|
if (capacity >= amount) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private long parsePositive(String raw) {
|
|
try {
|
|
return Long.parseLong(raw);
|
|
} catch (NumberFormatException exception) {
|
|
return -1L;
|
|
}
|
|
}
|
|
}
|