From dc8300795ecdc99c84de9839d27d9928f8e4c294 Mon Sep 17 00:00:00 2001 From: Krakenied Date: Fri, 15 Nov 2024 16:48:34 +0100 Subject: [PATCH] Add placeholder support to vaultreward option --- .../bukkit/config/BukkitQuestsLoader.java | 2 +- .../hook/vault/rewards/DummyVaultReward.java | 24 ++++++++++ .../vault/rewards/NumericVaultReward.java | 21 +++++++++ .../vault/rewards/PlaceholderVaultReward.java | 39 ++++++++++++++++ .../hook/vault/rewards/VaultReward.java | 46 +++++++++++++++++++ .../NormalQuestController.java | 16 +++++-- .../quests/common/quest/Quest.java | 10 ++-- 7 files changed, 148 insertions(+), 10 deletions(-) create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/DummyVaultReward.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/NumericVaultReward.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/PlaceholderVaultReward.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/VaultReward.java diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java index 50fcf8f9..660f3eed 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java @@ -276,7 +276,7 @@ public FileVisitResult visitFile(Path path, BasicFileAttributes attributes) { List startCommands = config.getStringList("startcommands"); List cancelCommands = config.getStringList("cancelcommands"); List expiryCommands = config.getStringList("expirycommands"); - double vaultReward = config.getDouble("vaultreward", 0.0D); + String vaultReward = config.getString("vaultreward", null); boolean repeatable = config.getBoolean("options.repeatable", false); boolean cooldown = config.getBoolean("options.cooldown.enabled", false); boolean timeLimit = config.getBoolean("options.time-limit.enabled", false); diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/DummyVaultReward.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/DummyVaultReward.java new file mode 100644 index 00000000..93c644b7 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/DummyVaultReward.java @@ -0,0 +1,24 @@ +package com.leonardobishop.quests.bukkit.hook.vault.rewards; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +final class DummyVaultReward extends VaultReward { + + static final DummyVaultReward INSTANCE = new DummyVaultReward(); + + DummyVaultReward() { + // temporarily ignore it + //noinspection DataFlowIssue + super(null); + } + + @Override + public double getRewardValue(final @NotNull Player player) { + return 0.0d; + } + + @Override + public void give(final @NotNull Player player) { + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/NumericVaultReward.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/NumericVaultReward.java new file mode 100644 index 00000000..2b1ed151 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/NumericVaultReward.java @@ -0,0 +1,21 @@ +package com.leonardobishop.quests.bukkit.hook.vault.rewards; + +import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +final class NumericVaultReward extends VaultReward { + + private final double value; + + NumericVaultReward(final @NotNull BukkitQuestsPlugin plugin, final double value) { + super(plugin); + + this.value = value; + } + + @Override + public double getRewardValue(final @NotNull Player player) { + return this.value; + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/PlaceholderVaultReward.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/PlaceholderVaultReward.java new file mode 100644 index 00000000..93e2a6b2 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/PlaceholderVaultReward.java @@ -0,0 +1,39 @@ +package com.leonardobishop.quests.bukkit.hook.vault.rewards; + +import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.hook.papi.AbstractPlaceholderAPIHook; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +final class PlaceholderVaultReward extends VaultReward { + + private final String rewardString; + + PlaceholderVaultReward(final @NotNull BukkitQuestsPlugin plugin, final @NotNull String rewardString) { + super(plugin); + + this.rewardString = rewardString; + } + + @Override + public double getRewardValue(final @NotNull Player player) { + final AbstractPlaceholderAPIHook hook = this.plugin.getPlaceholderAPIHook(); + + if (hook == null) { + this.plugin.getLogger().warning("Could not give '" + this.rewardString + "' vault reward to " + player.getName() + ". No PlaceholderAPI hook found!"); + return 0.0d; + } + + final String papiRewardString = this.plugin.getPlaceholderAPIHook().replacePlaceholders(player, this.rewardString); + + final double vaultReward; + try { + vaultReward = Double.parseDouble(papiRewardString); + } catch (final NumberFormatException e) { + this.plugin.getLogger().warning("Could not give '" + this.rewardString + "' (PAPI: '" + papiRewardString + "') vault reward to " + player.getName() + ". Invalid double format!"); + return 0.0d; + } + + return vaultReward; + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/VaultReward.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/VaultReward.java new file mode 100644 index 00000000..158d026f --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/vault/rewards/VaultReward.java @@ -0,0 +1,46 @@ +package com.leonardobishop.quests.bukkit.hook.vault.rewards; + +import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class VaultReward { + + final BukkitQuestsPlugin plugin; + + VaultReward(final @NotNull BukkitQuestsPlugin plugin) { + this.plugin = plugin; + } + + public abstract double getRewardValue(final @NotNull Player player); + + public void give(final @NotNull Player player) { + this.plugin.getVaultHook().depositPlayer(player, this.getRewardValue(player)); + } + + public static @NotNull VaultReward parse(final @NotNull BukkitQuestsPlugin plugin, final @Nullable String str) { + if (str == null) { + return DummyVaultReward.INSTANCE; + } + + if (str.indexOf('%') == -1) { + return parseNumeric(plugin, str); + } + + return new PlaceholderVaultReward(plugin, str); + } + + private static @NotNull VaultReward parseNumeric(final @NotNull BukkitQuestsPlugin plugin, final @NotNull String str) { + final double value; + + try { + value = Double.parseDouble(str); + } catch (final NumberFormatException e) { + plugin.getLogger().warning("Could not parse '" + str + "' vault reward. Invalid double format!"); + return DummyVaultReward.INSTANCE; + } + + return new NumericVaultReward(plugin, value); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java index af2a316d..04ef14b4 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/questcontroller/NormalQuestController.java @@ -9,6 +9,7 @@ import com.leonardobishop.quests.bukkit.api.event.PlayerStopTrackQuestEvent; import com.leonardobishop.quests.bukkit.api.event.PreStartQuestEvent; import com.leonardobishop.quests.bukkit.config.BukkitQuestsConfig; +import com.leonardobishop.quests.bukkit.hook.vault.rewards.VaultReward; import com.leonardobishop.quests.bukkit.menu.itemstack.QItemStack; import com.leonardobishop.quests.bukkit.util.FormatUtils; import com.leonardobishop.quests.bukkit.util.Messages; @@ -29,8 +30,10 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.WeakHashMap; import java.util.concurrent.TimeUnit; public class NormalQuestController implements QuestController { @@ -39,6 +42,7 @@ public class NormalQuestController implements QuestController { private final BukkitQuestsConfig config; private final List autoStartQuestCache; + private final Map vaultRewardCache; public NormalQuestController(BukkitQuestsPlugin plugin) { this.plugin = plugin; @@ -49,6 +53,8 @@ public NormalQuestController(BukkitQuestsPlugin plugin) { if (quest.isAutoStartEnabled()) autoStartQuestCache.add(quest); } this.autoStartQuestCache = autoStartQuestCache; + + this.vaultRewardCache = new WeakHashMap<>(); } @Override @@ -235,10 +241,12 @@ public boolean completeQuestForPlayer(QPlayer qPlayer, Quest quest) { Bukkit.getPluginManager().callEvent(questFinishEvent); // PlayerFinishQuestEvent -- end plugin.getScheduler().doSync(() -> { - final double vaultReward = quest.getVaultReward(); - if (vaultReward > 0.0D) { - this.plugin.getVaultHook().depositPlayer(player, vaultReward); - } + final VaultReward vaultReward = this.vaultRewardCache.computeIfAbsent(quest, + k -> VaultReward.parse(this.plugin, k.getVaultReward()) + ); + + // Use cached reward to do not parse it every single time + vaultReward.give(player); for (String s : quest.getRewards()) { s = s.replace("{player}", player.getName()); diff --git a/common/src/main/java/com/leonardobishop/quests/common/quest/Quest.java b/common/src/main/java/com/leonardobishop/quests/common/quest/Quest.java index 3194b504..df3a1aaf 100644 --- a/common/src/main/java/com/leonardobishop/quests/common/quest/Quest.java +++ b/common/src/main/java/com/leonardobishop/quests/common/quest/Quest.java @@ -25,7 +25,7 @@ public class Quest implements Comparable { private List startCommands; private List cancelCommands; private List expiryCommands; - private double vaultReward; + private String vaultReward; private boolean repeatEnabled; private boolean cooldownEnabled; private int cooldown; @@ -210,9 +210,9 @@ public List getExpiryCommands() { * Get the Vault reward for this quest. * The Vault reward is an amount of Vault economy money to be given upon completing the quest. * - * @return double + * @return string */ - public double getVaultReward() { + public @Nullable String getVaultReward() { return this.vaultReward; } @@ -353,7 +353,7 @@ public static class Builder { private List startCommands = Collections.emptyList(); private List cancelCommands = Collections.emptyList(); private List expiryCommands = Collections.emptyList(); - private double vaultReward = 0.0D; + private String vaultReward = null; private boolean repeatEnabled = false; private boolean cooldownEnabled = false; private int cooldown = 0; @@ -417,7 +417,7 @@ public Builder withExpiryCommands(List expiryCommands) { return this; } - public Builder withVaultReward(double vaultReward) { + public Builder withVaultReward(String vaultReward) { this.vaultReward = vaultReward; return this; }