From 6a56cddaa13fee7c6e697dcd64cbe55124f4d23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Fri, 9 Aug 2024 09:24:32 +0200 Subject: [PATCH] Add option to purge invalid/outdated user data if someone is heavily modifying pool/quest configs in production --- .../auroramc/quests/api/data/QuestData.java | 38 +++++++++++++++++-- .../gg/auroramc/quests/config/Config.java | 1 + .../quests/listener/PlayerListener.java | 20 ++++++---- src/main/resources/config.yml | 3 ++ 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/main/java/gg/auroramc/quests/api/data/QuestData.java b/src/main/java/gg/auroramc/quests/api/data/QuestData.java index 7276862..e8447a5 100644 --- a/src/main/java/gg/auroramc/quests/api/data/QuestData.java +++ b/src/main/java/gg/auroramc/quests/api/data/QuestData.java @@ -4,13 +4,14 @@ import com.google.common.collect.Sets; import gg.auroramc.aurora.api.user.UserDataHolder; import gg.auroramc.aurora.api.util.NamespacedId; +import gg.auroramc.quests.AuroraQuests; +import gg.auroramc.quests.api.quest.Quest; +import gg.auroramc.quests.api.quest.QuestPool; import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.Nullable; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; +import java.util.stream.Collectors; public class QuestData extends UserDataHolder { private final Map rolledQuests = Maps.newConcurrentMap(); @@ -190,4 +191,33 @@ public void initFrom(@Nullable ConfigurationSection data) { poolUnlocks.addAll(data.getStringList("pool_unlocks")); } + + public void purgeInvalidData(Collection questPools) { + var poolIds = questPools.stream().map(QuestPool::getId).collect(Collectors.toSet()); + + completedCount.keySet().removeIf(poolId -> !poolIds.contains(poolId)); + progression.keySet().removeIf(poolId -> !poolIds.contains(poolId)); + questUnlocks.keySet().removeIf(poolId -> !poolIds.contains(poolId)); + rolledQuests.keySet().removeIf(poolId -> !poolIds.contains(poolId)); + completedQuests.keySet().removeIf(poolId -> !poolIds.contains(poolId)); + poolUnlocks.removeIf(poolId -> !poolIds.contains(poolId)); + + for (var pool : questPools) { + var questIds = pool.getQuests().stream().map(Quest::getId).collect(Collectors.toSet()); + + if (progression.containsKey(pool.getId())) { + progression.get(pool.getId()).keySet().removeIf(id -> !questIds.contains(id)); + } + + if (questUnlocks.containsKey(pool.getId())) { + questUnlocks.get(pool.getId()).removeIf(id -> !questIds.contains(id)); + } + + if (completedQuests.containsKey(pool.getId())) { + completedQuests.get(pool.getId()).removeIf(id -> !questIds.contains(id)); + } + } + + dirty.set(true); + } } diff --git a/src/main/java/gg/auroramc/quests/config/Config.java b/src/main/java/gg/auroramc/quests/config/Config.java index a848512..ffcfbba 100644 --- a/src/main/java/gg/auroramc/quests/config/Config.java +++ b/src/main/java/gg/auroramc/quests/config/Config.java @@ -13,6 +13,7 @@ @Getter public class Config extends AuroraConfig { private Boolean debug = false; + private Boolean purgeInvalidDataOnLogin = false; private String language = "en"; private Map difficulties; private Boolean preventCreativeMode = false; diff --git a/src/main/java/gg/auroramc/quests/listener/PlayerListener.java b/src/main/java/gg/auroramc/quests/listener/PlayerListener.java index fe2667f..be7173c 100644 --- a/src/main/java/gg/auroramc/quests/listener/PlayerListener.java +++ b/src/main/java/gg/auroramc/quests/listener/PlayerListener.java @@ -1,15 +1,18 @@ package gg.auroramc.quests.listener; +import gg.auroramc.aurora.api.AuroraAPI; import gg.auroramc.aurora.api.events.user.AuroraUserLoadedEvent; import gg.auroramc.aurora.api.message.Chat; import gg.auroramc.aurora.api.message.Placeholder; import gg.auroramc.quests.AuroraQuests; +import gg.auroramc.quests.api.data.QuestData; import gg.auroramc.quests.api.event.QuestCompletedEvent; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; +import java.util.HashSet; import java.util.concurrent.CompletableFuture; public class PlayerListener implements Listener { @@ -25,13 +28,9 @@ public void onPlayerLoaded(AuroraUserLoadedEvent event) { if (player == null) return; if (event.isAsynchronous()) { - roll(player); - plugin.getQuestManager().getRewardAutoCorrector().correctRewards(player); + initPlayer(player); } else { - CompletableFuture.runAsync(() -> { - roll(player); - plugin.getQuestManager().getRewardAutoCorrector().correctRewards(player); - }); + CompletableFuture.runAsync(() -> initPlayer(player)); } } @@ -40,7 +39,7 @@ public void onPlayerQuit(PlayerQuitEvent event) { plugin.getQuestManager().handlePlayerQuit(event.getPlayer().getUniqueId()); } - private void roll(Player player) { + private void initPlayer(Player player) { plugin.getQuestManager().tryUnlockQuestPools(player); plugin.getQuestManager().tryStartGlobalQuests(player); @@ -50,6 +49,13 @@ private void roll(Player player) { var msg = plugin.getConfigManager().getMessageConfig().getReRolledTarget(); Chat.sendMessage(player, msg, Placeholder.of("{pool}", String.join(", ", pools.stream().map(p -> p.getConfig().getName()).toList()))); + + plugin.getQuestManager().getRewardAutoCorrector().correctRewards(player); + + if (plugin.getConfigManager().getConfig().getPurgeInvalidDataOnLogin()) { + AuroraAPI.getUserManager().getUser(player).getData(QuestData.class) + .purgeInvalidData(plugin.getQuestManager().getQuestPools()); + } } @EventHandler diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 7918e55..0d7fc30 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -5,6 +5,9 @@ debug: false language: en prevent-creative-mode: true +# Only enable this if you are heavily modifying your quest pools/quests data in production (WHICH YOU SHOULDN'T) +purge-invalid-data-on-login: false + # Timer to try to unlock global quests and quest pools if for some reason the event driven method doesn't work unlock-task: enabled: false