From 3cee8805b77c13a796da807fcbeccade9132364d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Sun, 29 Sep 2024 09:20:16 +0200 Subject: [PATCH] Optimize stat correctors to use less threads and player schedulers; Add EcoSkills as supported stat provider? --- build.gradle.kts | 5 +- .../java/gg/auroramc/levels/AuroraLevels.java | 5 +- .../java/gg/auroramc/levels/hooks/Hooks.java | 1 + .../hooks/auraskills/AuraSkillsCorrector.java | 69 +++++++++--------- .../hooks/ecoskills/EcoSkillsCorrector.java | 70 ++++++++++++++++++ .../levels/hooks/ecoskills/EcoSkillsHook.java | 17 +++++ .../hooks/ecoskills/EcoSkillsStatReward.java | 73 +++++++++++++++++++ .../hooks/luckperms/PermissionCorrector.java | 52 ++++++------- .../levels/hooks/mmolib/MMOStatCorrector.java | 60 +++++++-------- .../mythic/reward/MythicStatCorrector.java | 71 +++++++++--------- .../levels/leveler/PlayerLeveler.java | 3 +- src/main/resources/plugin.yml | 1 + 12 files changed, 290 insertions(+), 137 deletions(-) create mode 100644 src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsCorrector.java create mode 100644 src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsHook.java create mode 100644 src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsStatReward.java diff --git a/build.gradle.kts b/build.gradle.kts index 3584763..f6c4f39 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,7 +18,7 @@ plugins { } group = "gg.auroramc" -version = "1.5.3" +version = "1.5.4-SNAPSHOT" java.sourceCompatibility = JavaVersion.VERSION_21 java.targetCompatibility = JavaVersion.VERSION_21 @@ -33,6 +33,7 @@ repositories { maven("https://mvn.lumine.io/repository/maven-public/") maven("https://nexus.phoenixdevt.fr/repository/maven-public/") maven("https://maven.enginehub.org/repo/") + maven("https://repo.auxilor.io/repository/maven-public/") } dependencies { @@ -43,6 +44,8 @@ dependencies { compileOnly("io.lumine:Mythic-Dist:5.6.1") compileOnly("io.lumine:MythicLib-dist:1.6.2-SNAPSHOT") compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.7") + compileOnly("com.willfp:eco:6.73.0") + compileOnly("com.willfp:EcoSkills:3.59.7") implementation("co.aikar:acf-paper:0.5.1-SNAPSHOT") diff --git a/src/main/java/gg/auroramc/levels/AuroraLevels.java b/src/main/java/gg/auroramc/levels/AuroraLevels.java index 85fdb4e..d5af99c 100644 --- a/src/main/java/gg/auroramc/levels/AuroraLevels.java +++ b/src/main/java/gg/auroramc/levels/AuroraLevels.java @@ -13,6 +13,8 @@ import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; +import java.util.concurrent.CompletableFuture; + public class AuroraLevels extends JavaPlugin { @Getter private PlayerLeveler leveler; @@ -74,7 +76,8 @@ public void reload() { commandManager.reload(); leveler.reload(false); - Bukkit.getOnlinePlayers().forEach(player -> leveler.getRewardAutoCorrector().correctRewards(player)); + Bukkit.getOnlinePlayers().forEach(player -> + CompletableFuture.runAsync(() -> leveler.getRewardAutoCorrector().correctRewards(player))); } @Override diff --git a/src/main/java/gg/auroramc/levels/hooks/Hooks.java b/src/main/java/gg/auroramc/levels/hooks/Hooks.java index 40ea6f3..6572a14 100644 --- a/src/main/java/gg/auroramc/levels/hooks/Hooks.java +++ b/src/main/java/gg/auroramc/levels/hooks/Hooks.java @@ -10,6 +10,7 @@ @Getter public enum Hooks { AURA_SKILLS(AuraSkillsHook.class, "AuraSkills"), + ECO_SKILLS(AuraSkillsHook.class, "EcoSkills"), LUCK_PERMS(LuckPermsHook.class, "LuckPerms"), MYTHIC_MOBS(MythicHook.class, "MythicMobs"), WORLD_GUARD(WorldguardHook.class, "WorldGuard"), diff --git a/src/main/java/gg/auroramc/levels/hooks/auraskills/AuraSkillsCorrector.java b/src/main/java/gg/auroramc/levels/hooks/auraskills/AuraSkillsCorrector.java index 5e9958f..7baeb9e 100644 --- a/src/main/java/gg/auroramc/levels/hooks/auraskills/AuraSkillsCorrector.java +++ b/src/main/java/gg/auroramc/levels/hooks/auraskills/AuraSkillsCorrector.java @@ -6,11 +6,9 @@ import dev.aurelium.auraskills.api.stat.StatModifier; import gg.auroramc.aurora.api.reward.RewardCorrector; import gg.auroramc.levels.AuroraLevels; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import java.util.Map; -import java.util.concurrent.CompletableFuture; public class AuraSkillsCorrector implements RewardCorrector { private final AuroraLevels plugin; @@ -21,50 +19,49 @@ public AuraSkillsCorrector(AuroraLevels plugin) { @Override public void correctRewards(Player player) { - CompletableFuture.runAsync(() -> { - var leveler = plugin.getLeveler(); - var data = leveler.getUserData(player); - var level = data.getLevel(); + var leveler = plugin.getLeveler(); + var data = leveler.getUserData(player); + var level = data.getLevel(); - Map statMap = Maps.newHashMap(); + Map statMap = Maps.newHashMap(); - // Reset all stat modifiers first - for (var stat : AuraSkillsApi.get().getGlobalRegistry().getStats()) { - statMap.put(stat, 0.0); - } + // Reset all stat modifiers first + for (var stat : AuraSkillsApi.get().getGlobalRegistry().getStats()) { + statMap.put(stat, 0.0); + } - // Gather new stat modifiers - for (int i = 1; i < level + 1; i++) { - var matcher = leveler.getLevelMatcher().getBestMatcher(i); - if (matcher == null) continue; - var formulaPlaceholders = leveler.getRewardFormulaPlaceholders(player, i); - for (var reward : matcher.computeRewards(i)) { - if (reward instanceof AuraSkillsStatReward statReward) { - statMap.merge(statReward.getStat(), statReward.getValue(formulaPlaceholders), Double::sum); - } + // Gather new stat modifiers + for (int i = 1; i < level + 1; i++) { + var matcher = leveler.getLevelMatcher().getBestMatcher(i); + if (matcher == null) continue; + var formulaPlaceholders = leveler.getRewardFormulaPlaceholders(player, i); + for (var reward : matcher.computeRewards(i)) { + if (reward instanceof AuraSkillsStatReward statReward) { + statMap.merge(statReward.getStat(), statReward.getValue(formulaPlaceholders), Double::sum); } } + } - // I'm not sure if it's safe to call AuraSkills apis async, so lets just run it on the main thread - Bukkit.getGlobalRegionScheduler().run(plugin, (task) -> { - // Apply the new stat modifiers - for (var entry : statMap.entrySet()) { - var statKey = AuraSkillsStatReward.getAURA_SKILLS_STAT() + entry.getKey().getId().toString(); - var user = AuraSkillsApi.get().getUser(player.getUniqueId()); + if (!player.isOnline()) return; - var oldModifier = user.getStatModifier(statKey); + player.getScheduler().run(plugin, (task) -> { + // Apply the new stat modifiers + for (var entry : statMap.entrySet()) { + var statKey = AuraSkillsStatReward.getAURA_SKILLS_STAT() + entry.getKey().getId().toString(); + var user = AuraSkillsApi.get().getUser(player.getUniqueId()); - if (oldModifier == null) { - if (entry.getValue() > 0) { - user.addStatModifier(new StatModifier(statKey, entry.getKey(), entry.getValue())); - } - } else if (entry.getValue() <= 0) { - user.removeStatModifier(statKey); - } else if (entry.getValue() != oldModifier.value()) { + var oldModifier = user.getStatModifier(statKey); + + if (oldModifier == null) { + if (entry.getValue() > 0) { user.addStatModifier(new StatModifier(statKey, entry.getKey(), entry.getValue())); } + } else if (entry.getValue() <= 0) { + user.removeStatModifier(statKey); + } else if (entry.getValue() != oldModifier.value()) { + user.addStatModifier(new StatModifier(statKey, entry.getKey(), entry.getValue())); } - }); - }); + } + }, null); } } diff --git a/src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsCorrector.java b/src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsCorrector.java new file mode 100644 index 0000000..441965d --- /dev/null +++ b/src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsCorrector.java @@ -0,0 +1,70 @@ +package gg.auroramc.levels.hooks.ecoskills; + +import com.google.common.collect.Maps; +import com.willfp.ecoskills.api.EcoSkillsAPI; +import com.willfp.ecoskills.api.modifiers.ModifierOperation; +import com.willfp.ecoskills.api.modifiers.StatModifier; +import com.willfp.ecoskills.stats.Stats; +import gg.auroramc.aurora.api.reward.RewardCorrector; +import gg.auroramc.levels.AuroraLevels; +import org.bukkit.entity.Player; + +import java.util.Map; + +public class EcoSkillsCorrector implements RewardCorrector { + private final AuroraLevels plugin; + + public EcoSkillsCorrector(AuroraLevels plugin) { + this.plugin = plugin; + } + + @Override + public void correctRewards(Player player) { + var leveler = plugin.getLeveler(); + var data = leveler.getUserData(player); + var level = data.getLevel(); + + Map> statMap = Maps.newHashMap(); + + Stats.INSTANCE.values().forEach(stat -> { + var map = statMap.computeIfAbsent(stat.getId(), (key) -> Maps.newHashMap()); + for (var operation : ModifierOperation.values()) { + map.put(operation, 0.0); + } + }); + + // Gather new stat modifiers + for (int i = 1; i < level + 1; i++) { + var matcher = leveler.getLevelMatcher().getBestMatcher(i); + if (matcher == null) continue; + var formulaPlaceholders = leveler.getRewardFormulaPlaceholders(player, i); + for (var reward : matcher.computeRewards(i)) { + if (reward instanceof EcoSkillsStatReward statReward && statReward.isValid()) { + statMap.computeIfAbsent(statReward.getStat().getId(), (key) -> Maps.newHashMap()) + .merge(statReward.getOperation(), statReward.getValue(formulaPlaceholders), Double::sum); + } + } + } + + // Apply the new stat modifiers + player.getScheduler().run(plugin, (task) -> { + for (var entry : statMap.entrySet()) { + var statType = entry.getKey(); + var stat = Stats.INSTANCE.getByID(statType); + if (stat == null) continue; + + for (var modifierEntry : entry.getValue().entrySet()) { + var operation = modifierEntry.getKey(); + var value = modifierEntry.getValue(); + var uuid = EcoSkillsStatReward.createStatModifierUUID(stat, operation); + if (value <= 0) { + EcoSkillsAPI.removeStatModifier(player, uuid); + } else { + AuroraLevels.logger().debug("Adding stat " + statType + " with value " + value + "/" + operation.name() + " to player " + player.getName()); + EcoSkillsAPI.addStatModifier(player, new StatModifier(uuid, stat, value, operation)); + } + } + } + }, null); + } +} diff --git a/src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsHook.java b/src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsHook.java new file mode 100644 index 0000000..9290ecb --- /dev/null +++ b/src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsHook.java @@ -0,0 +1,17 @@ +package gg.auroramc.levels.hooks.ecoskills; + +import gg.auroramc.aurora.api.util.NamespacedId; +import gg.auroramc.levels.AuroraLevels; +import gg.auroramc.levels.hooks.Hook; + +public class EcoSkillsHook implements Hook { + @Override + public void hook(AuroraLevels plugin) { + plugin.getLeveler().getRewardFactory() + .registerRewardType(NamespacedId.fromDefault("ecoskills_stat"), EcoSkillsStatReward.class); + plugin.getLeveler().getRewardAutoCorrector() + .registerCorrector(NamespacedId.fromDefault("ecoskills_stat"), new EcoSkillsCorrector(plugin)); + + AuroraLevels.logger().info("Hooked into AuraSkills for stat rewards with reward type: 'ecoskills_stat'. Auto reward corrector for stats is registered."); + } +} diff --git a/src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsStatReward.java b/src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsStatReward.java new file mode 100644 index 0000000..f96ae96 --- /dev/null +++ b/src/main/java/gg/auroramc/levels/hooks/ecoskills/EcoSkillsStatReward.java @@ -0,0 +1,73 @@ +package gg.auroramc.levels.hooks.ecoskills; + +import com.willfp.ecoskills.api.EcoSkillsAPI; +import com.willfp.ecoskills.api.modifiers.ModifierOperation; +import com.willfp.ecoskills.api.modifiers.StatModifier; +import com.willfp.ecoskills.stats.Stat; +import com.willfp.ecoskills.stats.Stats; +import gg.auroramc.aurora.api.message.Placeholder; +import gg.auroramc.aurora.api.reward.NumberReward; +import gg.auroramc.levels.AuroraLevels; +import lombok.Getter; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Locale; +import java.util.UUID; + +@Getter +public class EcoSkillsStatReward extends NumberReward { + public static final String prefix = "aurora_levels/stat/"; + + private boolean valid = true; + private Stat stat; + private ModifierOperation operation = ModifierOperation.ADD; + + private UUID createStatModifierUUID() { + return createStatModifierUUID(stat, operation); + } + + public static UUID createStatModifierUUID(Stat stat, ModifierOperation operation) { + return UUID.nameUUIDFromBytes((prefix + stat.getId() + "/" + operation.name()).getBytes()); + } + + @Override + public void execute(Player player, long level, List> placeholders) { + if (!valid) return; + var uuid = createStatModifierUUID(); + var current = EcoSkillsAPI.getStatModifier(player, uuid); + + double value = getValue(placeholders) + (current != null ? current.getModifier() : 0); + + // Since the UUID is always the same this should overwrite the previous value + EcoSkillsAPI.addStatModifier(player, new StatModifier(uuid, stat, value, operation)); + } + + @Override + public void init(ConfigurationSection args) { + super.init(args); + var statName = args.getString("stat", ""); + stat = Stats.INSTANCE.getByID(statName); + if (stat == null) { + valid = false; + AuroraLevels.logger().warning("Couldn't find EcoSkills stat: " + statName); + } + + var operationName = args.getString("operation", "add").toUpperCase(Locale.ROOT); + + try { + operation = ModifierOperation.valueOf(operationName); + } catch (IllegalArgumentException e) { + valid = false; + AuroraLevels.logger().warning("Couldn't find EcoSkills operation: " + operationName); + } + } + + @Override + public String getDisplay(Player player, List> placeholders) { + var display = super.getDisplay(player, placeholders); + if (!valid) return display; + return Placeholder.execute(display, Placeholder.of("{stat}", stat.getName())); + } +} diff --git a/src/main/java/gg/auroramc/levels/hooks/luckperms/PermissionCorrector.java b/src/main/java/gg/auroramc/levels/hooks/luckperms/PermissionCorrector.java index 472d2fb..f19aa72 100644 --- a/src/main/java/gg/auroramc/levels/hooks/luckperms/PermissionCorrector.java +++ b/src/main/java/gg/auroramc/levels/hooks/luckperms/PermissionCorrector.java @@ -8,8 +8,6 @@ import net.luckperms.api.util.Tristate; import org.bukkit.entity.Player; -import java.util.concurrent.CompletableFuture; - public class PermissionCorrector implements RewardCorrector { private AuroraLevels plugin; @@ -19,38 +17,34 @@ public PermissionCorrector(AuroraLevels plugin) { @Override public void correctRewards(Player player) { - CompletableFuture.runAsync(() -> { - var leveler = plugin.getLeveler(); - var data = leveler.getUserData(player); - var level = data.getLevel(); - - for (int i = 1; i < level + 1; i++) { - var matcher = leveler.getLevelMatcher().getBestMatcher(i); - if (matcher == null) continue; - var formulaPlaceholders = leveler.getRewardFormulaPlaceholders(player, i); - for (var reward : matcher.computeRewards(i)) { - if (reward instanceof PermissionReward permissionReward) { - if (permissionReward.getPermissions() == null || permissionReward.getPermissions().isEmpty()) { - continue; - } + var leveler = plugin.getLeveler(); + var data = leveler.getUserData(player); + var level = data.getLevel(); + + for (int i = 1; i < level + 1; i++) { + var matcher = leveler.getLevelMatcher().getBestMatcher(i); + if (matcher == null) continue; + var formulaPlaceholders = leveler.getRewardFormulaPlaceholders(player, i); + for (var reward : matcher.computeRewards(i)) { + if (reward instanceof PermissionReward permissionReward) { + if (permissionReward.getPermissions() == null || permissionReward.getPermissions().isEmpty()) { + continue; + } - var nodes = permissionReward.buildNodes(player, formulaPlaceholders); + var nodes = permissionReward.buildNodes(player, formulaPlaceholders); - LuckPermsProvider.get().getUserManager().modifyUser(player.getUniqueId(), (user) -> { - for (var node : nodes) { - var hasPermission = user.data().contains(node, NodeEqualityPredicate.EXACT); + LuckPermsProvider.get().getUserManager().modifyUser(player.getUniqueId(), (user) -> { + for (var node : nodes) { + var hasPermission = user.data().contains(node, NodeEqualityPredicate.EXACT); - if (hasPermission.equals(Tristate.UNDEFINED)) { - AuroraLevels.logger().debug("Permission " + node.getKey() + " is undefined for player " + player.getName()); - user.data().add(node); - } + if (hasPermission.equals(Tristate.UNDEFINED)) { + AuroraLevels.logger().debug("Permission " + node.getKey() + " is undefined for player " + player.getName()); + user.data().add(node); } - }); - } + } + }); } - - } - }); + } } } diff --git a/src/main/java/gg/auroramc/levels/hooks/mmolib/MMOStatCorrector.java b/src/main/java/gg/auroramc/levels/hooks/mmolib/MMOStatCorrector.java index 47329a6..03613a0 100644 --- a/src/main/java/gg/auroramc/levels/hooks/mmolib/MMOStatCorrector.java +++ b/src/main/java/gg/auroramc/levels/hooks/mmolib/MMOStatCorrector.java @@ -10,12 +10,10 @@ import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import io.lumine.mythic.lib.player.modifier.ModifierSource; import io.lumine.mythic.lib.player.modifier.ModifierType; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import java.util.Map; import java.util.UUID; -import java.util.concurrent.CompletableFuture; public class MMOStatCorrector implements RewardCorrector { private final AuroraLevels plugin; @@ -26,43 +24,41 @@ public MMOStatCorrector(AuroraLevels plugin) { @Override public void correctRewards(Player player) { - CompletableFuture.runAsync(() -> { - var leveler = plugin.getLeveler(); - var data = leveler.getUserData(player); - var level = data.getLevel(); + var leveler = plugin.getLeveler(); + var data = leveler.getUserData(player); + var level = data.getLevel(); - MMOPlayerData playerData = MMOPlayerData.get(player); - StatMap stats = playerData.getStatMap(); + MMOPlayerData playerData = MMOPlayerData.get(player); + StatMap stats = playerData.getStatMap(); - Map statMap = Maps.newHashMap(); + Map statMap = Maps.newHashMap(); - // Gather new stat modifiers - for (int i = 1; i < level + 1; i++) { - var matcher = leveler.getLevelMatcher().getBestMatcher(i); - if (matcher == null) continue; - var formulaPlaceholders = leveler.getRewardFormulaPlaceholders(player, i); - for (var reward : matcher.computeRewards(i)) { - if (reward instanceof MMOStatReward statReward && statReward.isValid()) { - var key = NamespacedId.of(MMOStatReward.getMMO_STAT(), statReward.getStat()).toString(); - var current = statReward.getCurrentModifier(key, stats); - UUID uuid = current != null ? current.getUniqueId() : UUID.randomUUID(); - statMap.merge(statReward.getStat(), - new MMOStat(statReward.getModifierType(), statReward.getValue(formulaPlaceholders), key, uuid), - (a, b) -> new MMOStat(statReward.getModifierType(), a.value() + b.value(), a.key(), a.uuid())); - } + // Gather new stat modifiers + for (int i = 1; i < level + 1; i++) { + var matcher = leveler.getLevelMatcher().getBestMatcher(i); + if (matcher == null) continue; + var formulaPlaceholders = leveler.getRewardFormulaPlaceholders(player, i); + for (var reward : matcher.computeRewards(i)) { + if (reward instanceof MMOStatReward statReward && statReward.isValid()) { + var key = NamespacedId.of(MMOStatReward.getMMO_STAT(), statReward.getStat()).toString(); + var current = statReward.getCurrentModifier(key, stats); + UUID uuid = current != null ? current.getUniqueId() : UUID.randomUUID(); + statMap.merge(statReward.getStat(), + new MMOStat(statReward.getModifierType(), statReward.getValue(formulaPlaceholders), key, uuid), + (a, b) -> new MMOStat(statReward.getModifierType(), a.value() + b.value(), a.key(), a.uuid())); } } + } - Bukkit.getGlobalRegionScheduler().runDelayed(plugin, (task) -> { - for (var entry : statMap.entrySet()) { - var statType = entry.getKey(); - var s = entry.getValue(); + player.getScheduler().runDelayed(plugin, (task) -> { + for (var entry : statMap.entrySet()) { + var statType = entry.getKey(); + var s = entry.getValue(); - new StatModifier(s.uuid, s.key, statType, s.value, s.modifierType, EquipmentSlot.OTHER, ModifierSource.OTHER) - .register(playerData); - } - }, 3); - }); + new StatModifier(s.uuid, s.key, statType, s.value, s.modifierType, EquipmentSlot.OTHER, ModifierSource.OTHER) + .register(playerData); + } + }, null, 3); } public record MMOStat(ModifierType modifierType, double value, String key, UUID uuid) { diff --git a/src/main/java/gg/auroramc/levels/hooks/mythic/reward/MythicStatCorrector.java b/src/main/java/gg/auroramc/levels/hooks/mythic/reward/MythicStatCorrector.java index aef7e4e..af9f567 100644 --- a/src/main/java/gg/auroramc/levels/hooks/mythic/reward/MythicStatCorrector.java +++ b/src/main/java/gg/auroramc/levels/hooks/mythic/reward/MythicStatCorrector.java @@ -9,7 +9,6 @@ import org.bukkit.entity.Player; import java.util.Map; -import java.util.concurrent.CompletableFuture; public class MythicStatCorrector implements RewardCorrector { private final AuroraLevels plugin; @@ -20,44 +19,42 @@ public MythicStatCorrector(AuroraLevels plugin) { @Override public void correctRewards(Player player) { - CompletableFuture.runAsync(() -> { - var leveler = plugin.getLeveler(); - var data = leveler.getUserData(player); - var level = data.getLevel(); - var mythic = MythicBukkit.inst(); - var registry = mythic.getPlayerManager().getProfile(player).getStatRegistry(); - - Map> statMap = Maps.newHashMap(); - - mythic.getStatManager().getStats().values() - .forEach(statType -> { - if (!statType.isEnabled()) return; - registry.removeValue(statType, MythicStatReward.getSource()); - }); - - // Gather new stat modifiers - for (int i = 1; i < level + 1; i++) { - var matcher = leveler.getLevelMatcher().getBestMatcher(i); - if (matcher == null) continue; - var formulaPlaceholders = leveler.getRewardFormulaPlaceholders(player, i); - for (var reward : matcher.computeRewards(i)) { - if (reward instanceof MythicStatReward statReward && statReward.isValid()) { - statMap.computeIfAbsent(statReward.getStatType(), (key) -> Maps.newHashMap()) - .merge(statReward.getModifierType(), statReward.getValue(formulaPlaceholders), Double::sum); - } + var leveler = plugin.getLeveler(); + var data = leveler.getUserData(player); + var level = data.getLevel(); + var mythic = MythicBukkit.inst(); + var registry = mythic.getPlayerManager().getProfile(player).getStatRegistry(); + + Map> statMap = Maps.newHashMap(); + + mythic.getStatManager().getStats().values() + .forEach(statType -> { + if (!statType.isEnabled()) return; + registry.removeValue(statType, MythicStatReward.getSource()); + }); + + // Gather new stat modifiers + for (int i = 1; i < level + 1; i++) { + var matcher = leveler.getLevelMatcher().getBestMatcher(i); + if (matcher == null) continue; + var formulaPlaceholders = leveler.getRewardFormulaPlaceholders(player, i); + for (var reward : matcher.computeRewards(i)) { + if (reward instanceof MythicStatReward statReward && statReward.isValid()) { + statMap.computeIfAbsent(statReward.getStatType(), (key) -> Maps.newHashMap()) + .merge(statReward.getModifierType(), statReward.getValue(formulaPlaceholders), Double::sum); } } - - // Apply the new stat modifiers - for (var entry : statMap.entrySet()) { - var statType = entry.getKey(); - for (var modifierEntry : entry.getValue().entrySet()) { - var modifierType = modifierEntry.getKey(); - var value = modifierEntry.getValue(); - AuroraLevels.logger().debug("Adding stat " + statType.getKey() + " with value " + value + " to player " + player.getName()); - registry.putValue(statType, MythicStatReward.getSource(), modifierType, value); - } + } + + // Apply the new stat modifiers + for (var entry : statMap.entrySet()) { + var statType = entry.getKey(); + for (var modifierEntry : entry.getValue().entrySet()) { + var modifierType = modifierEntry.getKey(); + var value = modifierEntry.getValue(); + AuroraLevels.logger().debug("Adding stat " + statType.getKey() + " with value " + value + " to player " + player.getName()); + registry.putValue(statType, MythicStatReward.getSource(), modifierType, value); } - }); + } } } diff --git a/src/main/java/gg/auroramc/levels/leveler/PlayerLeveler.java b/src/main/java/gg/auroramc/levels/leveler/PlayerLeveler.java index 7fec05d..d17376c 100644 --- a/src/main/java/gg/auroramc/levels/leveler/PlayerLeveler.java +++ b/src/main/java/gg/auroramc/levels/leveler/PlayerLeveler.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; @@ -257,6 +258,6 @@ public double getRequiredXpForLevelUp(Player player) { public void onUserLoaded(AuroraUserLoadedEvent event) { var player = event.getUser().getPlayer(); if (player == null) return; - rewardAutoCorrector.correctRewards(player); + CompletableFuture.runAsync(() -> rewardAutoCorrector.correctRewards(player)); } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3d966d2..5eb1dd2 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -13,6 +13,7 @@ softdepend: - "PlaceholderAPI" - "MythicLib" - "WorldGuard" + - "EcoSkills" permissions: aurora.levels.*: