Files
CraftBank/src/main/java/com/craftbank/hooks/XConomyExpansion.java
T
2026-07-04 12:20:18 +08:00

193 lines
5.9 KiB
Java

package com.craftbank.hooks;
import com.craftbank.CraftBank;
import com.craftbank.model.PlayerAccount;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* XConomy PlaceholderAPI 兼容层, 让原有 %xconomy_*% 变量无需替换即可使用。
*/
public final class XConomyExpansion extends PlaceholderExpansion {
private static final int RANKING_SIZE = 100;
private final CraftBank plugin;
private final DecimalFormat numberFormat = new DecimalFormat("#,##0.00");
private final List<Map.Entry<String, Double>> top = new CopyOnWriteArrayList<>();
private volatile double sumBalance;
public XConomyExpansion(CraftBank plugin) {
this.plugin = plugin;
}
@Override
public @NotNull String getIdentifier() {
return "xconomy";
}
@Override
public @NotNull String getAuthor() {
return "CraftBank";
}
@Override
public @NotNull String getVersion() {
return plugin.getDescription().getVersion();
}
@Override
public boolean persist() {
return true;
}
@Override
public String onRequest(OfflinePlayer player, @NotNull String identifier) {
String id = identifier.toLowerCase();
if (id.equals("balance") || id.equals("balance_value") || id.equals("balance_formatted")) {
double cash = getCash(player);
return switch (id) {
case "balance_value" -> decimal(cash);
case "balance_formatted" -> formatCompact(cash);
default -> formatDisplay(cash);
};
}
if (id.startsWith("top_player_")) {
Integer index = parseIndex(id, "top_player_");
if (index == null) {
return "[XConomy]Invalid index";
}
return topName(index);
}
if (id.equals("top_rank") || id.startsWith("top_rank_")) {
String name = id.equals("top_rank") ? (player == null ? null : player.getName())
: identifier.substring("top_rank_".length());
return rankOf(name);
}
if (id.startsWith("top_balance_formatted_")) {
Integer index = parseIndex(id, "top_balance_formatted_");
return index == null ? "[XConomy]Invalid index" : topBalance(index, true, false);
}
if (id.startsWith("top_balance_value_")) {
Integer index = parseIndex(id, "top_balance_value_");
return index == null ? "[XConomy]Invalid index" : topBalance(index, false, true);
}
if (id.startsWith("top_balance_")) {
Integer index = parseIndex(id, "top_balance_");
return index == null ? "[XConomy]Invalid index" : topBalance(index, false, false);
}
if (id.contains("top_hidden")) {
return "0";
}
if (id.contains("paypermission")) {
if (id.contains("_global")) {
return "1";
}
return player == null ? "Error" : "DEFAULT";
}
if (id.equals("paytoggle")) {
return player == null ? "Error" : "1";
}
if (id.contains("sum_balance")) {
return id.contains("sum_balance_value") ? decimal(sumBalance) : formatDisplay(sumBalance);
}
return null;
}
public void refreshCache() {
top.clear();
top.addAll(plugin.getDatabaseManager().getTopCash(RANKING_SIZE));
sumBalance = plugin.getDatabaseManager().getTotalCash();
}
private double getCash(OfflinePlayer player) {
if (player == null) {
return 0.0;
}
PlayerAccount account = plugin.getEconomyManager().getCached(player.getUniqueId());
return account == null ? 0.0 : account.getCash();
}
private String topName(int oneBasedIndex) {
if (oneBasedIndex > top.size()) {
return "No data";
}
return top.get(oneBasedIndex - 1).getKey();
}
private String topBalance(int oneBasedIndex, boolean compact, boolean raw) {
if (oneBasedIndex > top.size()) {
return "No data";
}
double balance = top.get(oneBasedIndex - 1).getValue();
if (raw) {
return decimal(balance);
}
return compact ? formatCompact(balance) : formatDisplay(balance);
}
private String rankOf(String name) {
if (name == null) {
return "No data";
}
for (int i = 0; i < top.size(); i++) {
if (name.equalsIgnoreCase(top.get(i).getKey())) {
return Integer.toString(i + 1);
}
}
return "No data";
}
private Integer parseIndex(String id, String prefix) {
String value = id.substring(prefix.length());
if (!value.matches("\\d+") || value.matches("0+")) {
return null;
}
return Integer.parseInt(value);
}
private String formatDisplay(double amount) {
return ChatColor.translateAlternateColorCodes('&', numberFormat.format(amount) + " "
+ (round(amount).compareTo(BigDecimal.ONE) == 0 ? "dollar" : "dollars"));
}
private String formatCompact(double amount) {
double abs = Math.abs(amount);
if (abs >= 1_000_000.0) {
return numberFormat.format(amount / 1_000_000.0) + "m dollars";
}
if (abs >= 1_000.0) {
return numberFormat.format(amount / 1_000.0) + "k dollars";
}
return formatDisplay(amount);
}
private String decimal(double amount) {
return round(amount).toString();
}
private BigDecimal round(double amount) {
return BigDecimal.valueOf(amount).setScale(2, RoundingMode.DOWN);
}
}