package de.fanta.challenge.challenges;
import com.destroystokyo.paper.event.player.PlayerAdvancementCriterionGrantEvent;
import de.fanta.challenge.Challenge;
import de.fanta.challenge.events.TimerChangedEvent;
import de.fanta.challenge.utils.ChatUtil;
import de.fanta.challenge.utils.Config;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.advancement.Advancement;
import org.bukkit.advancement.AdvancementProgress;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerAdvancementDoneEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
public class AllAdvancementsChallenge implements Listener {
public static BossBar bossBar;
private static boolean running;
private static final Challenge plugin = Challenge.getPlugin();
@EventHandler
public void onActivation(TimerChangedEvent event) {
if (Config.getBoolean("alladvancements")) {
if (event.isRunning()) {
start();
} else {
stop();
}
}
}
@EventHandler
public void onAdvancementDone(PlayerAdvancementDoneEvent e) {
if (isRunning()) {
createAdvancementString(e.getPlayer());
}
}
@EventHandler
public void onAdvancementCriteria(PlayerAdvancementCriterionGrantEvent e) {
if (isRunning()) {
createAdvancementString(e.getPlayer());
}
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
if (!isRunning()) {
return;
}
bossBar.addViewer(e.getPlayer());
setAdvancementsToPlayer();
}
public static boolean isRunning() {
return running;
}
public static void setRunning(boolean run) {
running = run;
}
private static void updateBossbar() {
int done = countDone();
Component bossBarTitle = Component.text("(" + done + "/" + plugin.getAdvancements().size() + ") Advancements", ChatUtil.GREEN);
float progress = done * 100.0f / plugin.getAdvancements().size() / 100.0f;
if (bossBar == null) {
bossBar = BossBar.bossBar(bossBarTitle, progress, BossBar.Color.GREEN, BossBar.Overlay.PROGRESS);
} else {
bossBar.name(bossBarTitle);
}
bossBar.progress(progress);
}
private void createAdvancementString(Player player) {
ConfigurationSection advancements = Config.createSection("advancements");
ArrayList<String> advancementsDone = new ArrayList<>();
ConfigurationSection progress = advancements.createSection("progress");
Iterator<Advancement> it = Bukkit.advancementIterator();
while (it.hasNext()) {
Advancement a = it.next();
NamespacedKey key = a.getKey();
if (key.getNamespace().equals(NamespacedKey.MINECRAFT) && !key.getKey().startsWith("recipes/")) {
AdvancementProgress ap = player.getAdvancementProgress(a);
if (ap.isDone()) {
advancementsDone.add(key.getKey());
} else {
Collection<String> ac = ap.getAwardedCriteria();
if (!ac.isEmpty()) {
progress.set(key.getKey(), new ArrayList<>(ac));
}
}
}
}
advancements.set("done", advancementsDone);
plugin.saveConfig();
setAdvancementsToPlayer();
}
private static void setAdvancementsToPlayer() {
if (Config.contains("advancements")) {
ConfigurationSection advancements = Config.getConfigurationSection("advancements");
if (advancements != null) {
HashSet<String> done = new HashSet<>(advancements.getStringList("done"));
ConfigurationSection progress = advancements.getConfigurationSection("progress");
if (progress == null) {
return;
}
Iterator<Advancement> it = Bukkit.advancementIterator();
while (it.hasNext()) {
Advancement a = it.next();
NamespacedKey key = a.getKey();
if (key.getNamespace().equals(NamespacedKey.MINECRAFT) && !key.getKey().startsWith("recipes/")) {
for (Player pp : plugin.getVanish().getPlayerListWithoutVanishPlayers()) {
AdvancementProgress ap = pp.getAdvancementProgress(a);
if (done.contains(key.getKey())) {
if (!ap.isDone()) {
for (String crit : ap.getRemainingCriteria()) {
ap.awardCriteria(crit);
}
}
} else if (progress.contains(key.getKey())) {
List<String> parts = progress.getStringList(key.getKey());
for (String part : parts) {
ap.awardCriteria(part);
}
}
}
}
}
}
}
updateBossbar();
}
private static int countDone() {
int i = 0;
ConfigurationSection advancements = Config.getConfigurationSection("advancements");
if (advancements != null) {
HashSet<String> done = new HashSet<>(advancements.getStringList("done"));
for (String ignored : done) {
i++;
}
}
return i;
}
public static void start() {
setAdvancementsToPlayer();
updateBossbar();
for (Player pp : Bukkit.getOnlinePlayers()) {
bossBar.addViewer(pp);
}
setRunning(true);
}
public static void stop() {
if (bossBar != null) {
bossBar.viewers().forEach(bossBarViewer -> bossBar.removeViewer((Audience) bossBarViewer));
}
setRunning(false);
}
}