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).

MinborAIminborai 4 0 0 1
Source code (ZIP)
Tüm hakları saklıdırUse on serverModifyCommercial· Attribution
src/main/java/com/minborai/gunlukodul/GunlukOdul.java
1package com.minborai.gunlukodul;
2
3import 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;
24
25import java.time.LocalDate;
26import java.time.ZoneId;
27import java.util.ArrayList;
28import java.util.List;
29
30public final class GunlukOdul extends JavaPlugin implements Listener {
31
32 private static final MiniMessage MM = MiniMessage.miniMessage();
33 private static final int DAYS = 7;
34 private static final int FIRST_SLOT = 10;
35
36 private NamespacedKey lastKey;
37 private NamespacedKey streakKey;
38
39 @Override
40 public void onEnable() {
41 saveDefaultConfig();
42 lastKey = new NamespacedKey(this, "last_claim_day");
43 streakKey = new NamespacedKey(this, "streak");
44 getServer().getPluginManager().registerEvents(this, this);
45 }
46
47 private long today() {
48 return LocalDate.now(ZoneId.of(getConfig().getString("timezone", "Europe/Istanbul"))).toEpochDay();
49 }
50
51 /** Bugün alınabilecek gün (1-7); bugün alındıysa -1 */
52 private int claimableDay(Player player) {
53 PersistentDataContainer pdc = player.getPersistentDataContainer();
54 long last = pdc.getOrDefault(lastKey, PersistentDataType.LONG, Long.MIN_VALUE);
55 int streak = pdc.getOrDefault(streakKey, PersistentDataType.INTEGER, 0);
56 long now = today();
57 if (last == now) return -1;
58 // Dün alındıysa seri devam eder, kaçırıldıysa 1. güne döner
59 return last == now - 1 ? streak % DAYS + 1 : 1;
60 }
61
62 private int claimedStreak(Player player) {
63 PersistentDataContainer pdc = player.getPersistentDataContainer();
64 long last = pdc.getOrDefault(lastKey, PersistentDataType.LONG, Long.MIN_VALUE);
65 int streak = pdc.getOrDefault(streakKey, PersistentDataType.INTEGER, 0);
66 return last == today() ? streak : (last == today() - 1 ? streak % DAYS : 0);
67 }
68
69 private Component mm(String raw) {
70 return MM.deserialize("<!italic>" + raw);
71 }
72
73 private void open(Player player) {
74 RewardMenu holder = new RewardMenu();
75 Inventory inv = Bukkit.createInventory(holder, 27, MM.deserialize(getConfig().getString("menu-title", "Günlük Ödül")));
76 holder.setInventory(inv);
77 ItemStack filler = item(Material.BLACK_STAINED_GLASS_PANE, " ", List.of());
78 for (int i = 0; i < inv.getSize(); i++) inv.setItem(i, filler);
79
80 int claimable = claimableDay(player);
81 int done = claimedStreak(player);
82 for (int day = 1; day <= DAYS; day++) {
83 ConfigurationSection sec = getConfig().getConfigurationSection("days." + day);
84 List<String> lore = new ArrayList<>();
85 if (sec != null) for (String line : sec.getStringList("lore")) lore.add(line);
86 Material icon;
87 String state;
88 if (day <= done) {
89 icon = Material.LIME_STAINED_GLASS_PANE;
90 state = getConfig().getString("labels.claimed", "<green>Alındı");
91 } else if (day == claimable) {
92 icon = Material.matchMaterial(sec != null ? sec.getString("icon", "CHEST") : "CHEST");
93 if (icon == null) icon = Material.CHEST;
94 state = getConfig().getString("labels.ready", "<yellow>Tıkla ve al!");
95 } else {
96 icon = Material.GRAY_STAINED_GLASS_PANE;
97 state = getConfig().getString("labels.locked", "<gray>Henüz değil");
98 }
99 lore.add("");
100 lore.add(state);
101 inv.setItem(FIRST_SLOT + day - 1, item(icon, getConfig().getString("labels.day", "<gold>Gün <day>").replace("<day>", String.valueOf(day)), lore));
102 }
103 player.openInventory(inv);
104 }
105
106 private ItemStack item(Material material, String name, List<String> lore) {
107 ItemStack stack = new ItemStack(material);
108 ItemMeta meta = stack.getItemMeta();
109 meta.displayName(mm(name));
110 List<Component> lines = new ArrayList<>();
111 for (String l : lore) lines.add(mm(l));
112 meta.lore(lines);
113 stack.setItemMeta(meta);
114 return stack;
115 }
116
117 private void claim(Player player, int day) {
118 ConfigurationSection sec = getConfig().getConfigurationSection("days." + day);
119 if (sec != null) {
120 for (String entry : sec.getStringList("items")) {
121 String[] parts = entry.split(":");
122 Material mat = Material.matchMaterial(parts[0]);
123 if (mat == null) continue;
124 int amount = 1;
125 try {
126 if (parts.length > 1) amount = Math.max(1, Math.min(6400, Integer.parseInt(parts[1].trim())));
127 } catch (NumberFormatException e) {
128 getLogger().warning("Geçersiz adet: " + entry);
129 }
130 player.getInventory().addItem(new ItemStack(mat, amount)).values()
131 .forEach(left -> player.getWorld().dropItemNaturally(player.getLocation(), left));
132 }
133 int xp = sec.getInt("xp", 0);
134 if (xp > 0) player.giveExp(xp);
135 for (String cmd : sec.getStringList("commands")) {
136 Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("%player%", player.getName()));
137 }
138 }
139 PersistentDataContainer pdc = player.getPersistentDataContainer();
140 pdc.set(lastKey, PersistentDataType.LONG, today());
141 pdc.set(streakKey, PersistentDataType.INTEGER, day);
142 player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1.4f);
143 player.sendMessage(MM.deserialize(getConfig().getString("messages.claimed", "<green>Gün <day> ödülünü aldın!"), Placeholder.unparsed("day", String.valueOf(day))));
144 }
145
146 @EventHandler
147 public void onClick(InventoryClickEvent event) {
148 if (!(event.getInventory().getHolder() instanceof RewardMenu)) return;
149 event.setCancelled(true);
150 if (!(event.getWhoClicked() instanceof Player player)) return;
151 if (event.getClickedInventory() != event.getInventory()) return;
152 int day = event.getSlot() - FIRST_SLOT + 1;
153 if (day < 1 || day > DAYS) return;
154 int claimable = claimableDay(player);
155 if (day != claimable) {
156 player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1f, 0.6f);
157 return;
158 }
159 player.closeInventory();
160 claim(player, day);
161 }
162
163 @EventHandler
164 public void onDrag(InventoryDragEvent event) {
165 if (event.getInventory().getHolder() instanceof RewardMenu) event.setCancelled(true);
166 }
167
168 @Override
169 public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
170 if (!(sender instanceof Player player)) {
171 sender.sendMessage("Bu komut yalnızca oyuncular içindir.");
172 return true;
173 }
174 open(player);
175 return true;
176 }
177}
178