139 lines
5.2 KiB
Java
139 lines
5.2 KiB
Java
package de.mviper.adventskalender;
|
|
|
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
import org.bukkit.entity.Player;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.util.HashSet;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
/**
|
|
* Platzhalter: %ak_claimed%, %ak_day%, %ak_has_claimed_today%, %ak_remaining%, %ak_is_global%, %ak_event%
|
|
* beziehen sich auf das laufende Event (sonst das erste aktivierte). Mit Event-Präfix, z.B.
|
|
* %ak_halloween_claimed%, gilt der Platzhalter für genau dieses Event.
|
|
*/
|
|
public class AdventCalendarExpansion extends PlaceholderExpansion {
|
|
|
|
private static final long CACHE_MILLIS = 5000L;
|
|
|
|
private record Cached(Set<Integer> days, long time) {}
|
|
|
|
// Kurzer Cache, damit Scoreboards/Hologramme die Datenbank nicht jede Sekunde abfragen
|
|
private final ConcurrentHashMap<String, Cached> cache = new ConcurrentHashMap<>();
|
|
|
|
@Override
|
|
public @NotNull String getIdentifier() {
|
|
return "ak";
|
|
}
|
|
|
|
@Override
|
|
public @NotNull String getAuthor() {
|
|
return "M_Viper";
|
|
}
|
|
|
|
@Override
|
|
public @NotNull String getVersion() {
|
|
return Adventskalender.getInstance().getDescription().getVersion();
|
|
}
|
|
|
|
@Override
|
|
public boolean persist() {
|
|
return true; // Expansion bleibt nach PAPI-Reload registriert
|
|
}
|
|
|
|
private Set<Integer> claimedDays(Player player, CalendarEvent ev) {
|
|
long now = System.currentTimeMillis();
|
|
String key = player.getUniqueId() + ":" + ev.getId();
|
|
Cached c = cache.get(key);
|
|
if (c != null && now - c.time() < CACHE_MILLIS) return c.days();
|
|
Set<Integer> days = DataHandler.getViewClaimedDays(player, ev);
|
|
if (days == null) days = new HashSet<>();
|
|
cache.put(key, new Cached(days, now));
|
|
return days;
|
|
}
|
|
|
|
private record CachedBirthday(Optional<DataHandler.Birthday> birthday, long time) {}
|
|
|
|
private final ConcurrentHashMap<UUID, CachedBirthday> birthdayCache = new ConcurrentHashMap<>();
|
|
|
|
private String birthdayPlaceholder(Player player, boolean activeOnly) {
|
|
long now = System.currentTimeMillis();
|
|
CachedBirthday c = birthdayCache.get(player.getUniqueId());
|
|
if (c == null || now - c.time() >= CACHE_MILLIS * 6) {
|
|
try {
|
|
c = new CachedBirthday(DataHandler.getBirthday(player.getUniqueId()), now);
|
|
} catch (DataHandler.DataException e) {
|
|
return activeOnly ? "Nein" : "-";
|
|
}
|
|
birthdayCache.put(player.getUniqueId(), c);
|
|
}
|
|
if (c.birthday().isEmpty()) return activeOnly ? "Nein" : "-";
|
|
DataHandler.Birthday b = c.birthday().get();
|
|
if (!activeOnly) return BirthdayManager.format(b.month(), b.day());
|
|
Integer year = BirthdayManager.activeYear(b.month(), b.day(),
|
|
java.time.LocalDate.now(Adventskalender.getInstance().getZone()));
|
|
return (year != null && b.claimedYear() < year) ? "Ja" : "Nein";
|
|
}
|
|
|
|
@Override
|
|
public String onPlaceholderRequest(Player player, String identifier) {
|
|
if (player == null) return "";
|
|
|
|
String id = identifier.toLowerCase();
|
|
|
|
// %ak_birthday% - eingetragener Geburtstag (TT.MM.) oder "-"
|
|
// %ak_birthday_active% - "Ja", wenn das Geburtstagsgeschenk gerade abholbar ist
|
|
if (id.equals("birthday") || id.equals("birthday_active")) {
|
|
return birthdayPlaceholder(player, id.equals("birthday_active"));
|
|
}
|
|
|
|
CalendarEvent ev = null;
|
|
|
|
// Optionales Event-Präfix, z.B. "halloween_claimed"
|
|
for (CalendarEvent candidate : EventManager.all()) {
|
|
if (id.startsWith(candidate.getId() + "_")) {
|
|
ev = candidate;
|
|
id = id.substring(candidate.getId().length() + 1);
|
|
break;
|
|
}
|
|
}
|
|
if (ev == null) ev = EventManager.defaultEvent();
|
|
if (ev == null) return "";
|
|
|
|
int currentDay = ev.currentDay();
|
|
|
|
switch (id) {
|
|
|
|
// %ak_event% - ID des Events
|
|
case "event":
|
|
return ev.getId();
|
|
|
|
// %ak_claimed% - Anzahl der bereits geöffneten Türchen
|
|
case "claimed":
|
|
return String.valueOf(claimedDays(player, ev).size());
|
|
|
|
// %ak_day% - Der aktuelle Tag des Kalenders
|
|
case "day":
|
|
return String.valueOf(currentDay);
|
|
|
|
// %ak_has_claimed_today% - Gibt "Ja" oder "Nein" zurück, ob heute schon geöffnet wurde
|
|
case "has_claimed_today":
|
|
if (currentDay == 0) return "Keine Adventszeit";
|
|
return claimedDays(player, ev).contains(currentDay) ? "Ja" : "Nein";
|
|
|
|
// %ak_remaining% - Wie viele Türchen sind noch offen?
|
|
case "remaining":
|
|
return String.valueOf(ev.getDays() - claimedDays(player, ev).size());
|
|
|
|
// %ak_is_global% - Zeigt an, ob der globale Modus aktiv ist
|
|
case "is_global":
|
|
return ev.isGlobal() ? "Global" : "Spieler-basiert";
|
|
}
|
|
|
|
return null; // Placeholder unbekannt
|
|
}
|
|
}
|