Paper1.21.11Resmi#ekonomi#para#komut
Mini Ekonomi
/bakiye, /pay, /baltop ve yönetici /eco (give/take/set): başlangıç parası, otomatik kayıt, sekme tamamlama. Bağımlılık gerektirmez.
Tüm hakları saklıdırSunucuda kullanDeğiştirTicari· Atıf gerekli
src/main/java/com/minborai/miniekonomi/MiniEkonomi.java
1package com.minborai.miniekonomi;23import net.kyori.adventure.text.Component;4import net.kyori.adventure.text.minimessage.MiniMessage;5import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;6import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;7import org.bukkit.Bukkit;8import org.bukkit.OfflinePlayer;9import org.bukkit.command.Command;10import org.bukkit.command.CommandSender;11import org.bukkit.configuration.file.YamlConfiguration;12import org.bukkit.entity.Player;13import org.bukkit.event.EventHandler;14import org.bukkit.event.Listener;15import org.bukkit.event.player.PlayerJoinEvent;16import org.bukkit.plugin.java.JavaPlugin;1718import java.io.File;19import java.io.IOException;20import java.math.BigDecimal;21import java.math.RoundingMode;22import java.text.DecimalFormat;23import java.text.DecimalFormatSymbols;24import java.util.ArrayList;25import java.util.Collections;26import java.util.List;27import java.util.Locale;28import java.util.Map;29import java.util.UUID;30import java.util.concurrent.ConcurrentHashMap;3132public final class MiniEkonomi extends JavaPlugin implements Listener {3334private static final MiniMessage MM = MiniMessage.miniMessage();35private static final BigDecimal MAX = new BigDecimal("1000000000000");3637private final Map<UUID, BigDecimal> balances = new ConcurrentHashMap<>();38private File file;39private boolean dirty = false;40private DecimalFormat format;4142@Override43public void onEnable() {44saveDefaultConfig();45format = new DecimalFormat("#,##0.##", DecimalFormatSymbols.getInstance(new Locale("tr", "TR")));46file = new File(getDataFolder(), "balances.yml");47YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);48for (String key : yml.getKeys(false)) {49try {50balances.put(UUID.fromString(key), new BigDecimal(yml.getString(key, "0")));51} catch (IllegalArgumentException ignored) {52// bozuk satır atlanır53}54}55getServer().getPluginManager().registerEvents(this, this);56// Değişiklik varsa 5 dakikada bir kaydet57getServer().getScheduler().runTaskTimer(this, () -> {58if (dirty) save();59}, 6000L, 6000L);60}6162@Override63public void onDisable() {64save();65}6667private void save() {68YamlConfiguration yml = new YamlConfiguration();69balances.forEach((id, value) -> yml.set(id.toString(), value.toPlainString()));70try {71yml.save(file);72dirty = false;73} catch (IOException e) {74getLogger().warning("balances.yml kaydedilemedi: " + e.getMessage());75}76}7778public BigDecimal balance(UUID id) {79return balances.getOrDefault(id, BigDecimal.ZERO);80}8182private void set(UUID id, BigDecimal value) {83balances.put(id, value.setScale(2, RoundingMode.HALF_UP));84dirty = true;85}8687private String money(BigDecimal v) {88return format.format(v) + getConfig().getString("currency-symbol", "₺");89}9091private Component text(String key, String... pairs) {92List<TagResolver> tags = new ArrayList<>();93for (int i = 0; i + 1 < pairs.length; i += 2) tags.add(Placeholder.unparsed(pairs[i], pairs[i + 1]));94return MM.deserialize(getConfig().getString("messages.prefix", "") + getConfig().getString("messages." + key, key), TagResolver.resolver(tags));95}9697/** "12,5" ya da "12.5" → pozitif tutar (2 hane); geçersizse null */98private BigDecimal parse(String raw) {99try {100BigDecimal v = new BigDecimal(raw.replace(',', '.')).setScale(2, RoundingMode.DOWN);101return v.signum() > 0 && v.compareTo(MAX) <= 0 ? v : null;102} catch (NumberFormatException e) {103return null;104}105}106107private OfflinePlayer find(String name) {108Player online = Bukkit.getPlayerExact(name);109return online != null ? online : Bukkit.getOfflinePlayerIfCached(name);110}111112@EventHandler113public void onJoin(PlayerJoinEvent event) {114UUID id = event.getPlayer().getUniqueId();115if (!balances.containsKey(id)) set(id, BigDecimal.valueOf(getConfig().getDouble("starting-balance", 100)));116}117118@Override119public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {120switch (command.getName()) {121case "bakiye" -> {122if (args.length > 0 && sender.hasPermission("economy.balance.others")) {123OfflinePlayer target = find(args[0]);124if (target == null) {125sender.sendMessage(text("unknown-player", "player", args[0]));126return true;127}128sender.sendMessage(text("balance-other", "player", String.valueOf(target.getName()), "amount", money(balance(target.getUniqueId()))));129} else if (sender instanceof Player player) {130sender.sendMessage(text("balance", "amount", money(balance(player.getUniqueId()))));131} else {132sender.sendMessage(text("players-only"));133}134}135case "pay" -> {136if (!(sender instanceof Player player)) {137sender.sendMessage(text("players-only"));138return true;139}140if (args.length < 2) return false;141OfflinePlayer target = find(args[0]);142BigDecimal amount = parse(args[1]);143if (target == null) {144sender.sendMessage(text("unknown-player", "player", args[0]));145return true;146}147if (target.getUniqueId().equals(player.getUniqueId())) {148sender.sendMessage(text("pay-self"));149return true;150}151if (amount == null) {152sender.sendMessage(text("invalid-amount"));153return true;154}155if (balance(player.getUniqueId()).compareTo(amount) < 0) {156sender.sendMessage(text("not-enough", "amount", money(balance(player.getUniqueId()))));157return true;158}159set(player.getUniqueId(), balance(player.getUniqueId()).subtract(amount));160set(target.getUniqueId(), balance(target.getUniqueId()).add(amount));161sender.sendMessage(text("paid", "player", String.valueOf(target.getName()), "amount", money(amount)));162if (target instanceof Player online) online.sendMessage(text("received", "player", player.getName(), "amount", money(amount)));163}164case "baltop" -> {165List<Map.Entry<UUID, BigDecimal>> top = new ArrayList<>(balances.entrySet());166top.sort(Map.Entry.<UUID, BigDecimal>comparingByValue().reversed());167sender.sendMessage(text("top-header"));168for (int i = 0; i < Math.min(10, top.size()); i++) {169String name = Bukkit.getOfflinePlayer(top.get(i).getKey()).getName();170sender.sendMessage(MM.deserialize(getConfig().getString("messages.top-line", "<gray><rank>. <white><player></white> <dark_gray>-</dark_gray> <green><amount>"),171Placeholder.unparsed("rank", String.valueOf(i + 1)),172Placeholder.unparsed("player", name == null ? "?" : name),173Placeholder.unparsed("amount", money(top.get(i).getValue()))));174}175}176case "eco" -> {177if (args.length < 3) return false;178OfflinePlayer target = find(args[1]);179BigDecimal amount = args[0].equalsIgnoreCase("set") ? parseNonNegative(args[2]) : parse(args[2]);180if (target == null) {181sender.sendMessage(text("unknown-player", "player", args[1]));182return true;183}184if (amount == null) {185sender.sendMessage(text("invalid-amount"));186return true;187}188UUID id = target.getUniqueId();189switch (args[0].toLowerCase(Locale.ROOT)) {190case "give" -> set(id, balance(id).add(amount).min(MAX));191case "take" -> set(id, balance(id).subtract(amount).max(BigDecimal.ZERO));192case "set" -> set(id, amount);193default -> {194return false;195}196}197sender.sendMessage(text("admin-done", "player", String.valueOf(target.getName()), "amount", money(balance(id))));198}199default -> {200return false;201}202}203return true;204}205206private BigDecimal parseNonNegative(String raw) {207if (raw.equals("0")) return BigDecimal.ZERO;208return parse(raw);209}210211@Override212public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {213List<String> out = new ArrayList<>();214String last = args.length == 0 ? "" : args[args.length - 1].toLowerCase(Locale.ROOT);215boolean playerArg = (command.getName().equals("pay") || command.getName().equals("bakiye")) && args.length == 1216|| command.getName().equals("eco") && args.length == 2;217if (command.getName().equals("eco") && args.length == 1) {218for (String s : List.of("give", "take", "set")) if (s.startsWith(last)) out.add(s);219} else if (playerArg) {220for (Player p : Bukkit.getOnlinePlayers()) if (p.getName().toLowerCase(Locale.ROOT).startsWith(last)) out.add(p.getName());221}222return out;223}224}225