Paper1.21.11Official#ödül#menü#gui#etkileşim
Günlük Ödül
/daily menüsü: 7 günlük seri, kaçırınca sıfırlanır; eşya, XP ve konsol komutu ödülleri config'den. Veri oyuncunun kendisinde (PDC).
Tüm hakları saklıdırUse on serverModifyCommercial· Attribution
src/main/java/com/minborai/gunlukodul/GunlukOdul.java
1package com.minborai.gunlukodul;23import net.kyori.adventure.text.Component;4import net.kyori.adventure.text.minimessage.MiniMessage;5import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;6import org.bukkit.Bukkit;7import org.bukkit.Material;8import org.bukkit.NamespacedKey;9import org.bukkit.Sound;10import org.bukkit.command.Command;11import org.bukkit.command.CommandSender;12import org.bukkit.configuration.ConfigurationSection;13import org.bukkit.entity.Player;14import org.bukkit.event.EventHandler;15import org.bukkit.event.Listener;16import org.bukkit.event.inventory.InventoryClickEvent;17import org.bukkit.event.inventory.InventoryDragEvent;18import org.bukkit.inventory.Inventory;19import org.bukkit.inventory.ItemStack;20import org.bukkit.inventory.meta.ItemMeta;21import org.bukkit.persistence.PersistentDataContainer;22import org.bukkit.persistence.PersistentDataType;23import org.bukkit.plugin.java.JavaPlugin;2425import java.time.LocalDate;26import java.time.ZoneId;27import java.util.ArrayList;28import java.util.List;2930public final class GunlukOdul extends JavaPlugin implements Listener {3132private static final MiniMessage MM = MiniMessage.miniMessage();33private static final int DAYS = 7;34private static final int FIRST_SLOT = 10;3536private NamespacedKey lastKey;37private NamespacedKey streakKey;3839@Override40public void onEnable() {41saveDefaultConfig();42lastKey = new NamespacedKey(this, "last_claim_day");43streakKey = new NamespacedKey(this, "streak");44getServer().getPluginManager().registerEvents(this, this);45}4647private long today() {48return LocalDate.now(ZoneId.of(getConfig().getString("timezone", "Europe/Istanbul"))).toEpochDay();49}5051/** Bugün alınabilecek gün (1-7); bugün alındıysa -1 */52private int claimableDay(Player player) {53PersistentDataContainer pdc = player.getPersistentDataContainer();54long last = pdc.getOrDefault(lastKey, PersistentDataType.LONG, Long.MIN_VALUE);55int streak = pdc.getOrDefault(streakKey, PersistentDataType.INTEGER, 0);56long now = today();57if (last == now) return -1;58// Dün alındıysa seri devam eder, kaçırıldıysa 1. güne döner59return last == now - 1 ? streak % DAYS + 1 : 1;60}6162private int claimedStreak(Player player) {63PersistentDataContainer pdc = player.getPersistentDataContainer();64long last = pdc.getOrDefault(lastKey, PersistentDataType.LONG, Long.MIN_VALUE);65int streak = pdc.getOrDefault(streakKey, PersistentDataType.INTEGER, 0);66return last == today() ? streak : (last == today() - 1 ? streak % DAYS : 0);67}6869private Component mm(String raw) {70return MM.deserialize("<!italic>" + raw);71}7273private void open(Player player) {74RewardMenu holder = new RewardMenu();75Inventory inv = Bukkit.createInventory(holder, 27, MM.deserialize(getConfig().getString("menu-title", "Günlük Ödül")));76holder.setInventory(inv);77ItemStack filler = item(Material.BLACK_STAINED_GLASS_PANE, " ", List.of());78for (int i = 0; i < inv.getSize(); i++) inv.setItem(i, filler);7980int claimable = claimableDay(player);81int done = claimedStreak(player);82for (int day = 1; day <= DAYS; day++) {83ConfigurationSection sec = getConfig().getConfigurationSection("days." + day);84List<String> lore = new ArrayList<>();85if (sec != null) for (String line : sec.getStringList("lore")) lore.add(line);86Material icon;87String state;88if (day <= done) {89icon = Material.LIME_STAINED_GLASS_PANE;90state = getConfig().getString("labels.claimed", "<green>Alındı");91} else if (day == claimable) {92icon = Material.matchMaterial(sec != null ? sec.getString("icon", "CHEST") : "CHEST");93if (icon == null) icon = Material.CHEST;94state = getConfig().getString("labels.ready", "<yellow>Tıkla ve al!");95} else {96icon = Material.GRAY_STAINED_GLASS_PANE;97state = getConfig().getString("labels.locked", "<gray>Henüz değil");98}99lore.add("");100lore.add(state);101inv.setItem(FIRST_SLOT + day - 1, item(icon, getConfig().getString("labels.day", "<gold>Gün <day>").replace("<day>", String.valueOf(day)), lore));102}103player.openInventory(inv);104}105106private ItemStack item(Material material, String name, List<String> lore) {107ItemStack stack = new ItemStack(material);108ItemMeta meta = stack.getItemMeta();109meta.displayName(mm(name));110List<Component> lines = new ArrayList<>();111for (String l : lore) lines.add(mm(l));112meta.lore(lines);113stack.setItemMeta(meta);114return stack;115}116117private void claim(Player player, int day) {118ConfigurationSection sec = getConfig().getConfigurationSection("days." + day);119if (sec != null) {120for (String entry : sec.getStringList("items")) {121String[] parts = entry.split(":");122Material mat = Material.matchMaterial(parts[0]);123if (mat == null) continue;124int amount = 1;125try {126if (parts.length > 1) amount = Math.max(1, Math.min(6400, Integer.parseInt(parts[1].trim())));127} catch (NumberFormatException e) {128getLogger().warning("Geçersiz adet: " + entry);129}130player.getInventory().addItem(new ItemStack(mat, amount)).values()131.forEach(left -> player.getWorld().dropItemNaturally(player.getLocation(), left));132}133int xp = sec.getInt("xp", 0);134if (xp > 0) player.giveExp(xp);135for (String cmd : sec.getStringList("commands")) {136Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", player.getName()));137}138}139PersistentDataContainer pdc = player.getPersistentDataContainer();140pdc.set(lastKey, PersistentDataType.LONG, today());141pdc.set(streakKey, PersistentDataType.INTEGER, day);142player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1.4f);143player.sendMessage(MM.deserialize(getConfig().getString("messages.claimed", "<green>Gün <day> ödülünü aldın!"), Placeholder.unparsed("day", String.valueOf(day))));144}145146@EventHandler147public void onClick(InventoryClickEvent event) {148if (!(event.getInventory().getHolder() instanceof RewardMenu)) return;149event.setCancelled(true);150if (!(event.getWhoClicked() instanceof Player player)) return;151if (event.getClickedInventory() != event.getInventory()) return;152int day = event.getSlot() - FIRST_SLOT + 1;153if (day < 1 || day > DAYS) return;154int claimable = claimableDay(player);155if (day != claimable) {156player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1f, 0.6f);157return;158}159player.closeInventory();160claim(player, day);161}162163@EventHandler164public void onDrag(InventoryDragEvent event) {165if (event.getInventory().getHolder() instanceof RewardMenu) event.setCancelled(true);166}167168@Override169public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {170if (!(sender instanceof Player player)) {171sender.sendMessage("Bu komut yalnızca oyuncular içindir.");172return true;173}174open(player);175return true;176}177}178