summaryrefslogtreecommitdiffstats
path: root/bukkit/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'bukkit/src/main')
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java218
-rw-r--r--bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/TaskUtils.java27
-rw-r--r--bukkit/src/main/resources/resources/bukkit/config.yml3
3 files changed, 172 insertions, 76 deletions
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java
index 67491687..e4cc2515 100644
--- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java
+++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/PlaceholderAPIEvaluateTaskType.java
@@ -5,6 +5,7 @@ import com.leonardobishop.quests.bukkit.scheduler.WrappedRunnable;
import com.leonardobishop.quests.bukkit.scheduler.WrappedTask;
import com.leonardobishop.quests.bukkit.tasktype.BukkitTaskType;
import com.leonardobishop.quests.bukkit.util.TaskUtils;
+import com.leonardobishop.quests.bukkit.util.constraint.TaskConstraintSet;
import com.leonardobishop.quests.common.config.ConfigProblem;
import com.leonardobishop.quests.common.player.QPlayer;
import com.leonardobishop.quests.common.player.questprogressfile.TaskProgress;
@@ -15,10 +16,13 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.Arrays;
+import java.util.WeakHashMap;
+import java.util.concurrent.CompletableFuture;
public final class PlaceholderAPIEvaluateTaskType extends BukkitTaskType {
private final BukkitQuestsPlugin plugin;
+ private final WeakHashMap<Task, Integer> refreshTicksMap = new WeakHashMap<>();
private WrappedTask poll;
public PlaceholderAPIEvaluateTaskType(BukkitQuestsPlugin plugin) {
@@ -48,95 +52,135 @@ public final class PlaceholderAPIEvaluateTaskType extends BukkitTaskType {
}
}
});
+ super.addConfigValidator(TaskUtils.useIntegerConfigValidator(this, "refresh-ticks"));
+ super.addConfigValidator(TaskUtils.useBooleanConfigValidator(this, "async"));
}
@Override
public void onReady() {
+ int refreshTicks = plugin.getConfig().getInt("options.placeholderapi-global-refresh-ticks", 30);
this.poll = new WrappedRunnable() {
@Override
public void run() {
for (Player player : Bukkit.getOnlinePlayers()) {
- QPlayer qPlayer = plugin.getPlayerManager().getPlayer(player.getUniqueId());
- if (qPlayer == null) {
+ handle(player);
+ }
+ }
+ }.runTaskTimer(plugin.getScheduler(), refreshTicks, refreshTicks);
+ }
+
+ private void handle(Player player) {
+ if (player.hasMetadata("NPC")) {
+ return;
+ }
+
+ QPlayer qPlayer = plugin.getPlayerManager().getPlayer(player.getUniqueId());
+ if (qPlayer == null) {
+ return;
+ }
+
+ for (TaskUtils.PendingTask pendingTask : TaskUtils.getApplicableTasks(player, qPlayer, this, TaskConstraintSet.ALL)) {
+ Quest quest = pendingTask.quest();
+ Task task = pendingTask.task();
+ TaskProgress taskProgress = pendingTask.taskProgress();
+
+ super.debug("Polling PAPI for player", quest.getId(), task.getId(), player.getUniqueId());
+
+ Integer refreshTicks = (Integer) task.getConfigValue("refresh-ticks");
+ if (refreshTicks != null) {
+ int currentTick = Bukkit.getCurrentTick();
+ Integer lastRefreshTicks = refreshTicksMap.get(task);
+
+ if (lastRefreshTicks != null) {
+ int ticksSinceLastRefresh = currentTick - lastRefreshTicks;
+
+ if (ticksSinceLastRefresh < refreshTicks) {
+ super.debug("Ticks since last refresh are lower than specified, continuing...", quest.getId(), task.getId(), player.getUniqueId());
continue;
}
+ }
- for (TaskUtils.PendingTask pendingTask : TaskUtils.getApplicableTasks(player, qPlayer, PlaceholderAPIEvaluateTaskType.this)) {
- Quest quest = pendingTask.quest();
- Task task = pendingTask.task();
- TaskProgress taskProgress = pendingTask.taskProgress();
+ refreshTicksMap.put(task, currentTick);
+ }
- PlaceholderAPIEvaluateTaskType.super.debug("Polling PAPI for player", quest.getId(), task.getId(), player.getUniqueId());
+ String placeholder = (String) task.getConfigValue("placeholder");
+ if (placeholder == null) {
+ continue;
+ }
- String placeholder = (String) task.getConfigValue("placeholder");
- String evaluates = String.valueOf(task.getConfigValue("evaluates"));
- String configOperator = (String) task.getConfigValue("operator");
- Operator operator = null;
- if (configOperator != null) {
- try {
- operator = Operator.valueOf(configOperator);
- } catch (IllegalArgumentException ignored) { }
- }
- if (placeholder != null && evaluates != null) {
- double numericEvaluates = 0;
- if (operator != null) {
- try {
- numericEvaluates = Double.parseDouble(evaluates);
- } catch (NumberFormatException ex) {
- PlaceholderAPIEvaluateTaskType.super.debug("Numeric operator was specified but configured string to evaluate to cannot be parsed into a double, continuing...", quest.getId(), task.getId(), player.getUniqueId());
- continue;
- }
- }
+ String evaluatesString = String.valueOf(task.getConfigValue("evaluates"));
+ if (evaluatesString == null) {
+ continue;
+ }
+ String operatorString = (String) task.getConfigValue("operator");
+ Operator operator;
+ if (operatorString != null) {
+ try {
+ operator = Operator.valueOf(operatorString);
+ } catch (IllegalArgumentException ignored) {
+ super.debug("Numeric operator was specified but cannot be parsed, continuing...", quest.getId(), task.getId(), player.getUniqueId());
+ continue;
+ }
+ } else {
+ operator = null;
+ }
+
+ super.debug("Operator = " + operator, quest.getId(), task.getId(), player.getUniqueId());
+
+ boolean async = TaskUtils.getConfigBoolean(task, "async", false);
+ CompletableFuture<String> future = evaluate(player, placeholder, async);
- String evaluated = PlaceholderAPI.setPlaceholders(player, placeholder);
- PlaceholderAPIEvaluateTaskType.super.debug("Evaluation = '" + evaluated + "'", quest.getId(), task.getId(), player.getUniqueId());
- if (operator == null && evaluated.equals(evaluates)) {
- PlaceholderAPIEvaluateTaskType.super.debug("Marking task as complete", quest.getId(), task.getId(), player.getUniqueId());
- taskProgress.setCompleted(true);
- } else if (operator != null) {
- double numericEvaluated;
- try {
- numericEvaluated = Double.parseDouble(evaluated);
- } catch (NumberFormatException ex) {
- PlaceholderAPIEvaluateTaskType.super.debug("Numeric operator was specified but evaluated string cannot be parsed into a double, continuing...", quest.getId(), task.getId(), player.getUniqueId());
- continue;
- }
- PlaceholderAPIEvaluateTaskType.super.debug("Operator = " + operator, quest.getId(), task.getId(), player.getUniqueId());
- taskProgress.setProgress(numericEvaluated);
- switch (operator) {
- case GREATER_THAN -> {
- if (numericEvaluated > numericEvaluates) {
- PlaceholderAPIEvaluateTaskType.super.debug("Marking task as complete", quest.getId(), task.getId(), player.getUniqueId());
- taskProgress.setCompleted(true);
- }
- }
- case LESS_THAN -> {
- if (numericEvaluated < numericEvaluates) {
- PlaceholderAPIEvaluateTaskType.super.debug("Marking task as complete", quest.getId(), task.getId(), player.getUniqueId());
- taskProgress.setCompleted(true);
- }
- }
- case GREATER_THAN_OR_EQUAL_TO -> {
- if (numericEvaluated >= numericEvaluates) {
- PlaceholderAPIEvaluateTaskType.super.debug("Marking task as complete", quest.getId(), task.getId(), player.getUniqueId());
- taskProgress.setCompleted(true);
- }
- }
- case LESS_THAN_OR_EQUAL_TO -> {
- if (numericEvaluated <= numericEvaluates) {
- PlaceholderAPIEvaluateTaskType.super.debug("Marking task as complete", quest.getId(), task.getId(), player.getUniqueId());
- taskProgress.setCompleted(true);
- }
- }
- }
+ future.thenAccept(evaluatedString -> {
+ super.debug("Evaluation = '" + evaluatedString + "'", quest.getId(), task.getId(), player.getUniqueId());
+
+ if (operator != null) {
+ double evaluates;
+ try {
+ evaluates = Double.parseDouble(evaluatesString);
+ } catch (NumberFormatException ignored) {
+ super.debug("Numeric operator was specified but configured string to evaluate to cannot be parsed into a double, continuing...", quest.getId(), task.getId(), player.getUniqueId());
+ return;
+ }
- }
- }
+ double evaluated;
+ try {
+ evaluated = Double.parseDouble(evaluatedString);
+ } catch (NumberFormatException ignored) {
+ super.debug("Numeric operator was specified but evaluated string to cannot be parsed into a double, continuing...", quest.getId(), task.getId(), player.getUniqueId());
+ return;
}
+
+ taskProgress.setProgress(evaluated);
+
+ if (operator.compare(evaluated, evaluates)) {
+ super.debug("Marking task as complete", quest.getId(), task.getId(), player.getUniqueId());
+ taskProgress.setCompleted(true);
+ }
+
+ TaskUtils.sendTrackAdvancement(player, quest, task, taskProgress, evaluates);
+ } else if (evaluatedString.equals(evaluatesString)) {
+ super.debug("Marking task as complete", quest.getId(), task.getId(), player.getUniqueId());
+ taskProgress.setCompleted(true);
}
- }
- }.runTaskTimer(plugin.getScheduler(), 30L, 30L);
+ });
+ }
+ }
+
+ private CompletableFuture<String> evaluate(Player player, String placeholder, boolean async) {
+ if (!async) {
+ String evaluated = PlaceholderAPI.setPlaceholders(player, placeholder);
+ return CompletableFuture.completedFuture(evaluated);
+ }
+
+ CompletableFuture<String> future = new CompletableFuture<>();
+
+ plugin.getScheduler().runTaskAsynchronously(() -> {
+ String evaluated = PlaceholderAPI.setPlaceholders(player, placeholder);
+ plugin.getScheduler().runTaskAtEntity(player, () -> future.complete(evaluated));
+ });
+
+ return future;
}
@Override
@@ -146,10 +190,32 @@ public final class PlaceholderAPIEvaluateTaskType extends BukkitTaskType {
}
}
- enum Operator {
- GREATER_THAN,
- LESS_THAN,
- GREATER_THAN_OR_EQUAL_TO,
- LESS_THAN_OR_EQUAL_TO;
+ private enum Operator {
+ GREATER_THAN {
+ @Override
+ public boolean compare(double evaluated, double evaluates) {
+ return evaluated > evaluates;
+ }
+ },
+ LESS_THAN {
+ @Override
+ public boolean compare(double evaluated, double evaluates) {
+ return evaluated < evaluates;
+ }
+ },
+ GREATER_THAN_OR_EQUAL_TO {
+ @Override
+ public boolean compare(double evaluated, double evaluates) {
+ return evaluated >= evaluates;
+ }
+ },
+ LESS_THAN_OR_EQUAL_TO {
+ @Override
+ public boolean compare(double evaluated, double evaluates) {
+ return evaluated <= evaluates;
+ }
+ };
+
+ public abstract boolean compare(double evaluated, double evaluates);
}
}
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/TaskUtils.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/TaskUtils.java
index 4fa0b702..fb284045 100644
--- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/TaskUtils.java
+++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/util/TaskUtils.java
@@ -538,6 +538,33 @@ public class TaskUtils {
/**
* Returns a config validator which checks if at least one value in the given
+ * paths is a long.
+ *
+ * @param paths a list of valid paths for task
+ * @return config validator
+ */
+ public static TaskType.ConfigValidator useLongConfigValidator(TaskType type, String... paths) {
+ return (config, problems) -> {
+ for (String path : paths) {
+ Object object = config.get(path);
+
+ if (object == null) {
+ continue;
+ }
+
+ try {
+ Long l = (Long) object;
+ } catch (ClassCastException ex) {
+ problems.add(new ConfigProblem(ConfigProblem.ConfigProblemType.ERROR,
+ "Expected a long for '" + path + "', but got '" + object + "' instead", null, path));
+ }
+ break;
+ }
+ };
+ }
+
+ /**
+ * Returns a config validator which checks if at least one value in the given
* paths is an integer.
*
* @param paths a list of valid paths for task
diff --git a/bukkit/src/main/resources/resources/bukkit/config.yml b/bukkit/src/main/resources/resources/bukkit/config.yml
index 32733079..c4d7df4b 100644
--- a/bukkit/src/main/resources/resources/bukkit/config.yml
+++ b/bukkit/src/main/resources/resources/bukkit/config.yml
@@ -121,6 +121,9 @@ options:
use-progress-as-fallback: true
# PlayerBlockTracker class to be used with the hook
playerblocktracker-class-name: "com.gestankbratwurst.playerblocktracker.PlayerBlockTracker"
+ # How frequently placeholderapi_evaluate task placeholders will be refreshed (def=30 - 1.5s)
+ # (multiply SECONDS by 20 to get the number of ticks)
+ placeholderapi-global-refresh-ticks: 30
# Verify quests exist when a player's data is loaded - inconsistencies may arise when
# players progress on specific quests and those quests are later removed. The problem is that their progress
# is still kept in the quest progress file, which may lead to issues such as players reaching a quest started