summaryrefslogtreecommitdiffstats
path: root/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/leonardobishop/quests/QuestCompleter.java62
-rw-r--r--src/main/java/com/leonardobishop/quests/Quests.java115
-rw-r--r--src/main/java/com/leonardobishop/quests/QuestsConfigLoader.java420
-rw-r--r--src/main/java/com/leonardobishop/quests/QuestsLogger.java40
-rw-r--r--src/main/java/com/leonardobishop/quests/api/QuestsPlaceholders.java440
-rw-r--r--src/main/java/com/leonardobishop/quests/blocktype/Block.java1
-rw-r--r--src/main/java/com/leonardobishop/quests/commands/CommandQuests.java250
-rw-r--r--src/main/java/com/leonardobishop/quests/events/EventInventory.java11
-rw-r--r--src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java13
-rw-r--r--src/main/java/com/leonardobishop/quests/events/EventPlayerLeave.java1
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetter.java (renamed from src/main/java/com/leonardobishop/quests/itemgetter/ItemGetter.java)13
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetterLatest.java (renamed from src/main/java/com/leonardobishop/quests/itemgetter/ItemGetterLatest.java)14
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetter_1_13.java (renamed from src/main/java/com/leonardobishop/quests/itemgetter/ItemGetter_1_13.java)14
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetter_Late_1_8.java (renamed from src/main/java/com/leonardobishop/quests/itemgetter/ItemGetter_Late_1_8.java)22
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/papi/IPlaceholderAPIHook.java14
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/papi/PlaceholderAPIHook.java29
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/title/Title.java (renamed from src/main/java/com/leonardobishop/quests/title/Title.java)2
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/title/Title_Bukkit.java (renamed from src/main/java/com/leonardobishop/quests/title/Title_Bukkit.java)2
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/title/Title_BukkitNoTimings.java (renamed from src/main/java/com/leonardobishop/quests/title/Title_BukkitNoTimings.java)2
-rw-r--r--src/main/java/com/leonardobishop/quests/hooks/title/Title_Other.java (renamed from src/main/java/com/leonardobishop/quests/title/Title_Other.java)2
-rw-r--r--src/main/java/com/leonardobishop/quests/obj/Messages.java2
-rw-r--r--src/main/java/com/leonardobishop/quests/obj/Options.java17
-rw-r--r--src/main/java/com/leonardobishop/quests/obj/misc/QItemStack.java17
-rw-r--r--src/main/java/com/leonardobishop/quests/obj/misc/QMenuCancel.java23
-rw-r--r--src/main/java/com/leonardobishop/quests/obj/misc/QMenuCategory.java38
-rw-r--r--src/main/java/com/leonardobishop/quests/obj/misc/QMenuDaily.java18
-rw-r--r--src/main/java/com/leonardobishop/quests/obj/misc/QMenuQuest.java38
-rw-r--r--src/main/java/com/leonardobishop/quests/player/QPlayer.java41
-rw-r--r--src/main/java/com/leonardobishop/quests/player/QPlayerManager.java46
-rw-r--r--src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgress.java29
-rw-r--r--src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java59
-rw-r--r--src/main/java/com/leonardobishop/quests/player/questprogressfile/TaskProgress.java18
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/Category.java24
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/Quest.java12
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/QuestManager.java5
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/Task.java9
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/ConfigValue.java8
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskType.java26
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskTypeManager.java6
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskUtils.java48
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BreedingTaskType.java10
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingTaskType.java9
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingCertainTaskType.java44
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingTaskType.java10
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CommandTaskType.java96
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DealDamageTaskType.java11
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DistancefromTaskType.java37
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/EnchantingTaskType.java10
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ExpEarnTaskType.java12
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FishingTaskType.java10
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/InventoryTaskType.java84
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/IridiumSkyblockValueType.java90
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MilkingTaskType.java10
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningCertainTaskType.java49
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningTaskType.java10
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingCertainTaskType.java21
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingTaskType.java11
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaceholderAPIEvaluateTaskType.java77
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlayerkillingTaskType.java13
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaytimeTaskType.java69
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PositionTaskType.java21
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ShearingTaskType.java11
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/TamingTaskType.java11
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/WalkingTaskType.java11
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/ASkyBlockLevelType.java (renamed from src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ASkyBlockLevelType.java)13
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/BentoBoxLevelTaskType.java (renamed from src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BentoBoxLevelTaskType.java)17
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/CitizensDeliverTaskType.java (renamed from src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensDeliverTaskType.java)42
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/CitizensInteractTaskType.java (renamed from src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensInteractTaskType.java)13
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/EssentialsBalanceTaskType.java100
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/EssentialsMoneyEarnTaskType.java83
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/IridiumSkyblockValueType.java91
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/MythicMobsKillingType.java (renamed from src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MythicMobsKillingType.java)13
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/PlaceholderAPIEvaluateTaskType.java159
-rw-r--r--src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/uSkyBlockLevelType.java (renamed from src/main/java/com/leonardobishop/quests/quests/tasktypes/types/uSkyBlockLevelType.java)14
-rw-r--r--src/main/java/com/leonardobishop/quests/updater/Updater.java6
75 files changed, 2386 insertions, 853 deletions
diff --git a/src/main/java/com/leonardobishop/quests/QuestCompleter.java b/src/main/java/com/leonardobishop/quests/QuestCompleter.java
index b783540c..97357126 100644
--- a/src/main/java/com/leonardobishop/quests/QuestCompleter.java
+++ b/src/main/java/com/leonardobishop/quests/QuestCompleter.java
@@ -6,11 +6,16 @@ import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
import com.leonardobishop.quests.quests.Quest;
import com.leonardobishop.quests.quests.Task;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
-import java.util.Map;
+import java.util.LinkedList;
+import java.util.Queue;
public class QuestCompleter implements Runnable {
+ private final Queue<QuestProgress> completionQueue = new LinkedList<>();
+ private final Queue<QuestProgressFile> fullCheckQueue = new LinkedList<>();
private final Quests plugin;
public QuestCompleter(Quests plugin) {
@@ -19,12 +24,34 @@ public class QuestCompleter implements Runnable {
@Override
public void run() {
- //TODO if it still runs like shit then maybe only process a few players per X ticks rather than the whole server in one go
- for (QPlayer qPlayer : plugin.getPlayerManager().getQPlayers()) {
- if (qPlayer.isOnlyDataLoaded()) {
- continue;
- }
+ this.processCompletionQueue();
+ this.processFullCheckQueue();
+ }
+
+ private void processCompletionQueue() {
+ QuestProgress questProgress = completionQueue.poll();
+ if (questProgress == null) return;
+
+ Player player = Bukkit.getPlayer(questProgress.getPlayer());
+ if (player != null && player.isOnline()) {
+ QPlayer qPlayer = plugin.getPlayerManager().getPlayer(player.getUniqueId());
QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
+ Quest quest = plugin.getQuestManager().getQuestById(questProgress.getQuestId());
+
+ if (!questProgressFile.hasStartedQuest(quest)) return;
+
+ if (checkComplete(quest, questProgress)) {
+ questProgressFile.completeQuest(quest);
+ }
+ }
+ }
+
+ private void processFullCheckQueue() {
+ QuestProgressFile questProgressFile = fullCheckQueue.poll();
+ if (questProgressFile == null) return;
+
+ Player player = Bukkit.getPlayer(questProgressFile.getPlayerUUID());
+ if (player != null && player.isOnline()) {
for (QuestProgress questProgress : questProgressFile.getAllQuestProgress()) {
Quest quest = plugin.getQuestManager().getQuestById(questProgress.getQuestId());
if (quest == null) continue;
@@ -44,4 +71,25 @@ public class QuestCompleter implements Runnable {
}
}
}
-} \ No newline at end of file
+
+ private boolean checkComplete(Quest quest, QuestProgress questProgress) {
+ boolean complete = true;
+ for (Task task : quest.getTasks()) {
+ TaskProgress taskProgress;
+ if ((taskProgress = questProgress.getTaskProgress(task.getId())) == null || !taskProgress.isCompleted()) {
+ complete = false;
+ break;
+ }
+ }
+
+ return complete;
+ }
+
+ public void queueSingular(QuestProgress questProgress) {
+ completionQueue.add(questProgress);
+ }
+
+ public void queueFullCheck(QuestProgressFile questProgressFile) {
+ fullCheckQueue.add(questProgressFile);
+ }
+}
diff --git a/src/main/java/com/leonardobishop/quests/Quests.java b/src/main/java/com/leonardobishop/quests/Quests.java
index c0ccf7db..5272e9ac 100644
--- a/src/main/java/com/leonardobishop/quests/Quests.java
+++ b/src/main/java/com/leonardobishop/quests/Quests.java
@@ -1,15 +1,20 @@
package com.leonardobishop.quests;
-import com.leonardobishop.quests.api.QuestsPlaceholders;
import com.leonardobishop.quests.bstats.Metrics;
import com.leonardobishop.quests.commands.CommandQuests;
import com.leonardobishop.quests.events.EventInventory;
import com.leonardobishop.quests.events.EventPlayerJoin;
import com.leonardobishop.quests.events.EventPlayerLeave;
-import com.leonardobishop.quests.itemgetter.ItemGetter;
-import com.leonardobishop.quests.itemgetter.ItemGetterLatest;
-import com.leonardobishop.quests.itemgetter.ItemGetter_1_13;
-import com.leonardobishop.quests.itemgetter.ItemGetter_Late_1_8;
+import com.leonardobishop.quests.hooks.itemgetter.ItemGetter;
+import com.leonardobishop.quests.hooks.itemgetter.ItemGetterLatest;
+import com.leonardobishop.quests.hooks.itemgetter.ItemGetter_1_13;
+import com.leonardobishop.quests.hooks.itemgetter.ItemGetter_Late_1_8;
+import com.leonardobishop.quests.hooks.papi.IPlaceholderAPIHook;
+import com.leonardobishop.quests.hooks.papi.PlaceholderAPIHook;
+import com.leonardobishop.quests.hooks.title.Title;
+import com.leonardobishop.quests.hooks.title.Title_Bukkit;
+import com.leonardobishop.quests.hooks.title.Title_BukkitNoTimings;
+import com.leonardobishop.quests.hooks.title.Title_Other;
import com.leonardobishop.quests.obj.Messages;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.QPlayerManager;
@@ -17,10 +22,7 @@ import com.leonardobishop.quests.quests.QuestManager;
import com.leonardobishop.quests.quests.tasktypes.TaskType;
import com.leonardobishop.quests.quests.tasktypes.TaskTypeManager;
import com.leonardobishop.quests.quests.tasktypes.types.*;
-import com.leonardobishop.quests.title.Title;
-import com.leonardobishop.quests.title.Title_Bukkit;
-import com.leonardobishop.quests.title.Title_BukkitNoTimings;
-import com.leonardobishop.quests.title.Title_Other;
+import com.leonardobishop.quests.quests.tasktypes.types.dependent.*;
import com.leonardobishop.quests.updater.Updater;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
@@ -31,7 +33,6 @@ import org.bukkit.scheduler.BukkitTask;
import java.io.*;
import java.util.ArrayList;
-import java.util.Map;
public class Quests extends JavaPlugin {
@@ -42,12 +43,14 @@ public class Quests extends JavaPlugin {
private static Updater updater;
private static Title title;
private ItemGetter itemGetter;
+ private QuestCompleter questCompleter;
private QuestsConfigLoader questsConfigLoader;
private QuestsLogger questsLogger;
+ private IPlaceholderAPIHook placeholderAPIHook;
private boolean brokenConfig = false;
- private BukkitTask questCompleterTask;
private BukkitTask questAutosaveTask;
+ private BukkitTask questQueuePollTask;
public static Quests get() {
return (Quests) Bukkit.getPluginManager().getPlugin("Quests");
@@ -98,7 +101,8 @@ public class Quests extends JavaPlugin {
@Override
public void onEnable() {
- questsLogger = new QuestsLogger(this, LoggingLevel.INFO);
+ questsLogger = new QuestsLogger(this, QuestsLogger.LoggingLevel.INFO);
+ questCompleter = new QuestCompleter(this);
taskTypeManager = new TaskTypeManager(this);
questManager = new QuestManager(this);
@@ -112,10 +116,6 @@ public class Quests extends JavaPlugin {
Bukkit.getPluginManager().registerEvents(new EventInventory(this), this);
Bukkit.getPluginManager().registerEvents(new EventPlayerLeave(this), this);
- if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
- new QuestsPlaceholders(this).register();
- }
-
Metrics metrics = new Metrics(this);
if (metrics.isEnabled()) {
this.getQuestsLogger().info("Metrics started. This can be disabled at /plugins/bStats/config.yml.");
@@ -146,6 +146,8 @@ public class Quests extends JavaPlugin {
taskTypeManager.registerTaskType(new EnchantingTaskType());
taskTypeManager.registerTaskType(new DealDamageTaskType());
taskTypeManager.registerTaskType(new PermissionTaskType());
+ taskTypeManager.registerTaskType(new DistancefromTaskType());
+ taskTypeManager.registerTaskType(new CommandTaskType());
// TODO: FIX
// taskTypeManager.registerTaskType(new BrewingCertainTaskType());
if (Bukkit.getPluginManager().isPluginEnabled("ASkyBlock")) {
@@ -170,27 +172,37 @@ public class Quests extends JavaPlugin {
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
taskTypeManager.registerTaskType(new PlaceholderAPIEvaluateTaskType());
}
+ if (Bukkit.getPluginManager().isPluginEnabled("Essentials")) {
+ taskTypeManager.registerTaskType(new EssentialsMoneyEarnTaskType());
+ taskTypeManager.registerTaskType(new EssentialsBalanceTaskType());
+ }
taskTypeManager.closeRegistrations();
reloadQuests();
- if (!questsConfigLoader.getBrokenFiles().isEmpty()) {
- this.getQuestsLogger().severe("Quests has failed to load the following files:");
- for (Map.Entry<String, QuestsConfigLoader.ConfigLoadError> entry : questsConfigLoader.getBrokenFiles().entrySet()) {
- this.getQuestsLogger().severe(" - " + entry.getKey() + ": " + entry.getValue().getMessage());
- }
- }
+// if (!questsConfigLoader.getBrokenFiles().isEmpty()) {
+// this.getQuestsLogger().severe("Quests has failed to load the following files:");
+// for (Map.Entry<String, QuestsConfigLoader.ConfigLoadError> entry : questsConfigLoader.getBrokenFiles().entrySet()) {
+// this.getQuestsLogger().severe(" - " + entry.getKey() + ": " + entry.getValue().getMessage());
+// }
+// }
for (Player player : Bukkit.getOnlinePlayers()) {
- qPlayerManager.loadPlayer(player.getUniqueId(), false);
+ qPlayerManager.loadPlayer(player.getUniqueId());
}
});
+ if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
+ this.placeholderAPIHook = new PlaceholderAPIHook();
+ this.placeholderAPIHook.registerExpansion(this);
+ }
+
// this intentionally should not be documented
boolean ignoreUpdates = false;
try {
ignoreUpdates = new File(this.getDataFolder() + File.separator + "stfuQuestsUpdate").exists();
} catch (Throwable ignored) { }
+
updater = new Updater(this);
if (!ignoreUpdates) {
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
@@ -199,6 +211,10 @@ public class Quests extends JavaPlugin {
}
}
+ public IPlaceholderAPIHook getPlaceholderAPIHook() {
+ return placeholderAPIHook;
+ }
+
@Override
public void onDisable() {
for (TaskType taskType : getTaskTypeManager().getTaskTypes()) {
@@ -207,11 +223,9 @@ public class Quests extends JavaPlugin {
} catch (Exception ignored) { }
}
for (QPlayer qPlayer : qPlayerManager.getQPlayers()) {
- if (qPlayer.isOnlyDataLoaded()) {
- continue;
- }
qPlayer.getQuestProgressFile().saveToDisk(true);
}
+ if (placeholderAPIHook != null) placeholderAPIHook.unregisterExpansion();
}
public void reloadQuests() {
@@ -222,36 +236,52 @@ public class Quests extends JavaPlugin {
questsConfigLoader.loadConfig();
long autocompleteInterval = 12000;
- long completerPollInterval = 100;
if (!isBrokenConfig()) {
autocompleteInterval = this.getConfig().getLong("options.performance-tweaking.quest-autocomplete-interval", 12000);
- completerPollInterval = this.getConfig().getLong("options.performance-tweaking.quest-completer-poll-interval", 100);
}
+ boolean autosaveTaskCancelled = true;
if (questAutosaveTask != null) {
try {
questAutosaveTask.cancel();
- } catch (Exception ignored) { }
+ } catch (Exception ex) {
+ questsLogger.debug("Cannot cancel and restart quest autosave task");
+ autosaveTaskCancelled = false;
+ }
}
- questAutosaveTask = Bukkit.getScheduler().runTaskTimer(this, () -> {
- for (QPlayer qPlayer : qPlayerManager.getQPlayers()) {
- if (qPlayer.isOnlyDataLoaded()) {
- continue;
+ if (autosaveTaskCancelled) {
+ questAutosaveTask = Bukkit.getScheduler().runTaskTimer(this, () -> {
+ for (QPlayer qPlayer : qPlayerManager.getQPlayers()) {
+ qPlayer.getQuestProgressFile().saveToDisk(false);
}
- qPlayer.getQuestProgressFile().saveToDisk(false);
- }
- }, autocompleteInterval, autocompleteInterval);
- if (questCompleterTask != null) {
+ }, autocompleteInterval, autocompleteInterval);
+ }
+
+ boolean queuePollTaskCancelled = true;
+ long queueExecuteInterval = 1;
+ if (!isBrokenConfig()) {
+ queueExecuteInterval = this.getConfig().getLong("options.performance-tweaking.quest-queue-executor-interval", 1);
+ }
+ if (questQueuePollTask != null) {
try {
- questCompleterTask.cancel();
- } catch (Exception ignored) { }
+ questQueuePollTask.cancel();
+ } catch (Exception ex) {
+ questsLogger.debug("Cannot cancel and restart quest autosave task");
+ queuePollTaskCancelled = false;
+ }
+ }
+ if (queuePollTaskCancelled) {
+ questQueuePollTask = Bukkit.getScheduler().runTaskTimer(this, questCompleter, queueExecuteInterval, queueExecuteInterval);
}
- questCompleterTask = Bukkit.getScheduler().runTaskTimer(this, new QuestCompleter(this), 20, completerPollInterval);
}
public ItemStack getItemStack(String path, ConfigurationSection config, ItemGetter.Filter... excludes) {
return itemGetter.getItem(path, config, this, excludes);
}
+ public ItemGetter getItemGetter() {
+ return itemGetter;
+ }
+
private void setupVersionSpecific() {
String version;
try {
@@ -330,6 +360,7 @@ public class Quests extends JavaPlugin {
examples.add("example4.yml");
examples.add("example5.yml");
examples.add("example6.yml");
+ examples.add("example7.yml");
examples.add("README.txt");
for (String name : examples) {
@@ -356,6 +387,10 @@ public class Quests extends JavaPlugin {
}
}
+ public QuestCompleter getQuestCompleter() {
+ return questCompleter;
+ }
+
public QuestsLogger getQuestsLogger() {
return questsLogger;
}
diff --git a/src/main/java/com/leonardobishop/quests/QuestsConfigLoader.java b/src/main/java/com/leonardobishop/quests/QuestsConfigLoader.java
index 460b75d2..b6517e5e 100644
--- a/src/main/java/com/leonardobishop/quests/QuestsConfigLoader.java
+++ b/src/main/java/com/leonardobishop/quests/QuestsConfigLoader.java
@@ -1,11 +1,11 @@
package com.leonardobishop.quests;
-import com.leonardobishop.quests.itemgetter.ItemGetter;
+import com.leonardobishop.quests.hooks.itemgetter.ItemGetter;
+import com.leonardobishop.quests.obj.Options;
import com.leonardobishop.quests.obj.misc.QItemStack;
import com.leonardobishop.quests.quests.Category;
import com.leonardobishop.quests.quests.Quest;
import com.leonardobishop.quests.quests.Task;
-import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
import com.leonardobishop.quests.quests.tasktypes.TaskType;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
@@ -18,15 +18,15 @@ import java.io.IOException;
import java.net.URI;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class QuestsConfigLoader {
- private final Map<String, ConfigLoadError> brokenFiles = new HashMap<>();
+ private final Map<String, List<ConfigProblem>> filesWithProblems = new HashMap<>();
private final Quests plugin;
+ private int problemsCount;
public QuestsConfigLoader(Quests plugin) {
this.plugin = plugin;
@@ -37,7 +37,7 @@ public class QuestsConfigLoader {
*/
public void loadConfig() {
plugin.reloadConfig();
- brokenFiles.clear();
+ filesWithProblems.clear();
plugin.setBrokenConfig(false);
// test CONFIG file integrity
@@ -45,154 +45,237 @@ public class QuestsConfigLoader {
YamlConfiguration config = new YamlConfiguration();
config.load(new File(plugin.getDataFolder() + File.separator + "config.yml"));
} catch (Exception ex) {
- brokenFiles.put("<MAIN CONFIG> config.yml", new ConfigLoadError(ConfigLoadErrorType.MALFORMED_YAML));
+ filesWithProblems.put("<MAIN CONFIG> config.yml", Collections.singletonList(new ConfigProblem(ConfigProblemType.ERROR, ConfigProblemDescriptions.MALFORMED_YAML.getDescription())));
plugin.setBrokenConfig(true);
- return;
}
- for (String id : plugin.getConfig().getConfigurationSection("categories").getKeys(false)) {
- ItemStack displayItem = plugin.getItemStack("categories." + id + ".display", plugin.getConfig());
- boolean permissionRequired = plugin.getConfig().getBoolean("categories." + id + ".permission-required", false);
+ if (!plugin.isBrokenConfig()) {
+ for (String id : plugin.getConfig().getConfigurationSection("categories").getKeys(false)) {
+ ItemStack displayItem = plugin.getItemStack("categories." + id + ".display", plugin.getConfig());
+ boolean permissionRequired = plugin.getConfig().getBoolean("categories." + id + ".permission-required", false);
- Category category = new Category(id, displayItem, permissionRequired);
- plugin.getQuestManager().registerCategory(category);
- }
- plugin.getQuestsLogger().setServerLoggingLevel(LoggingLevel.fromNumber(plugin.getConfig().getInt("options.verbose-logging-level", 2)));
+ Category category = new Category(id, displayItem, permissionRequired);
+ plugin.getQuestManager().registerCategory(category);
+ }
+ plugin.getQuestsLogger().setServerLoggingLevel(QuestsLogger.LoggingLevel.fromNumber(plugin.getConfig().getInt("options.verbose-logging-level", 2)));
- FileVisitor<Path> fileVisitor = new SimpleFileVisitor<Path>() {
- final URI questsRoot = Paths.get(plugin.getDataFolder() + File.separator + "quests").toUri();
+ HashMap<String, Quest> pathToQuest = new HashMap<>();
- @Override
- public FileVisitResult visitFile(Path path, BasicFileAttributes attributes) {
- File questFile = new File(path.toUri());
- URI relativeLocation = questsRoot.relativize(path.toUri());
+ FileVisitor<Path> fileVisitor = new SimpleFileVisitor<Path>() {
+ final URI questsRoot = Paths.get(plugin.getDataFolder() + File.separator + "quests").toUri();
- if (!questFile.getName().toLowerCase().endsWith(".yml")) return FileVisitResult.CONTINUE;
+ @Override
+ public FileVisitResult visitFile(Path path, BasicFileAttributes attributes) {
+ File questFile = new File(path.toUri());
+ URI relativeLocation = questsRoot.relativize(path.toUri());
- YamlConfiguration config = new YamlConfiguration();
- // test QUEST file integrity
- try {
- config.load(questFile);
- } catch (Exception ex) {
- brokenFiles.put(relativeLocation.getPath(), new ConfigLoadError(ConfigLoadErrorType.MALFORMED_YAML));
- return FileVisitResult.CONTINUE;
- }
+ if (!questFile.getName().toLowerCase().endsWith(".yml")) return FileVisitResult.CONTINUE;
- String id = questFile.getName().replace(".yml", "");
+ YamlConfiguration config = new YamlConfiguration();
+ // test QUEST file integrity
+ try {
+ config.load(questFile);
+ } catch (Exception ex) {
+ filesWithProblems.put(relativeLocation.getPath(), Collections.singletonList(new ConfigProblem(ConfigProblemType.ERROR, ConfigProblemDescriptions.MALFORMED_YAML.getDescription())));
+ return FileVisitResult.CONTINUE;
+ }
- if (!StringUtils.isAlphanumeric(id)) {
- brokenFiles.put(relativeLocation.getPath(), new ConfigLoadError(ConfigLoadErrorType.INVALID_QUEST_ID));
- return FileVisitResult.CONTINUE;
- }
+ String id = questFile.getName().replace(".yml", "");
+
+ List<ConfigProblem> configProblems = new ArrayList<>();
+
+ if (!StringUtils.isAlphanumeric(id)) {
+ configProblems.add(new ConfigProblem(ConfigProblemType.ERROR, ConfigProblemDescriptions.INVALID_QUEST_ID.getDescription(id)));
+ }
+
+ // CHECK EVERYTHING WRONG WITH THE QUEST FILE BEFORE ACTUALLY LOADING THE QUEST
+
+ if (!config.isConfigurationSection("tasks")) {
+ configProblems.add(new ConfigProblem(ConfigProblemType.ERROR, ConfigProblemDescriptions.NO_TASKS.getDescription(), "tasks"));
+ } else { //continue
+ int validTasks = 0;
+ for (String taskId : config.getConfigurationSection("tasks").getKeys(false)) {
+ boolean isValid = true;
+ String taskRoot = "tasks." + taskId;
+ String taskType = config.getString(taskRoot + ".type");
+
+ if (!config.isConfigurationSection(taskRoot)) {
+ configProblems.add(new ConfigProblem(ConfigProblemType.WARNING, ConfigProblemDescriptions.TASK_MALFORMED_NOT_SECTION.getDescription(taskId), taskRoot));
+ continue;
+ }
+
+ if (taskType == null) {
+ configProblems.add(new ConfigProblem(ConfigProblemType.WARNING, ConfigProblemDescriptions.NO_TASK_TYPE.getDescription(), taskRoot));
+ continue;
+ }
+
+ // check the tasks
+ TaskType t = plugin.getTaskTypeManager().getTaskType(taskType);
+ if (t != null) {
+ HashMap<String, Object> configValues = new HashMap<>();
+ for (String key : config.getConfigurationSection(taskRoot).getKeys(false)) {
+ configValues.put(key, config.get(taskRoot + "." + key));
+ }
+
+ configProblems.addAll(t.detectProblemsInConfig(taskRoot, configValues));
+ } else {
+ configProblems.add(new ConfigProblem(ConfigProblemType.WARNING, ConfigProblemDescriptions.UNKNOWN_TASK_TYPE.getDescription(taskType), taskRoot));
+ isValid = false;
+ }
+
+ if (isValid) {
+ validTasks++;
+ }
+ }
+ if (validTasks == 0) {
+ configProblems.add(new ConfigProblem(ConfigProblemType.ERROR, ConfigProblemDescriptions.NO_TASKS.getDescription(), "tasks"));
+ }
+ }
- // CHECK EVERYTHING WRONG WITH THE QUEST FILE BEFORE ACTUALLY LOADING THE QUEST
+ boolean error = false;
+ for (ConfigProblem problem : configProblems) {
+ if (problem.getType() == ConfigProblemType.ERROR) {
+ error = true;
+ }
+ }
- List<String> questErrors = new ArrayList<>();
- List<String> taskErrors = new ArrayList<>();
+ // END OF THE CHECKING
+
+ QItemStack displayItem = getQItemStack("display", config);
+ List<String> rewards = config.getStringList("rewards");
+ List<String> requirements = config.getStringList("options.requires");
+ List<String> rewardString = config.getStringList("rewardstring");
+ List<String> startString = config.getStringList("startstring");
+ boolean repeatable = config.getBoolean("options.repeatable", false);
+ boolean cooldown = config.getBoolean("options.cooldown.enabled", false);
+ boolean permissionRequired = config.getBoolean("options.permission-required", false);
+ int cooldownTime = config.getInt("options.cooldown.time", 10);
+ int sortOrder = config.getInt("options.sort-order", 1);
+ String category = config.getString("options.category");
+
+ if (category == null) category = "";
+
+ Quest quest;
+ if (category.equals("")) {
+ quest = new Quest(id, displayItem, rewards, requirements, repeatable, cooldown, cooldownTime, permissionRequired, rewardString, startString, sortOrder);
+ } else {
+ quest = new Quest(id, displayItem, rewards, requirements, repeatable, cooldown, cooldownTime, permissionRequired, rewardString, startString, category, sortOrder);
+ Category c = plugin.getQuestManager().getCategoryById(category);
+ if (c != null) {
+ c.registerQuestId(id);
+ } else {
+ configProblems.add(new ConfigProblem(ConfigProblemType.WARNING, ConfigProblemDescriptions.UNKNOWN_CATEGORY.getDescription(category), "options.category"));
+ }
+ }
- if (!config.isConfigurationSection("tasks")) {
- questErrors.add("'tasks' section not defined");
- } else { //continue
for (String taskId : config.getConfigurationSection("tasks").getKeys(false)) {
String taskRoot = "tasks." + taskId;
String taskType = config.getString(taskRoot + ".type");
- if (!config.isConfigurationSection(taskRoot)) {
- questErrors.add("task '" + taskId + "' cannot be read (has no children)");
- continue;
+ Task task = new Task(taskId, taskType);
+
+ for (String key : config.getConfigurationSection(taskRoot).getKeys(false)) {
+ task.addConfigValue(key, config.get(taskRoot + "." + key));
}
- // check the tasks
- TaskType t = plugin.getTaskTypeManager().getTaskType(taskType);
- if (t != null) {
- List<String> missingFields = new ArrayList<>();
- for (ConfigValue cv : t.getCreatorConfigValues()) {
- if (cv.isRequired() && config.get(taskRoot + "." + cv.getKey()) == null)
- missingFields.add(cv.getKey());
+ quest.registerTask(task);
+ }
+
+ Pattern pattern = Pattern.compile("\\{([^}]+)}");
+
+ for (String line : displayItem.getLoreNormal()) {
+ Matcher matcher = pattern.matcher(line);
+ while (matcher.find()) {
+ String[] parts = matcher.group(1).split(":");
+ boolean match = false;
+ for (Task t : quest.getTasks()) {
+ if (t.getId().equals(parts[0])) {
+ match = true;
+ break;
+ }
}
- if (!missingFields.isEmpty())
- taskErrors.add("task '" + taskId + "': '" + t.getType() + "' missing required field(s) '" + String.join(", ", missingFields) + "'");
+ if (!match)
+ configProblems.add(new ConfigProblem(ConfigProblemType.WARNING,
+ ConfigProblemDescriptions.UNKNOWN_TASK_REFERENCE.getDescription(parts[0]), "display.lore-normal"));
+ }
+ }
+ for (String line : displayItem.getLoreStarted()) {
+ Matcher matcher = pattern.matcher(line);
+ while (matcher.find()) {
+ String[] parts = matcher.group(1).split(":");
+ boolean match = false;
+ for (Task t : quest.getTasks()) {
+ if (t.getId().equals(parts[0])) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ configProblems.add(new ConfigProblem(ConfigProblemType.WARNING,
+ ConfigProblemDescriptions.UNKNOWN_TASK_REFERENCE.getDescription(parts[0]), "display.lore-started"));
}
}
- }
- if (!questErrors.isEmpty()) { //if the file quest is not okay, do not load the quest
- brokenFiles.put(relativeLocation.getPath(), new ConfigLoadError(ConfigLoadErrorType.MALFORMED_QUEST, String.join("; ", questErrors)));
- return FileVisitResult.CONTINUE; //next quest please!
- } else if (!taskErrors.isEmpty()) { // likewise with tasks
- brokenFiles.put(relativeLocation.getPath(), new ConfigLoadError(ConfigLoadErrorType.MALFORMED_TASK, String.join("; ", taskErrors)));
+ pathToQuest.put(relativeLocation.getPath(), quest);
+ if (!configProblems.isEmpty()) {
+ filesWithProblems.put(relativeLocation.getPath(), configProblems);
+ }
+ if (!error && !Options.ERROR_CHECKING_OVERRIDE.getBooleanValue(false)) {
+ if (plugin.getConfig().getBoolean("options.show-quest-registrations")) {
+ plugin.getQuestsLogger().info("Registering quest " + quest.getId() + " with " + quest.getTasks().size() + " tasks.");
+ }
+ plugin.getQuestManager().registerQuest(quest);
+ plugin.getTaskTypeManager().registerQuestTasksWithTaskTypes(quest);
+ }
return FileVisitResult.CONTINUE;
}
+ };
- // END OF THE CHECKING
-
- QItemStack displayItem = getQItemStack("display", config);
- List<String> rewards = config.getStringList("rewards");
- List<String> requirements = config.getStringList("options.requires");
- List<String> rewardString = config.getStringList("rewardstring");
- List<String> startString = config.getStringList("startstring");
- boolean repeatable = config.getBoolean("options.repeatable", false);
- boolean cooldown = config.getBoolean("options.cooldown.enabled", false);
- boolean permissionRequired = config.getBoolean("options.permission-required", false);
- int cooldownTime = config.getInt("options.cooldown.time", 10);
- int sortOrder = config.getInt("options.sort-order", 1);
- String category = config.getString("options.category");
-
- if (category == null) category = "";
+ try {
+ Files.walkFileTree(Paths.get(plugin.getDataFolder() + File.separator + "quests"), fileVisitor);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
- Quest quest;
- if (category.equals("")) {
- quest = new Quest(id, displayItem, rewards, requirements, repeatable, cooldown, cooldownTime, permissionRequired, rewardString, startString, sortOrder);
- } else {
- quest = new Quest(id, displayItem, rewards, requirements, repeatable, cooldown, cooldownTime, permissionRequired, rewardString, startString, category, sortOrder);
- Category c = plugin.getQuestManager().getCategoryById(category);
- if (c != null) {
- c.registerQuestId(id);
+ // post-load checks
+ for (Map.Entry<String, Quest> loadedQuest : pathToQuest.entrySet()) {
+ List<ConfigProblem> configProblems = new ArrayList<>();
+ for (String req : loadedQuest.getValue().getRequirements()) {
+ if (plugin.getQuestManager().getQuestById(req) == null) {
+ configProblems.add(new ConfigProblem(ConfigProblemType.WARNING, ConfigProblemDescriptions.UNKNOWN_REQUIREMENT.getDescription(req), "options.requires"));
}
}
- for (String taskId : config.getConfigurationSection("tasks").getKeys(false)) {
- String taskRoot = "tasks." + taskId;
- String taskType = config.getString(taskRoot + ".type");
-
- Task task = new Task(taskId, taskType);
-
- for (String key : config.getConfigurationSection(taskRoot).getKeys(false)) {
- task.addConfigValue(key, config.get(taskRoot + "." + key));
+ if (!configProblems.isEmpty()) {
+ if (filesWithProblems.containsKey(loadedQuest.getKey())) {
+ filesWithProblems.get(loadedQuest.getKey()).addAll(configProblems);
+ } else {
+ filesWithProblems.put(loadedQuest.getKey(), configProblems);
}
-
- quest.registerTask(task);
}
+ }
- if (plugin.getConfig().getBoolean("options.show-quest-registrations")) {
- plugin.getQuestsLogger().info("Registering quest " + quest.getId() + " with " + quest.getTasks().size() + " tasks.");
+ for (TaskType taskType : plugin.getTaskTypeManager().getTaskTypes()) {
+ try {
+ taskType.onReady();
+ } catch (Exception e) {
+ e.printStackTrace();
}
- plugin.getQuestManager().registerQuest(quest);
- plugin.getTaskTypeManager().registerQuestTasksWithTaskTypes(quest);
- return FileVisitResult.CONTINUE;
}
- };
-
- try {
- Files.walkFileTree(Paths.get(plugin.getDataFolder() + File.separator + "quests"), fileVisitor);
- } catch (IOException e) {
- e.printStackTrace();
}
- for (TaskType taskType : plugin.getTaskTypeManager().getTaskTypes()) {
- try {
- taskType.onReady();
- } catch (Exception ignored) { }
+ problemsCount = 0;
+ for (List<QuestsConfigLoader.ConfigProblem> problemList : plugin.getQuestsConfigLoader().getFilesWithProblems().values()) {
+ problemsCount = problemsCount + problemList.size();
}
}
- /**
- * Gets recent file errors during load.
- *
- * @return Errors during load, Map<String, ConfigLoadError> of file name and error
- */
- public Map<String, ConfigLoadError> getBrokenFiles() {
- return brokenFiles;
+ public Map<String, List<ConfigProblem>> getFilesWithProblems() {
+ return filesWithProblems;
+ }
+
+ public int getProblemsCount() {
+ return problemsCount;
}
private QItemStack getQItemStack(String path, FileConfiguration config) {
@@ -218,38 +301,107 @@ public class QuestsConfigLoader {
ItemStack is = plugin.getItemStack(path, config,
ItemGetter.Filter.DISPLAY_NAME, ItemGetter.Filter.LORE, ItemGetter.Filter.ENCHANTMENTS, ItemGetter.Filter.ITEM_FLAGS);
- return new QItemStack(name, loreNormal, loreStarted, is);
+ return new QItemStack(plugin, name, loreNormal, loreStarted, is);
+ }
+
+ public enum ConfigProblemDescriptions {
+
+ MALFORMED_YAML("Malformed YAML file, cannot read config"),
+ INVALID_QUEST_ID("ID '%s' is invalid, must be alphanumeric, unique and with no spaces"),
+ NO_TASKS("Quest contains no valid tasks"),
+ NO_TASK_TYPE("Task type not specified"),
+ UNKNOWN_TASK_TYPE("Task type '%s' does not exist"),
+ NO_DISPLAY_NAME("No name specified"),
+ NO_DISPLAY_MATERIAL("No material specified"),
+ UNKNOWN_MATERIAL("Material '%s' does not exist"),
+ UNKNOWN_ENTITY_TYPE("Entity type '%s' does not exist"),
+ TASK_MALFORMED_NOT_SECTION("Task '%s' is not a configuration section (has no fields)"),
+ TASK_MISSING_FIELD("Required field '%s' is missing for task type '%s'"),
+ UNKNOWN_TASK_REFERENCE("Attempt to reference unknown task '%s'"),
+ UNKNOWN_CATEGORY("Category '%s' does not exist"),
+ UNKNOWN_REQUIREMENT("Quest requirement '%s' does not exist");
+
+ private final String description;
+
+ ConfigProblemDescriptions(String description) {
+ this.description = description;
+ }
+
+ @Override
+ public String toString() {
+ return getDescription();
+ }
+
+ public String getDescription(String... format) {
+ return String.format(description, (Object[]) format);
+ }
}
- public enum ConfigLoadErrorType {
+ public enum ConfigProblemType {
- MALFORMED_YAML("Malformed YAML"),
- INVALID_QUEST_ID("Invalid quest ID (must be alphanumeric)"),
- MALFORMED_QUEST("Quest file is not configured properly: %s"),
- MALFORMED_TASK("Tasks are not configured properly: %s");
+ ERROR("Error", "E", ChatColor.RED, 1),
+ WARNING("Warning", "W", ChatColor.YELLOW, 2);
- private String message;
+ private final String title;
+ private final String shortened;
+ private final ChatColor color;
+ private final int priority;
- ConfigLoadErrorType(String message) {
- this.message = message;
+ ConfigProblemType(String title, String shortened, ChatColor color, int priority) {
+ this.title = title;
+ this.shortened = shortened;
+ this.color = color;
+ this.priority = priority;
}
- public String getMessage() {
- return message;
+ public String getTitle() {
+ return title;
}
+
+ public String getShortened() {
+ return shortened;
+ }
+
+ public ChatColor getColor() {
+ return color;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
}
- public class ConfigLoadError {
- private ConfigLoadErrorType type;
- private String[] extraInfo;
+ public static class ConfigProblem {
+
+ private final ConfigProblemType type;
+ private final String description;
+ private final String location;
+
+ public ConfigProblem(ConfigProblemType type, String description, String location) {
+ this.type = type;
+ this.description = description == null ? "?" : description;
+ ;
+ this.location = location == null ? "?" : location;
+ }
- public ConfigLoadError(ConfigLoadErrorType type, String... extraInfo) {
+ public ConfigProblem(ConfigProblemType type, String description) {
this.type = type;
- this.extraInfo = extraInfo;
+ this.description = description == null ? "?" : description;
+ ;
+ this.location = "?";
+ }
+
+ public ConfigProblemType getType() {
+ return type;
+ }
+
+ public String getDescription() {
+ return description;
}
- public String getMessage() {
- return String.format(type.getMessage(), (Object[]) extraInfo);
+ public String getLocation() {
+ return location;
}
}
}
diff --git a/src/main/java/com/leonardobishop/quests/QuestsLogger.java b/src/main/java/com/leonardobishop/quests/QuestsLogger.java
index 212592c2..895b03dd 100644
--- a/src/main/java/com/leonardobishop/quests/QuestsLogger.java
+++ b/src/main/java/com/leonardobishop/quests/QuestsLogger.java
@@ -2,7 +2,7 @@ package com.leonardobishop.quests;
public class QuestsLogger {
- private Quests plugin;
+ private final Quests plugin;
private LoggingLevel serverLoggingLevel;
public QuestsLogger(Quests plugin, LoggingLevel serverLoggingLevel) {
@@ -53,29 +53,31 @@ public class QuestsLogger {
public void severe(String str) {
log(str, LoggingLevel.ERROR);
}
-}
-enum LoggingLevel {
- ERROR(0),
- WARNING(1),
- INFO(2),
- DEBUG(3);
- private int numericVerbosity;
+ public enum LoggingLevel {
+ ERROR(0),
+ WARNING(1),
+ INFO(2),
+ DEBUG(3);
- LoggingLevel(int number) {
- numericVerbosity = number;
- }
+ private int numericVerbosity;
- public int getNumericVerbosity() {
- return numericVerbosity;
- }
+ LoggingLevel(int number) {
+ numericVerbosity = number;
+ }
- static LoggingLevel fromNumber(int number) {
- for (LoggingLevel level : LoggingLevel.values()) {
- if (level.getNumericVerbosity() == number) {
- return level;
+ public int getNumericVerbosity() {
+ return numericVerbosity;
+ }
+
+ static LoggingLevel fromNumber(int number) {
+ for (LoggingLevel level : LoggingLevel.values()) {
+ if (level.getNumericVerbosity() == number) {
+ return level;
+ }
}
+ return LoggingLevel.INFO;
}
- return LoggingLevel.INFO;
}
+
}
diff --git a/src/main/java/com/leonardobishop/quests/api/QuestsPlaceholders.java b/src/main/java/com/leonardobishop/quests/api/QuestsPlaceholders.java
index f9acb3bb..2836f7ee 100644
--- a/src/main/java/com/leonardobishop/quests/api/QuestsPlaceholders.java
+++ b/src/main/java/com/leonardobishop/quests/api/QuestsPlaceholders.java
@@ -4,38 +4,47 @@ import com.leonardobishop.quests.Quests;
import com.leonardobishop.quests.api.enums.QuestStartResult;
import com.leonardobishop.quests.obj.Options;
import com.leonardobishop.quests.player.QPlayer;
-import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
import com.leonardobishop.quests.quests.Category;
import com.leonardobishop.quests.quests.Quest;
+import me.clip.placeholderapi.expansion.Cacheable;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
+import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
import java.util.concurrent.TimeUnit;
-public class QuestsPlaceholders extends PlaceholderExpansion {
+public class QuestsPlaceholders extends PlaceholderExpansion implements Cacheable {
+
private final Quests plugin;
+ private final Map<String, Map<String, String>> cache = new HashMap<>();
+ private final Map<String, SimpleDateFormat> formats = new HashMap<>();
public QuestsPlaceholders(Quests plugin) {
this.plugin = plugin;
}
@Override
+ public void clear() {
+ cache.clear();
+ formats.clear();
+ }
+
+ @Override
public String getIdentifier() {
return "quests";
}
@Override
public String getAuthor() {
- return this.plugin.getDescription().getAuthors().toString();
+ return plugin.getDescription().getAuthors().toString();
}
@Override
public String getVersion() {
- return this.plugin.getDescription().getVersion();
+ return plugin.getDescription().getVersion();
}
@Override
@@ -43,224 +52,247 @@ public class QuestsPlaceholders extends PlaceholderExpansion {
return true;
}
- //TODO maybe cache these results for a bit? all these calls could be heavy
-
@Override
public String onPlaceholderRequest(Player p, String params) {
- if (p == null || !p.isOnline())
- return null;
+ if (p == null || !p.isOnline()) return null;
+ if (cache.containsKey(p.getName()) && cache.get(p.getName()).containsKey(params)) return cache.get(p.getName()).get(params);
- String[] key = params.split("_", 5);
- QPlayer questP = this.plugin.getPlayerManager().getPlayer(p.getUniqueId());
+ String[] args = params.split("_", 4);
+ if (args.length < 1) return "Invalid Placeholder";
- if (key[0].equals("all") || key[0].equals("completed") || key[0].equals("completedBefore")
- || key[0].equals("completedbefore") || key[0].equals("started") || key[0].equals("categories")) {
- if (key.length == 1) {
- switch (key[0]) {
- case "all":
- return String.valueOf(this.plugin.getQuestManager().getQuests().size());
- case "completed":
- return String.valueOf(questP.getQuestProgressFile().getAllQuestsFromProgress(QuestProgressFile.QuestsProgressFilter.COMPLETED).size());
- case "completedbefore":
- case "completedBefore":
- return String.valueOf(questP.getQuestProgressFile().getAllQuestsFromProgress(QuestProgressFile.QuestsProgressFilter.COMPLETED_BEFORE).size());
- case "started":
- return String.valueOf(questP.getQuestProgressFile().getAllQuestsFromProgress(QuestProgressFile.QuestsProgressFilter.STARTED).size());
- case "categories":
- return String.valueOf(this.plugin.getQuestManager().getCategories().size());
- }
- } else if (key[1].equals("list") || key[1].equals("l")) {
- String separator = ",";
- if (!(key.length == 2)) {
- separator = key[2];
- }
+ final boolean save = args[args.length-1].toLowerCase().equals("cache");
+ if (save) args = Arrays.copyOf(args, args.length - 1);
- switch (key[0]) {
- case "all":
- return String.join(separator, this.plugin.getQuestManager().getQuests().toString());
- case "categories":
- return String.join(separator, this.plugin.getQuestManager().getCategories().toString());
- case "completed":
- List<String> listCompleted = new ArrayList<>();
- for (Quest qCompleted : questP.getQuestProgressFile().getAllQuestsFromProgress(QuestProgressFile.QuestsProgressFilter.COMPLETED)) {
- listCompleted.add(qCompleted.getDisplayNameStripped());
- }
- return String.join(separator, listCompleted);
- case "completedbefore":
- case "completedBefore":
- List<String> listCompletedBefore = new ArrayList<>();
- for (Quest qCompletedBefore : questP.getQuestProgressFile().getAllQuestsFromProgress(QuestProgressFile.QuestsProgressFilter.COMPLETED_BEFORE)) {
- listCompletedBefore.add(qCompletedBefore.getDisplayNameStripped());
- }
- return String.join(separator, listCompletedBefore);
- case "started":
- List<String> listStarted = new ArrayList<>();
- for (Quest qStarted : questP.getQuestProgressFile().getAllQuestsFromProgress(QuestProgressFile.QuestsProgressFilter.STARTED)) {
- listStarted.add(qStarted.getDisplayNameStripped());
- }
- return String.join(separator, listStarted);
- }
- }
- return "null";
- }
+ final QPlayer qPlayer = plugin.getPlayerManager().getPlayer(p.getUniqueId());
+ String split = args[args.length-1];
- if (key[0].startsWith("quest:") || key[0].startsWith("q:")) {
- Quest quest = this.plugin.getQuestManager().getQuestById(key[0].substring(key[0].lastIndexOf(":") + 1));
- if (key.length < 2) {
- if (quest != null) {
- return quest.getId();
- } else {
- return "null";
- }
- } else if (key[1].equals("started") || key[1].equals("s")) {
- if (quest != null && questP.getQuestProgressFile().getQuestProgress(quest).isStarted()) {
- return "true";
- }
- return "false";
- } else if (key[1].equals("completed") || key[1].equals("c")) {
- if (quest != null && questP.getQuestProgressFile().getQuestProgress(quest).isCompleted()) {
- return "true";
- }
- return "false";
- } else if (key[1].equals("completedbefore") || key[1].equals("completedBefore") || key[1].equals("cB")) {
- if (quest != null && questP.getQuestProgressFile().getQuestProgress(quest).isCompletedBefore()) {
- return "true";
- }
- return "false";
- } else if (key[1].equals("completiondate") || key[1].equals("completionDate")) {
- if (quest != null && questP.getQuestProgressFile().getQuestProgress(quest).isCompleted()) {
- SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); //TODO make configurable for all our american friends
- return sdf.format(questP.getQuestProgressFile().getQuestProgress(quest).getCompletionDate());
- }
- return "Never";
- } else if (key[1].equals("cooldown")) {
- if (quest != null && questP.getQuestProgressFile().getQuestProgress(quest).isCompleted()) {
- String time = this.plugin.convertToFormat(TimeUnit.SECONDS.convert(questP.getQuestProgressFile().getCooldownFor(quest), TimeUnit.MILLISECONDS));
- if (time.startsWith("-")) {
- return "0";
- }
- return time;
- }
- return "0";
- } else if (key[1].equals("canaccept") || key[1].equals("canAccept")) {
- if (quest != null && questP.getQuestProgressFile().canStartQuest(quest) == QuestStartResult.QUEST_SUCCESS) {
- return "true";
- }
- return "false";
- } else if (key[1].equals("meetsrequirements") || key[1].equals("meetsRequirements")) {
- if (quest != null && questP.getQuestProgressFile().hasMetRequirements(quest)) {
- return "true";
- }
- return "false";
- } else if (key[1].startsWith("task") || key[1].startsWith("t")) {
- String[] t = key[1].split(":");
- if (key[2].equals("progress") || key[2].equals("p")) {
- if (quest == null || questP.getQuestProgressFile().getQuestProgress(quest).getTaskProgress(t[1]).getProgress() == null) {
- return "0";
- }
- return String.valueOf(questP.getQuestProgressFile().getQuestProgress(quest).getTaskProgress(t[1]).getProgress());
- } else if (key[2].equals("completed") || key[2].equals("c")) {
- if (quest == null || questP.getQuestProgressFile().getQuestProgress(quest).getTaskProgress(t[1]).isCompleted()) {
- return "true";
+ String result = "null";
+ if (!args[0].contains(":")) {
+ if (args.length > 1 && split.equals(args[1])) split = ",";
+
+ switch (args[0].toLowerCase()) {
+ case "all":
+ case "a":
+ final List<Quest> listAll = new ArrayList<>(plugin.getQuestManager().getQuests().values());
+ result = (args.length == 1 ? String.valueOf(listAll.size()) : parseList((List<Quest>) listAll, args[1], split));
+ break;
+ case "completed":
+ case "c":
+ final List<Quest> listCompleted = qPlayer.getQuestProgressFile().getAllQuestsFromProgress(QuestProgressFile.QuestsProgressFilter.COMPLETED);
+ result = (args.length == 1 ? String.valueOf(listCompleted.size()) : parseList(listCompleted, args[1], split));
+ break;
+ case "completedbefore":
+ case "cb":
+ final List<Quest> listCompletedB = qPlayer.getQuestProgressFile().getAllQuestsFromProgress(QuestProgressFile.QuestsProgressFilter.COMPLETED_BEFORE);
+ result = (args.length == 1 ? String.valueOf(listCompletedB.size()) : parseList(listCompletedB, args[1], split));
+ break;
+ case "started":
+ case "s":
+ final List<Quest> listStarted = qPlayer.getQuestProgressFile().getAllQuestsFromProgress(QuestProgressFile.QuestsProgressFilter.STARTED);
+ result = (args.length == 1 ? String.valueOf(listStarted.size()) : parseList(listStarted, args[1], split));
+ break;
+ case "categories":
+ if (args.length == 1) {
+ result = String.valueOf(plugin.getQuestManager().getCategories().size());
+ } else {
+ final List<String> listCategories = new ArrayList<>();
+ switch (args[1].toLowerCase()) {
+ case "list":
+ case "l":
+ plugin.getQuestManager().getCategories().forEach(c -> listCategories.add(c.getDisplayNameStripped()));
+ break;
+ case "listid":
+ case "lid":
+ plugin.getQuestManager().getCategories().forEach(c -> listCategories.add(c.getId()));
+ break;
+ default:
+ return args[0] + "_" + args[1] + "is not a valid placeholder";
+ }
+ result = String.join(split, listCategories);
}
- return "false";
- }
+ break;
+ default:
+ return args[0] + "is not a valid placeholder";
}
+ } else {
+ final String[] key = args[0].split(":");
+ switch (key[0].toLowerCase()) {
+ case "quest":
+ case "q":
+ if (key.length == 1) return "Please specify quest name";
- return "null";
- }
+ final Quest quest = plugin.getQuestManager().getQuestById(key[1]);
+ if (quest == null) return key[1] + "is not a quest";
- if (key[0].startsWith("category:") || key[0].startsWith("c:")) {
- if (!Options.CATEGORIES_ENABLED.getBooleanValue()) {
- return "Categories Disabled";
- }
- Category category = this.plugin.getQuestManager().getCategoryById(key[0].substring(key[0].lastIndexOf(":") + 1));
- if (key.length < 2) {
- if (category != null) {
- return category.getId();
- } else {
- return "null";
- }
- } else if (key.length == 2) {
- switch (key[1]) {
- case "all":
- case "a":
- return String.valueOf(category.getRegisteredQuestIds().size());
- case "completed":
- case "c":
- return String.valueOf(getCategoryQuests(questP, category, QuestProgressFile.QuestsProgressFilter.COMPLETED).size());
- case "completedbefore":
- case "completedBefore":
- case "cB":
- return String.valueOf(getCategoryQuests(questP, category, QuestProgressFile.QuestsProgressFilter.COMPLETED_BEFORE).size());
- case "started":
- case "s":
- return String.valueOf(getCategoryQuests(questP, category, QuestProgressFile.QuestsProgressFilter.STARTED).size());
- }
- } else if (key[2].equals("list") || key[2].equals("l")) {
- String separator = ",";
- if (!(key.length == 3)) {
- separator = key[3];
- }
+ if (args.length == 1) {
+ result = quest.getDisplayNameStripped();
+ } else {
+ switch (args[1].toLowerCase()) {
+ case "started":
+ case "s":
+ result = (qPlayer.getQuestProgressFile().getQuestProgress(quest).isStarted() ? "true" : "false");
+ break;
+ case "completed":
+ case "c":
+ result = (qPlayer.getQuestProgressFile().getQuestProgress(quest).isCompleted() ? "true" : "false");
+ break;
+ case "completedbefore":
+ case "cb":
+ result = (qPlayer.getQuestProgressFile().getQuestProgress(quest).isCompletedBefore() ? "true" : "false");
+ break;
+ case "completiondate":
+ case "cd":
+ if (qPlayer.getQuestProgressFile().getQuestProgress(quest).isCompleted()) {
+ result = parseDate(args, qPlayer.getQuestProgressFile().getQuestProgress(quest).getCompletionDate());
+ } else {
+ result = "Never";
+ }
+ break;
+ case "cooldown":
+ if (qPlayer.getQuestProgressFile().getQuestProgress(quest).isCompleted()) {
+ final String time = plugin.convertToFormat(TimeUnit.SECONDS.convert(qPlayer.getQuestProgressFile().getCooldownFor(quest), TimeUnit.MILLISECONDS));
+ if (!time.startsWith("-")) result = time;
+ } else {
+ result = "0";
+ }
+ break;
+ case "canaccept":
+ result = (qPlayer.getQuestProgressFile().canStartQuest(quest) == QuestStartResult.QUEST_SUCCESS ? "true" : "false");
+ break;
+ case "meetsrequirements":
+ result = (qPlayer.getQuestProgressFile().hasMetRequirements(quest) ? "true" : "false");
+ break;
+ default:
+ if (!args[1].contains(":")) return args[0] + "_" + args[1] + "is not a valid placeholder";
- switch (key[1]) {
- case "all":
- case "a":
- List<String> listAll = new ArrayList<>();
- for (Quest qCompleted : getCategoryQuests(questP, category, QuestProgressFile.QuestsProgressFilter.ALL)) {
- listAll.add(qCompleted.getDisplayNameStripped());
- }
- return String.join(separator, listAll);
- case "completed":
- case "c":
- List<String> listCompleted = new ArrayList<>();
- for (Quest qCompleted : getCategoryQuests(questP, category, QuestProgressFile.QuestsProgressFilter.COMPLETED)) {
- listCompleted.add(qCompleted.getDisplayNameStripped());
- }
- return String.join(separator, listCompleted);
- case "completedbefore":
- case "completedBefore":
- case "cB":
- List<String> listCompletedBefore = new ArrayList<>();
- for (Quest qCompletedBefore : getCategoryQuests(questP, category, QuestProgressFile.QuestsProgressFilter.COMPLETED_BEFORE)) {
- listCompletedBefore.add(qCompletedBefore.getDisplayNameStripped());
+ final String[] t = args[1].split(":");
+ if (!t[0].toLowerCase().equals("task") && !t[0].toLowerCase().equals("t")) return args[0] + "_" + args[1] + "is not a valid placeholder";
+ if (t.length == 1) return "Please specify task name";
+
+ if (args.length == 2) {
+ result = qPlayer.getQuestProgressFile().getQuestProgress(quest).getTaskProgress(t[1]).getTaskId();
+ } else {
+ switch (args[2].toLowerCase()) {
+ case "progress":
+ case "p":
+ final Object progress = qPlayer.getQuestProgressFile().getQuestProgress(quest).getTaskProgress(t[1]).getProgress();
+ result = (progress == null ? "0" : String.valueOf(progress));
+ break;
+ case "completed":
+ case "c":
+ result = String.valueOf(qPlayer.getQuestProgressFile().getQuestProgress(quest).getTaskProgress(t[1]).isCompleted());
+ break;
+ default:
+ return args[0] + "_" + args[1] + "_" + args[2] + "is not a valid placeholder";
+ }
+ }
}
- return String.join(separator, listCompletedBefore);
- case "started":
- case "s":
- List<String> listStarted = new ArrayList<>();
- for (Quest qStarted : getCategoryQuests(questP, category, QuestProgressFile.QuestsProgressFilter.STARTED)) {
- listStarted.add(qStarted.getDisplayNameStripped());
+ }
+ break;
+ case "category":
+ case "c":
+ if (!Options.CATEGORIES_ENABLED.getBooleanValue()) return "Categories Disabled";
+ if (key.length == 1) return "Please specify category name";
+
+ final Category category = plugin.getQuestManager().getCategoryById(key[1]);
+ if (category == null) return key[1] + "is not a category";
+
+ if (args.length == 1) {
+ result = category.getDisplayNameStripped();
+ } else {
+ if (args.length > 2 && split.equals(args[2])) split = ",";
+ switch (args[1].toLowerCase()) {
+ case "all":
+ case "a":
+ final List<Quest> listAll = getCategoryQuests(qPlayer, category, QuestProgressFile.QuestsProgressFilter.ALL);
+ result = (args.length == 2 ? String.valueOf(listAll.size()) : parseList(listAll, args[2], split));
+ break;
+ case "completed":
+ case "c":
+ final List<Quest> listCompleted = getCategoryQuests(qPlayer, category, QuestProgressFile.QuestsProgressFilter.COMPLETED);
+ result = (args.length == 2 ? String.valueOf(listCompleted.size()) : parseList(listCompleted, args[2], split));
+ break;
+ case "completedbefore":
+ case "cb":
+ final List<Quest> listCompletedB = getCategoryQuests(qPlayer, category, QuestProgressFile.QuestsProgressFilter.COMPLETED_BEFORE);
+ result = (args.length == 2 ? String.valueOf(listCompletedB.size()) : parseList(listCompletedB, args[2], split));
+ break;
+ case "started":
+ case "s":
+ final List<Quest> listStarted = getCategoryQuests(qPlayer, category, QuestProgressFile.QuestsProgressFilter.STARTED);
+ result = (args.length == 2 ? String.valueOf(listStarted.size()) : parseList(listStarted, args[2], split));
+ break;
+ default:
+ return args[0] + "_" + args[1] + "is not a valid placeholder";
}
- return String.join(separator, listStarted);
- }
+ }
+ break;
+ default:
+ return args[0] + "is not a valid placeholder";
}
- return "null";
}
- return null;
+ return (save ? cache(p.getName(), params, result) : result);
}
- private List<Quest> getCategoryQuests(QPlayer questP, Category category, QuestProgressFile.QuestsProgressFilter filter) {
- List<Quest> categoryQuests = new ArrayList<>();
- for (String cQuests : category.getRegisteredQuestIds()) {
- Quest quest = plugin.getQuestManager().getQuestById(cQuests);
- if (quest == null) continue;
+ private String cache(String player, String params, String result) {
+ if (!cache.containsKey(player) || !cache.get(player).containsKey(params)) {
+ final Map<String, String> map = new HashMap<>();
+ map.put(params, result);
+ cache.put(player, map);
+ Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> cache.get(player).remove(params), plugin.getConfig().getInt("options.placeholder-cache-time", 10) * 20);
+ }
+ return result;
+ }
- boolean condition = false;
- if (filter == QuestProgressFile.QuestsProgressFilter.STARTED) {
- condition = questP.getQuestProgressFile().getQuestProgress(quest).isStarted();
- } else if (filter == QuestProgressFile.QuestsProgressFilter.COMPLETED_BEFORE) {
- condition = questP.getQuestProgressFile().getQuestProgress(quest).isCompletedBefore();
- } else if (filter == QuestProgressFile.QuestsProgressFilter.COMPLETED) {
- condition = questP.getQuestProgressFile().getQuestProgress(quest).isCompleted();
- } else if (filter == QuestProgressFile.QuestsProgressFilter.ALL) {
- condition = true;
- }
+ private String parseDate(String[] args, Long date) {
+ final String format = (args[args.length-1].equals(args[1]) ? "dd/MM/yyyy" : args[args.length-1]);
+ SimpleDateFormat sdf;
+ if (formats.containsKey(format)) {
+ sdf = formats.get(format);
+ } else {
+ sdf = new SimpleDateFormat(format);
+ formats.put(format, sdf);
+ }
+ return sdf.format(date);
+ }
- if (condition) {
- categoryQuests.add(quest);
- }
+ private String parseList(List<Quest> list, String type, String separator) {
+ final List<String> quests = new ArrayList<>();
+ switch (type.toLowerCase()) {
+ case "list":
+ case "l":
+ list.forEach(q -> quests.add(q.getDisplayNameStripped()));
+ break;
+ case "listid":
+ case "lid":
+ list.forEach(q -> quests.add(q.getId()));
+ break;
+ default:
+ return type + "is not a valid placeholder";
}
+ return String.join(separator, quests);
+ }
+
+ private List<Quest> getCategoryQuests(QPlayer questP, Category category, QuestProgressFile.QuestsProgressFilter filter) {
+ final List<Quest> categoryQuests = new ArrayList<>();
+ category.getRegisteredQuestIds().forEach(q -> {
+ Quest quest = plugin.getQuestManager().getQuestById(q);
+ if (quest != null) {
+ switch (filter) {
+ case STARTED:
+ if (questP.getQuestProgressFile().getQuestProgress(quest).isStarted()) categoryQuests.add(quest);
+ break;
+ case COMPLETED:
+ if (questP.getQuestProgressFile().getQuestProgress(quest).isCompleted()) categoryQuests.add(quest);
+ break;
+ case COMPLETED_BEFORE:
+ if (questP.getQuestProgressFile().getQuestProgress(quest).isCompletedBefore()) categoryQuests.add(quest);
+ break;
+ default:
+ categoryQuests.add(quest);
+ }
+ }
+ });
return categoryQuests;
}
}
diff --git a/src/main/java/com/leonardobishop/quests/blocktype/Block.java b/src/main/java/com/leonardobishop/quests/blocktype/Block.java
index 4fa71515..4b3b7d6a 100644
--- a/src/main/java/com/leonardobishop/quests/blocktype/Block.java
+++ b/src/main/java/com/leonardobishop/quests/blocktype/Block.java
@@ -2,6 +2,7 @@ package com.leonardobishop.quests.blocktype;
import org.bukkit.Material;
+@Deprecated
public class Block {
private Material material;
diff --git a/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java b/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java
index 382c3c1a..6c72a4e8 100644
--- a/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java
+++ b/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java
@@ -14,14 +14,20 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
+import org.bukkit.util.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.util.Map;
-import java.util.UUID;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.*;
-public class CommandQuests implements CommandExecutor {
+public class CommandQuests implements TabExecutor {
private final Quests plugin;
@@ -32,13 +38,19 @@ public class CommandQuests implements CommandExecutor {
@SuppressWarnings("deprecation")
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
+ if (plugin.getTaskTypeManager().areRegistrationsAccepted()) {
+ sender.sendMessage(ChatColor.RED + "Quests is not ready yet.");
+ return true;
+ }
if (plugin.isBrokenConfig() &&
!(args.length >= 2 &&
(args[0].equalsIgnoreCase("a") || args[0].equalsIgnoreCase("admin")) &&
args[1].equalsIgnoreCase("reload"))) {
- sender.sendMessage(ChatColor.RED + "The main config must be in tact before quests can be used. Quests has failed to load the following files:");
- for (Map.Entry<String, QuestsConfigLoader.ConfigLoadError> entry : plugin.getQuestsConfigLoader().getBrokenFiles().entrySet()) {
- sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + entry.getKey() + ": " + ChatColor.GRAY + entry.getValue().getMessage());
+ sender.sendMessage(ChatColor.RED + "Quests cannot be used right now. Please speak to an administrator.");
+ if (sender.hasPermission("quests.admin")) {
+ showProblems(sender);
+ sender.sendMessage(ChatColor.RED + "The main config (config.yml) must be in tact before quests can be used. " +
+ "Please use the above information to help rectify the problem.");
}
return true;
}
@@ -65,15 +77,11 @@ public class CommandQuests implements CommandExecutor {
} else if (args[1].equalsIgnoreCase("reload")) {
plugin.reloadConfig();
plugin.reloadQuests();
- Options.clearBoolValues();
- if (!plugin.getQuestsConfigLoader().getBrokenFiles().isEmpty()) {
- sender.sendMessage(ChatColor.RED + "Quests has failed to load the following files:");
- for (Map.Entry<String, QuestsConfigLoader.ConfigLoadError> entry : plugin.getQuestsConfigLoader().getBrokenFiles().entrySet()) {
- sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + entry.getKey() + ": " + ChatColor.GRAY + entry.getValue().getMessage());
- }
- } else {
- sender.sendMessage(ChatColor.GRAY + "Quests was reloaded.");
- }
+ showProblems(sender);
+ sender.sendMessage(ChatColor.GRAY + "Quests successfully reloaded.");
+ return true;
+ } else if (args[1].equalsIgnoreCase("config")) {
+ showProblems(sender);
return true;
} else if (args[1].equalsIgnoreCase("types")) {
sender.sendMessage(ChatColor.GRAY + "Registered task types:");
@@ -99,6 +107,41 @@ public class CommandQuests implements CommandExecutor {
showAdminHelp(sender, "opengui");
return true;
} else if (args[1].equalsIgnoreCase("moddata")) {
+ if (args[2].equalsIgnoreCase("clean")) {
+ FileVisitor<Path> fileVisitor = new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path path, BasicFileAttributes attributes) {
+ File playerDataFile = new File(path.toUri());
+ if (!playerDataFile.getName().toLowerCase().endsWith(".yml")) return FileVisitResult.CONTINUE;
+ String uuidStr = playerDataFile.getName().replace(".yml", "");
+ UUID uuid;
+ try {
+ uuid = UUID.fromString(uuidStr);
+ } catch (IllegalArgumentException ex) {
+ return FileVisitResult.CONTINUE;
+ }
+
+ plugin.getPlayerManager().loadPlayer(uuid);
+ QPlayer qPlayer = plugin.getPlayerManager().getPlayer(uuid);
+ qPlayer.getQuestProgressFile().clean();
+ qPlayer.getQuestProgressFile().saveToDisk(false, true);
+ if (Bukkit.getPlayer(uuid) == null) {
+ plugin.getPlayerManager().dropPlayer(uuid);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ };
+ //TODO command to clean specific player
+ try {
+ Files.walkFileTree(Paths.get(plugin.getDataFolder() + File.separator + "playerdata"), fileVisitor);
+ } catch (IOException e) {
+ sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_CLEAN_FAIL.getMessage());
+ e.printStackTrace();
+ return true;
+ }
+ sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_CLEAN_SUCCESS.getMessage());
+ return true;
+ }
showAdminHelp(sender, "moddata");
return true;
} else if (args[1].equalsIgnoreCase("types")) {
@@ -140,7 +183,7 @@ public class CommandQuests implements CommandExecutor {
String name;
// Player.class is a superclass for OfflinePlayer.
// getofflinePlayer return a player regardless if exists or not
- if (ofp != null) {
+ if (ofp.hasPlayedBefore()) {
uuid = ofp.getUniqueId();
name = ofp.getName();
} else {
@@ -151,7 +194,7 @@ public class CommandQuests implements CommandExecutor {
QPlayer qPlayer = plugin.getPlayerManager().getPlayer(uuid);
if (qPlayer == null) {
sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_LOADDATA.getMessage().replace("{player}", name));
- plugin.getPlayerManager().loadPlayer(uuid, true);
+ plugin.getPlayerManager().loadPlayer(uuid);
qPlayer = plugin.getPlayerManager().getPlayer(uuid); //get again
}
if (qPlayer == null) {
@@ -161,12 +204,12 @@ public class CommandQuests implements CommandExecutor {
QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
questProgressFile.clear();
questProgressFile.saveToDisk(false);
+ if (Bukkit.getPlayer(uuid) == null) {
+ plugin.getPlayerManager().dropPlayer(uuid);
+ }
sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_FULLRESET.getMessage().replace("{player}", name));
return true;
}
- if (plugin.getPlayerManager().getPlayer(uuid).isOnlyDataLoaded()) {
- plugin.getPlayerManager().removePlayer(uuid);
- }
showAdminHelp(sender, "moddata");
return true;
}
@@ -204,7 +247,7 @@ public class CommandQuests implements CommandExecutor {
OfflinePlayer ofp = Bukkit.getOfflinePlayer(args[3]);
UUID uuid;
String name;
- if (ofp != null) {
+ if (ofp.hasPlayedBefore()) {
uuid = ofp.getUniqueId();
name = ofp.getName();
} else {
@@ -214,7 +257,7 @@ public class CommandQuests implements CommandExecutor {
QPlayer qPlayer = plugin.getPlayerManager().getPlayer(uuid);
if (qPlayer == null) {
sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_LOADDATA.getMessage().replace("{player}", name));
- plugin.getPlayerManager().loadPlayer(uuid, true);
+ plugin.getPlayerManager().loadPlayer(uuid);
}
if (qPlayer == null) {
sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_NODATA.getMessage().replace("{player}", name));
@@ -230,7 +273,7 @@ public class CommandQuests implements CommandExecutor {
}
if (args[2].equalsIgnoreCase("reset")) {
questProgressFile.generateBlankQuestProgress(quest.getId());
- questProgressFile.saveToDisk(false);
+ questProgressFile.saveToDisk(false, true);
sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_RESET_SUCCESS.getMessage().replace("{player}", name).replace("{quest}", quest.getId()));
success = true;
} else if (args[2].equalsIgnoreCase("start")) {
@@ -266,12 +309,12 @@ public class CommandQuests implements CommandExecutor {
sender.sendMessage(Messages.COMMAND_QUEST_ADMIN_COMPLETE_SUCCESS.getMessage().replace("{player}", name).replace("{quest}", quest.getId()));
success = true;
}
- if (plugin.getPlayerManager().getPlayer(uuid).isOnlyDataLoaded()) {
- plugin.getPlayerManager().removePlayer(uuid);
- }
if (!success) {
showAdminHelp(sender, "moddata");
}
+ if (Bukkit.getPlayer(uuid) == null) {
+ plugin.getPlayerManager().dropPlayer(uuid);
+ }
return true;
}
}
@@ -325,13 +368,64 @@ public class CommandQuests implements CommandExecutor {
}
}
showHelp(sender);
- return true;
} else {
sender.sendMessage(ChatColor.RED + "Only admin commands are available to non-player senders.");
}
return true;
}
+ private void showProblems(CommandSender sender) {
+ if (!plugin.getQuestsConfigLoader().getFilesWithProblems().isEmpty()) {
+// sender.sendMessage(ChatColor.DARK_GRAY.toString() + "----");
+ sender.sendMessage(ChatColor.GRAY + "Detected problems and potential issues:");
+ Set<QuestsConfigLoader.ConfigProblemType> problemTypes = new HashSet<>();
+ for (Map.Entry<String, List<QuestsConfigLoader.ConfigProblem>> entry : plugin.getQuestsConfigLoader().getFilesWithProblems().entrySet()) {
+ HashMap<QuestsConfigLoader.ConfigProblemType, List<QuestsConfigLoader.ConfigProblem>> sortedProblems = new HashMap<>();
+ for (QuestsConfigLoader.ConfigProblem problem : entry.getValue()) {
+ if (sortedProblems.containsKey(problem.getType())) {
+ sortedProblems.get(problem.getType()).add(problem);
+ } else {
+ List<QuestsConfigLoader.ConfigProblem> specificProblems = new ArrayList<>();
+ specificProblems.add(problem);
+ sortedProblems.put(problem.getType(), specificProblems);
+ }
+ problemTypes.add(problem.getType());
+ }
+ QuestsConfigLoader.ConfigProblemType highest = null;
+ for (QuestsConfigLoader.ConfigProblemType type : QuestsConfigLoader.ConfigProblemType.values()) {
+ if (sortedProblems.containsKey(type)) {
+ highest = type;
+ break;
+ }
+ }
+ ChatColor highestColor = ChatColor.WHITE;
+ if (highest != null) {
+ highestColor = highest.getColor();
+ }
+ sender.sendMessage(highestColor + entry.getKey() + ChatColor.DARK_GRAY + " ----");
+ for (QuestsConfigLoader.ConfigProblemType type : QuestsConfigLoader.ConfigProblemType.values()) {
+ if (sortedProblems.containsKey(type)) {
+ for (QuestsConfigLoader.ConfigProblem problem : sortedProblems.get(type)) {
+ sender.sendMessage(ChatColor.DARK_GRAY + " | - " + problem.getType().getColor()
+ + problem.getType().getShortened() + ChatColor.DARK_GRAY + ": "
+ + ChatColor.GRAY + problem.getDescription() + ChatColor.DARK_GRAY + " :" + problem.getLocation());
+ }
+ }
+ }
+ }
+// sender.sendMessage(ChatColor.DARK_GRAY.toString() + "----");
+ List<String> legend = new ArrayList<>();
+ for (QuestsConfigLoader.ConfigProblemType type : QuestsConfigLoader.ConfigProblemType.values()) {
+ if (problemTypes.contains(type))
+ legend.add(type.getColor() + type.getShortened() + ChatColor.DARK_GRAY + " = " + type.getColor() + type.getTitle());
+ }
+ sender.sendMessage(ChatColor.DARK_GRAY.toString() + "----");
+ sender.sendMessage(ChatColor.GRAY.toString() + plugin.getQuestsConfigLoader().getProblemsCount() + " problem(s) | " + String.join(ChatColor.DARK_GRAY + ", ", legend));
+ } else {
+ sender.sendMessage(ChatColor.GRAY + "Quests did not detect any problems with your configuration.");
+ }
+ }
+
private void showHelp(CommandSender sender) {
sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "------------=[" + ChatColor.RED + " Quests v" + plugin
.getDescription().getVersion() + " " + ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "]=------------");
@@ -349,7 +443,7 @@ public class CommandQuests implements CommandExecutor {
sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "------------=[" + ChatColor.RED + " Quests Admin: opengui " + ChatColor
.GRAY.toString() + ChatColor.STRIKETHROUGH + "]=------------");
sender.sendMessage(ChatColor.GRAY + "The following commands are available: ");
- sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a opengui q/quest <player> " + ChatColor.DARK_GRAY + ": forcefully show" +
+ sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a opengui q/quests <player> " + ChatColor.DARK_GRAY + ": forcefully show" +
" quests for player");
sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a opengui c/category <player> <category> " + ChatColor.DARK_GRAY + ": " +
"forcefully " +
@@ -361,12 +455,14 @@ public class CommandQuests implements CommandExecutor {
sender.sendMessage(ChatColor.GRAY + "The following commands are available: ");
sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata fullreset <player> " + ChatColor.DARK_GRAY + ": clear a " +
"players quest data file");
- sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata reset <player> <questid>" + ChatColor.DARK_GRAY + ": clear a " +
+ sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata reset <player> <questid> " + ChatColor.DARK_GRAY + ": clear a " +
"players data for specifc quest");
- sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata start <player> <questid>" + ChatColor.DARK_GRAY + ": start a " +
+ sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata start <player> <questid> " + ChatColor.DARK_GRAY + ": start a " +
"quest for a player");
- sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata complete <player> <questid>" + ChatColor.DARK_GRAY + ": " +
+ sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata complete <player> <questid> " + ChatColor.DARK_GRAY + ": " +
"complete a quest for a player");
+ sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata clean " + ChatColor.DARK_GRAY + ": " +
+ "clean quest data files for quests which are no longer defined");
sender.sendMessage(ChatColor.GRAY + "These commands modify quest progress for players. Use them cautiously. Changes are irreversible.");
} else {
sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "------------=[" + ChatColor.RED + " Quests Admin " + ChatColor.GRAY
@@ -376,9 +472,99 @@ public class CommandQuests implements CommandExecutor {
sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a moddata " + ChatColor.DARK_GRAY + ": view help for quest progression");
sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a types [type]" + ChatColor.DARK_GRAY + ": view registered task types");
sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a reload " + ChatColor.DARK_GRAY + ": reload Quests configuration");
+ sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a config " + ChatColor.DARK_GRAY + ": see detected problems in config");
sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + "/quests a update " + ChatColor.DARK_GRAY + ": check for updates");
}
sender.sendMessage(ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "-----=[" + ChatColor.RED + " requires permission: quests.admin " +
ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH + "]=-----");
}
+
+ private List<String> matchTabComplete(String arg, List<String> options) {
+ List<String> completions = new ArrayList<>();
+ StringUtil.copyPartialMatches(arg, options, completions);
+ Collections.sort(completions);
+ return completions;
+ }
+
+ private List<String> tabCompleteCategory(String arg) {
+ List<String> options = new ArrayList<>();
+ for (Category c : plugin.getQuestManager().getCategories()) {
+ options.add(c.getId());
+ }
+ return matchTabComplete(arg, options);
+ }
+
+ private List<String> tabCompleteQuests(String arg) {
+ List<String> options = new ArrayList<>(plugin.getQuestManager().getQuests().keySet());
+ return matchTabComplete(arg, options);
+ }
+
+ @Nullable
+ @Override
+ public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
+ if (!Options.TAB_COMPLETE_ENABLED.getBooleanValue(true)) {
+ return null;
+ }
+ if (sender instanceof Player) {
+ if (args.length == 1) {
+ List<String> options = new ArrayList<>(Arrays.asList("quest", "category"));
+ if (sender.hasPermission("quests.admin")) {
+ options.add("admin");
+ }
+ return matchTabComplete(args[0], options);
+ } else if (args.length == 2) {
+ if (args[0].equalsIgnoreCase("c") || args[0].equalsIgnoreCase("category")) {
+ return tabCompleteCategory(args[1]);
+ } else if (args[0].equalsIgnoreCase("q") || args[0].equalsIgnoreCase("quest")) {
+ return tabCompleteQuests(args[1]);
+ } else if (args[0].equalsIgnoreCase("a") || args[0].equalsIgnoreCase("admin")
+ && sender.hasPermission("quests.admin")) {
+ List<String> options = Arrays.asList("opengui", "moddata", "types", "reload", "update", "config");
+ return matchTabComplete(args[1], options);
+ }
+ } else if (args.length == 3) {
+ if (args[0].equalsIgnoreCase("q") || args[0].equalsIgnoreCase("quest")
+ && sender.hasPermission("quests.admin")) {
+ Quest q = plugin.getQuestManager().getQuestById(args[1]);
+ if (q != null) {
+ List<String> options = Arrays.asList("start", "cancel");
+ return matchTabComplete(args[2], options);
+ }
+ } else if (args[0].equalsIgnoreCase("a") || args[0].equalsIgnoreCase("admin")
+ && sender.hasPermission("quests.admin")) {
+ if (args[1].equalsIgnoreCase("types")) {
+ List<String> options = new ArrayList<>();
+ for (TaskType taskType : plugin.getTaskTypeManager().getTaskTypes()) {
+ options.add(taskType.getType());
+ }
+ return matchTabComplete(args[2], options);
+ } else if (args[1].equalsIgnoreCase("opengui")) {
+ List<String> options = Arrays.asList("quests", "category");
+ return matchTabComplete(args[2], options);
+ } else if (args[1].equalsIgnoreCase("moddata")) {
+ List<String> options = Arrays.asList("fullreset", "reset", "start", "complete", "clean");
+ return matchTabComplete(args[2], options);
+ }
+ }
+ } else if (args.length == 4) {
+ if (sender.hasPermission("quests.admin")) return null;
+ } else if (args.length == 5) {
+ if (args[0].equalsIgnoreCase("a") || args[0].equalsIgnoreCase("admin")
+ && sender.hasPermission("quests.admin")) {
+ if (args[1].equalsIgnoreCase("opengui")) {
+ if (args[2].equalsIgnoreCase("c") || args[2].equalsIgnoreCase("category")) {
+ return tabCompleteCategory(args[4]);
+ }
+ } else if (args[1].equalsIgnoreCase("moddata")) {
+ if (args[2].equalsIgnoreCase("start")
+ || args[2].equalsIgnoreCase("complete")
+ || args[2].equalsIgnoreCase("reset")) {
+ return tabCompleteQuests(args[4]);
+ }
+ }
+ }
+ }
+ }
+ return Collections.emptyList();
+ }
}
diff --git a/src/main/java/com/leonardobishop/quests/events/EventInventory.java b/src/main/java/com/leonardobishop/quests/events/EventInventory.java
index aba0b12f..10f76538 100644
--- a/src/main/java/com/leonardobishop/quests/events/EventInventory.java
+++ b/src/main/java/com/leonardobishop/quests/events/EventInventory.java
@@ -1,14 +1,14 @@
package com.leonardobishop.quests.events;
+import com.leonardobishop.quests.Quests;
import com.leonardobishop.quests.api.enums.QuestStartResult;
import com.leonardobishop.quests.obj.Messages;
-import com.leonardobishop.quests.quests.Quest;
-import com.leonardobishop.quests.Quests;
import com.leonardobishop.quests.obj.Options;
import com.leonardobishop.quests.obj.misc.QMenu;
import com.leonardobishop.quests.obj.misc.QMenuCancel;
import com.leonardobishop.quests.obj.misc.QMenuCategory;
import com.leonardobishop.quests.obj.misc.QMenuQuest;
+import com.leonardobishop.quests.quests.Quest;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
@@ -22,12 +22,12 @@ import java.util.UUID;
public class EventInventory implements Listener {
- private static HashMap<UUID, QMenu> tracker = new HashMap<>();
- private Quests plugin;
+ private static final HashMap<UUID, QMenu> tracker = new HashMap<>();
+ private final Quests plugin;
// ADD PLAYERS TO THE BUFFER BEFORE AN ANTICIPATED MENU CHANGE SO THAT
// THEY ARE NOT LOST FROM THE TRACKER WHEN CHANGING MENUS
- private ArrayList<UUID> buffer = new ArrayList<>();
+ private final ArrayList<UUID> buffer = new ArrayList<>();
public EventInventory(Quests plugin) {
this.plugin = plugin;
@@ -136,5 +136,4 @@ public class EventInventory implements Listener {
buffer.remove(event.getPlayer().getUniqueId());
} else tracker.remove(event.getPlayer().getUniqueId());
}
-
}
diff --git a/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java b/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java
index 322316b1..52020ef7 100644
--- a/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java
+++ b/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java
@@ -2,6 +2,7 @@ package com.leonardobishop.quests.events;
import com.leonardobishop.quests.Quests;
import com.leonardobishop.quests.obj.Messages;
+import com.leonardobishop.quests.obj.Options;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -11,7 +12,7 @@ import java.util.UUID;
public class EventPlayerJoin implements Listener {
- private Quests plugin;
+ private final Quests plugin;
public EventPlayerJoin(Quests plugin) {
this.plugin = plugin;
@@ -20,7 +21,13 @@ public class EventPlayerJoin implements Listener {
@EventHandler
public void onEvent(PlayerJoinEvent event) {
UUID playerUuid = event.getPlayer().getUniqueId();
- plugin.getPlayerManager().loadPlayer(playerUuid, false);
+ plugin.getPlayerManager().loadPlayer(playerUuid);
+ if (Options.SOFT_CLEAN_QUESTSPROGRESSFILE_ON_JOIN.getBooleanValue()) {
+ plugin.getPlayerManager().getPlayer(playerUuid).getQuestProgressFile().clean();
+ if (Options.PUSH_SOFT_CLEAN_TO_DISK.getBooleanValue()) {
+ plugin.getPlayerManager().getPlayer(playerUuid).getQuestProgressFile().saveToDisk(false, true);
+ }
+ }
if (plugin.getDescription().getVersion().contains("beta") && event.getPlayer().hasPermission("quests.admin")) {
event.getPlayer().sendMessage(Messages.BETA_REMINDER.getMessage());
}
@@ -28,6 +35,8 @@ public class EventPlayerJoin implements Listener {
// delay for a bit so they actually see the message
Bukkit.getScheduler().runTaskLater(this.plugin, () -> event.getPlayer().sendMessage(plugin.getUpdater().getMessage()), 50L);
}
+ // run a full check to check for any missed quest completions
+ plugin.getQuestCompleter().queueFullCheck(plugin.getPlayerManager().getPlayer(playerUuid).getQuestProgressFile());
}
}
diff --git a/src/main/java/com/leonardobishop/quests/events/EventPlayerLeave.java b/src/main/java/com/leonardobishop/quests/events/EventPlayerLeave.java
index 9992bc22..2253cbec 100644
--- a/src/main/java/com/leonardobishop/quests/events/EventPlayerLeave.java
+++ b/src/main/java/com/leonardobishop/quests/events/EventPlayerLeave.java
@@ -1,7 +1,6 @@
package com.leonardobishop.quests.events;
import com.leonardobishop.quests.Quests;
-import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
diff --git a/src/main/java/com/leonardobishop/quests/itemgetter/ItemGetter.java b/src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetter.java
index 661d7302..a0d7545e 100644
--- a/src/main/java/com/leonardobishop/quests/itemgetter/ItemGetter.java
+++ b/src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetter.java
@@ -1,10 +1,8 @@
-package com.leonardobishop.quests.itemgetter;
+package com.leonardobishop.quests.hooks.itemgetter;
import com.leonardobishop.quests.Quests;
import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.ItemStack;
-import org.bukkit.plugin.java.JavaPlugin;
public interface ItemGetter {
@@ -29,6 +27,15 @@ public interface ItemGetter {
*/
ItemStack getItemStack(String material, Quests plugin);
+ /**
+ * Validates a material from a string.
+ * For pre-1.13 server implementations, the string may use a data code.
+ *
+ * @param material the string
+ * @return true if it a material
+ */
+ boolean isValidMaterial(String material);
+
enum Filter {
DISPLAY_NAME,
LORE,
diff --git a/src/main/java/com/leonardobishop/quests/itemgetter/ItemGetterLatest.java b/src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetterLatest.java
index 4015385a..c33baac7 100644
--- a/src/main/java/com/leonardobishop/quests/itemgetter/ItemGetterLatest.java
+++ b/src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetterLatest.java
@@ -1,4 +1,4 @@
-package com.leonardobishop.quests.itemgetter;
+package com.leonardobishop.quests.hooks.itemgetter;
import com.leonardobishop.quests.Quests;
import org.bukkit.ChatColor;
@@ -7,13 +7,11 @@ import org.bukkit.NamespacedKey;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.plugin.java.JavaPlugin;
import java.util.*;
@@ -228,4 +226,14 @@ public class ItemGetterLatest implements ItemGetter {
}
return new ItemStack(type, 1);
}
+
+ @Override
+ public boolean isValidMaterial(String material) {
+ try {
+ Material.valueOf(material);
+ return true;
+ } catch (IllegalArgumentException ex) {
+ return false;
+ }
+ }
}
diff --git a/src/main/java/com/leonardobishop/quests/itemgetter/ItemGetter_1_13.java b/src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetter_1_13.java
index b356f696..0e0850cd 100644
--- a/src/main/java/com/leonardobishop/quests/itemgetter/ItemGetter_1_13.java
+++ b/src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetter_1_13.java
@@ -1,4 +1,4 @@
-package com.leonardobishop.quests.itemgetter;
+package com.leonardobishop.quests.hooks.itemgetter;
import com.leonardobishop.quests.Quests;
import org.bukkit.ChatColor;
@@ -7,13 +7,11 @@ import org.bukkit.NamespacedKey;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.plugin.java.JavaPlugin;
import java.util.*;
@@ -218,4 +216,14 @@ public class ItemGetter_1_13 implements ItemGetter {
}
return new ItemStack(type, 1);
}
+
+ @Override
+ public boolean isValidMaterial(String material) {
+ try {
+ Material.valueOf(material);
+ return true;
+ } catch (IllegalArgumentException ex) {
+ return false;
+ }
+ }
}
diff --git a/src/main/java/com/leonardobishop/quests/itemgetter/ItemGetter_Late_1_8.java b/src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetter_Late_1_8.java
index 696560b1..f3523b70 100644
--- a/src/main/java/com/leonardobishop/quests/itemgetter/ItemGetter_Late_1_8.java
+++ b/src/main/java/com/leonardobishop/quests/hooks/itemgetter/ItemGetter_Late_1_8.java
@@ -1,16 +1,14 @@
-package com.leonardobishop.quests.itemgetter;
+package com.leonardobishop.quests.hooks.itemgetter;
import com.leonardobishop.quests.Quests;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.plugin.java.JavaPlugin;
import java.util.ArrayList;
import java.util.Arrays;
@@ -142,4 +140,22 @@ public class ItemGetter_Late_1_8 implements ItemGetter {
}
return new ItemStack(type, 1, (short) data);
}
+
+ @Override
+ public boolean isValidMaterial(String material) {
+ Material type = null;
+
+ if (Material.getMaterial(material) != null) {
+ type = Material.getMaterial(material);
+ } else if (material.contains(":")) {
+ String[] parts = material.split(Pattern.quote(":"));
+ if (parts.length > 1) {
+ if (Material.getMaterial(parts[0]) != null) {
+ type = Material.getMaterial(parts[0]);
+ }
+ }
+ }
+
+ return !(type == null);
+ }
}
diff --git a/src/main/java/com/leonardobishop/quests/hooks/papi/IPlaceholderAPIHook.java b/src/main/java/com/leonardobishop/quests/hooks/papi/IPlaceholderAPIHook.java
new file mode 100644
index 00000000..bc0c92a2
--- /dev/null
+++ b/src/main/java/com/leonardobishop/quests/hooks/papi/IPlaceholderAPIHook.java
@@ -0,0 +1,14 @@
+package com.leonardobishop.quests.hooks.papi;
+
+import com.leonardobishop.quests.Quests;
+import org.bukkit.entity.Player;
+
+public interface IPlaceholderAPIHook {
+
+ String replacePlaceholders(Player player, String text);
+
+ void registerExpansion(Quests plugin);
+
+ void unregisterExpansion();
+
+}
diff --git a/src/main/java/com/leonardobishop/quests/hooks/papi/PlaceholderAPIHook.java b/src/main/java/com/leonardobishop/quests/hooks/papi/PlaceholderAPIHook.java
new file mode 100644
index 00000000..13542b28
--- /dev/null
+++ b/src/main/java/com/leonardobishop/quests/hooks/papi/PlaceholderAPIHook.java
@@ -0,0 +1,29 @@
+package com.leonardobishop.quests.hooks.papi;
+
+import com.leonardobishop.quests.Quests;
+import com.leonardobishop.quests.api.QuestsPlaceholders;
+import me.clip.placeholderapi.PlaceholderAPI;
+import org.bukkit.entity.Player;
+
+public class PlaceholderAPIHook implements IPlaceholderAPIHook {
+
+ private QuestsPlaceholders placeholder;
+
+ public String replacePlaceholders(Player player, String text) {
+ return PlaceholderAPI.setPlaceholders(player, text);
+ }
+
+ @Override
+ public void registerExpansion(Quests plugin) {
+ placeholder = new QuestsPlaceholders(plugin);
+ placeholder.register();
+ }
+
+
+ @Override
+ public void unregisterExpansion() {
+ placeholder.unregister();
+ }
+
+
+}
diff --git a/src/main/java/com/leonardobishop/quests/title/Title.java b/src/main/java/com/leonardobishop/quests/hooks/title/Title.java
index 232c3b36..030d7455 100644
--- a/src/main/java/com/leonardobishop/quests/title/Title.java
+++ b/src/main/java/com/leonardobishop/quests/hooks/title/Title.java
@@ -1,4 +1,4 @@
-package com.leonardobishop.quests.title;
+package com.leonardobishop.quests.hooks.title;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/leonardobishop/quests/title/Title_Bukkit.java b/src/main/java/com/leonardobishop/quests/hooks/title/Title_Bukkit.java
index d05f815b..0f46771a 100644
--- a/src/main/java/com/leonardobishop/quests/title/Title_Bukkit.java
+++ b/src/main/java/com/leonardobishop/quests/hooks/title/Title_Bukkit.java
@@ -1,4 +1,4 @@
-package com.leonardobishop.quests.title;
+package com.leonardobishop.quests.hooks.title;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/leonardobishop/quests/title/Title_BukkitNoTimings.java b/src/main/java/com/leonardobishop/quests/hooks/title/Title_BukkitNoTimings.java
index 6bbbc32f..92ffdd16 100644
--- a/src/main/java/com/leonardobishop/quests/title/Title_BukkitNoTimings.java
+++ b/src/main/java/com/leonardobishop/quests/hooks/title/Title_BukkitNoTimings.java
@@ -1,4 +1,4 @@
-package com.leonardobishop.quests.title;
+package com.leonardobishop.quests.hooks.title;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/leonardobishop/quests/title/Title_Other.java b/src/main/java/com/leonardobishop/quests/hooks/title/Title_Other.java
index e4e998b9..ab7b7bf2 100644
--- a/src/main/java/com/leonardobishop/quests/title/Title_Other.java
+++ b/src/main/java/com/leonardobishop/quests/hooks/title/Title_Other.java
@@ -1,4 +1,4 @@
-package com.leonardobishop.quests.title;
+package com.leonardobishop.quests.hooks.title;
import org.bukkit.entity.Player;
diff --git a/src/main/java/com/leonardobishop/quests/obj/Messages.java b/src/main/java/com/leonardobishop/quests/obj/Messages.java
index b3c9ceab..92a0dca9 100644
--- a/src/main/java/com/leonardobishop/quests/obj/Messages.java
+++ b/src/main/java/com/leonardobishop/quests/obj/Messages.java
@@ -36,6 +36,8 @@ public enum Messages {
BETA_REMINDER("messages.beta-reminder"),
COMMAND_QUEST_ADMIN_LOADDATA("messages.command-quest-admin-loaddata"),
COMMAND_QUEST_ADMIN_NODATA("messages.command-quest-admin-nodata"),
+ COMMAND_QUEST_ADMIN_CLEAN_SUCCESS("messages.command-quest-admin-clean-success"),
+ COMMAND_QUEST_ADMIN_CLEAN_FAIL("messages.command-quest-admin-clean-fail"),
COMMAND_QUEST_ADMIN_FULLRESET("messages.command-quest-admin-fullreset"),
COMMAND_QUEST_ADMIN_START_FAILLOCKED("messages.command-quest-admin-start-faillocked"),
COMMAND_QUEST_ADMIN_START_FAILCOOLDOWN("messages.command-quest-admin-start-failcooldown"),
diff --git a/src/main/java/com/leonardobishop/quests/obj/Options.java b/src/main/java/com/leonardobishop/quests/obj/Options.java
index ffe8f6b7..9ed69fd7 100644
--- a/src/main/java/com/leonardobishop/quests/obj/Options.java
+++ b/src/main/java/com/leonardobishop/quests/obj/Options.java
@@ -17,11 +17,16 @@ public enum Options {
GUI_HIDE_LOCKED("options.gui-hide-locked"),
GUI_HIDE_QUESTS_NOPERMISSION("options.gui-hide-quests-nopermission"),
GUI_HIDE_CATEGORIES_NOPERMISSION("options.gui-hide-categories-nopermission"),
+ GUI_USE_PLACEHOLDERAPI("options.gui-use-placeholderapi"),
GUITITLE_QUESTS_CATEGORY("options.guinames.quests-category"),
GUITITLE_QUESTS("options.guinames.quests-menu"),
GUITITLE_DAILY_QUESTS("options.guinames.daily-quests"),
GUITITLE_QUEST_CANCEL("options.guinames.quest-cancel"),
ALLOW_QUEST_CANCEL("options.allow-quest-cancel"),
+ SOFT_CLEAN_QUESTSPROGRESSFILE_ON_JOIN("options.soft-clean-questsprogressfile-on-join"),
+ PUSH_SOFT_CLEAN_TO_DISK("options.tab-completion.push-soft-clean-to-disk"),
+ TAB_COMPLETE_ENABLED("options.tab-completion.enabled"),
+ ERROR_CHECKING_OVERRIDE("options.error-checking.override-errors"),
QUEST_AUTOSTART("options.quest-autostart");
private static final Map<String, Boolean> cachedBools = new HashMap<>();
@@ -36,10 +41,18 @@ public enum Options {
return Quests.get().getConfig().getInt(path);
}
+ public int getIntValue(int def) {
+ return Quests.get().getConfig().getInt(path, def);
+ }
+
public String getStringValue() {
return Quests.get().getConfig().getString(path);
}
+ public String getStringValue(String def) {
+ return Quests.get().getConfig().getString(path, def);
+ }
+
public boolean getBooleanValue() {
Boolean val = cachedBools.get(path);
if (val != null) {
@@ -50,6 +63,10 @@ public enum Options {
}
}
+ public boolean getBooleanValue(boolean def) {
+ return Quests.get().getConfig().getBoolean(path, def);
+ }
+
public List<String> getStringListValue() {
return Quests.get().getConfig().getStringList(path);
}
diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QItemStack.java b/src/main/java/com/leonardobishop/quests/obj/misc/QItemStack.java
index f7eca148..20bb3eb7 100644
--- a/src/main/java/com/leonardobishop/quests/obj/misc/QItemStack.java
+++ b/src/main/java/com/leonardobishop/quests/obj/misc/QItemStack.java
@@ -1,9 +1,13 @@
package com.leonardobishop.quests.obj.misc;
+import com.leonardobishop.quests.Quests;
+import com.leonardobishop.quests.obj.Options;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
import com.leonardobishop.quests.quests.Quest;
+import org.bukkit.Bukkit;
import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -15,12 +19,15 @@ import java.util.regex.Pattern;
public class QItemStack {
+ private final Quests plugin;
+
private String name;
private List<String> loreNormal;
private List<String> loreStarted;
private ItemStack startingItemStack;
- public QItemStack(String name, List<String> loreNormal, List<String> loreStarted, ItemStack startingItemStack) {
+ public QItemStack(Quests plugin, String name, List<String> loreNormal, List<String> loreStarted, ItemStack startingItemStack) {
+ this.plugin = plugin;
this.name = name;
this.loreNormal = loreNormal;
this.loreStarted = loreStarted;
@@ -66,6 +73,8 @@ public class QItemStack {
ism.setDisplayName(name);
List<String> formattedLore = new ArrayList<>();
List<String> tempLore = new ArrayList<>(loreNormal);
+
+ Player player = Bukkit.getPlayer(questProgressFile.getPlayerUUID());
if (questProgressFile.hasStartedQuest(quest)) {
tempLore.addAll(loreStarted);
ism.addEnchant(Enchantment.ARROW_INFINITE, 1, true);
@@ -76,6 +85,9 @@ public class QItemStack {
}
}
+ if (plugin.getPlaceholderAPIHook() != null && Options.GUI_USE_PLACEHOLDERAPI.getBooleanValue()) {
+ ism.setDisplayName(plugin.getPlaceholderAPIHook().replacePlaceholders(player, ism.getDisplayName()));
+ }
if (questProgress != null) {
for (String s : tempLore) {
Matcher m = Pattern.compile("\\{([^}]+)}").matcher(s);
@@ -95,6 +107,9 @@ public class QItemStack {
}
}
}
+ if (plugin.getPlaceholderAPIHook() != null && Options.GUI_USE_PLACEHOLDERAPI.getBooleanValue()) {
+ s = plugin.getPlaceholderAPIHook().replacePlaceholders(player, s);
+ }
formattedLore.add(s);
}
}
diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCancel.java b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCancel.java
index 9a4a2c4d..72445aaf 100644
--- a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCancel.java
+++ b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCancel.java
@@ -1,11 +1,10 @@
package com.leonardobishop.quests.obj.misc;
-import com.leonardobishop.quests.player.QPlayer;
-import com.leonardobishop.quests.quests.Quest;
import com.leonardobishop.quests.obj.Items;
import com.leonardobishop.quests.obj.Options;
+import com.leonardobishop.quests.player.QPlayer;
+import com.leonardobishop.quests.quests.Quest;
import org.bukkit.Bukkit;
-import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -78,22 +77,4 @@ public class QMenuCancel implements QMenu {
return superMenu;
}
- public ItemStack replaceItemStack(ItemStack is, Map<String, String> placeholders) {
- ItemStack newItemStack = is.clone();
- List<String> lore = newItemStack.getItemMeta().getLore();
- List<String> newLore = new ArrayList<>();
- ItemMeta ism = newItemStack.getItemMeta();
- if (lore != null) {
- for (String s : lore) {
- for (Map.Entry<String, String> entry : placeholders.entrySet()) {
- s = s.replace(entry.getKey(), entry.getValue());
- ism.setDisplayName(ism.getDisplayName().replace(entry.getKey(), entry.getValue()));
- }
- newLore.add(s);
- }
- }
- ism.setLore(newLore);
- newItemStack.setItemMeta(ism);
- return newItemStack;
- }
}
diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCategory.java b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCategory.java
index 3418831f..86f4d57f 100644
--- a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCategory.java
+++ b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuCategory.java
@@ -1,14 +1,17 @@
package com.leonardobishop.quests.obj.misc;
-import com.leonardobishop.quests.player.QPlayer;
-import com.leonardobishop.quests.quests.Category;
import com.leonardobishop.quests.Quests;
import com.leonardobishop.quests.obj.Options;
+import com.leonardobishop.quests.player.QPlayer;
+import com.leonardobishop.quests.quests.Category;
import org.bukkit.Bukkit;
import org.bukkit.Material;
+import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -17,11 +20,13 @@ import java.util.List;
*/
public class QMenuCategory implements QMenu {
+ private final Quests plugin;
private final int pageSize = 45;
private final HashMap<Integer, QMenuQuest> slotsToMenuQuest = new HashMap<>();
private final QPlayer owner;
- public QMenuCategory(QPlayer owner) {
+ public QMenuCategory(Quests plugin, QPlayer owner) {
+ this.plugin = plugin;
this.owner = owner;
}
@@ -61,12 +66,12 @@ public class QMenuCategory implements QMenu {
if (slotsToMenuQuest.containsKey(pointer)) {
Category category = Quests.get().getQuestManager().getCategoryById(slotsToMenuQuest.get(pointer).getCategoryName());
if (category != null) {
- inventory.setItem(pointer, category.getDisplayItem());
+ inventory.setItem(pointer, replaceItemStack(category.getDisplayItem()));
}
}
}
- inventory.setItem(49, pageIs);
+ inventory.setItem(49, replaceItemStack(pageIs));
if (Options.TRIM_GUI_SIZE.getBooleanValue() && page == 1) {
int slotsUsed = 0;
@@ -85,7 +90,7 @@ public class QMenuCategory implements QMenu {
Inventory trimmedInventory = Bukkit.createInventory(null, inventorySize, title);
for (int slot = 0; slot < pageMax; slot++) {
- if (slot >= trimmedInventory.getSize()){
+ if (slot >= trimmedInventory.getSize()) {
break;
}
trimmedInventory.setItem(slot, inventory.getItem(slot));
@@ -97,4 +102,25 @@ public class QMenuCategory implements QMenu {
}
+ public ItemStack replaceItemStack(ItemStack is) {
+ if (plugin.getPlaceholderAPIHook() != null && Options.GUI_USE_PLACEHOLDERAPI.getBooleanValue()) {
+ ItemStack newItemStack = is.clone();
+ List<String> lore = newItemStack.getItemMeta().getLore();
+ List<String> newLore = new ArrayList<>();
+ ItemMeta ism = newItemStack.getItemMeta();
+ Player player = Bukkit.getPlayer(owner.getUuid());
+ ism.setDisplayName(plugin.getPlaceholderAPIHook().replacePlaceholders(player, ism.getDisplayName()));
+ if (lore != null) {
+ for (String s : lore) {
+ s = plugin.getPlaceholderAPIHook().replacePlaceholders(player, s);
+ newLore.add(s);
+ }
+ }
+ ism.setLore(newLore);
+ newItemStack.setItemMeta(ism);
+ return newItemStack;
+ }
+ return is;
+ }
+
}
diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuDaily.java b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuDaily.java
index 220f288a..0e0cc132 100644
--- a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuDaily.java
+++ b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuDaily.java
@@ -1,8 +1,8 @@
package com.leonardobishop.quests.obj.misc;
+import com.leonardobishop.quests.obj.Options;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.quests.Quest;
-import com.leonardobishop.quests.obj.Options;
import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
@@ -99,22 +99,6 @@ public class QMenuDaily implements QMenu {
return Bukkit.createInventory(null, 27, title);
}
- public ItemStack replaceItemStack(ItemStack is, Map<String, String> placeholders) {
- ItemStack newItemStack = is.clone();
- List<String> lore = newItemStack.getItemMeta().getLore();
- List<String> newLore = new ArrayList<>();
- for (String s : lore) {
- for (Map.Entry<String, String> entry : placeholders.entrySet()) {
- s = s.replace(entry.getKey(), entry.getValue());
- }
- newLore.add(s);
- }
- ItemMeta ism = newItemStack.getItemMeta();
- ism.setLore(newLore);
- newItemStack.setItemMeta(ism);
- return newItemStack;
- }
-
//Implement too
public QMenuCategory getSuperMenu() {
return this.superMenu;
diff --git a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuQuest.java b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuQuest.java
index 622e4558..dbaf23ff 100644
--- a/src/main/java/com/leonardobishop/quests/obj/misc/QMenuQuest.java
+++ b/src/main/java/com/leonardobishop/quests/obj/misc/QMenuQuest.java
@@ -1,12 +1,13 @@
package com.leonardobishop.quests.obj.misc;
-import com.leonardobishop.quests.player.QPlayer;
-import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
-import com.leonardobishop.quests.quests.Quest;
import com.leonardobishop.quests.Quests;
import com.leonardobishop.quests.obj.Items;
import com.leonardobishop.quests.obj.Options;
+import com.leonardobishop.quests.player.QPlayer;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
+import com.leonardobishop.quests.quests.Quest;
import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -19,18 +20,21 @@ import java.util.concurrent.TimeUnit;
*/
public class QMenuQuest implements QMenu {
+ private final Quests plugin;
private final HashMap<Integer, String> slotsToQuestIds = new HashMap<>();
+ private final QMenuCategory superMenu;
+ private final String categoryName;
+ private final int pageSize = 45;
+ private final QPlayer owner;
+
private int backButtonLocation = -1;
private int pagePrevLocation = -1;
private int pageNextLocation = -1;
private int currentPage = -1;
private boolean backButtonEnabled = true;
- private final QMenuCategory superMenu;
- private final String categoryName;
- private final int pageSize = 45;
- private final QPlayer owner;
- public QMenuQuest(QPlayer owner, String categoryName, QMenuCategory superMenu) {
+ public QMenuQuest(Quests plugin, QPlayer owner, String categoryName, QMenuCategory superMenu) {
+ this.plugin = plugin;
this.owner = owner;
this.categoryName = categoryName;
this.superMenu = superMenu;
@@ -133,7 +137,8 @@ public class QMenuQuest implements QMenu {
ItemStack is = replaceItemStack(Items.QUEST_COOLDOWN.getItem(), placeholders);
inventory.setItem(invSlot, is);
} else {
- inventory.setItem(invSlot, Quests.get().getQuestManager().getQuestById(quest.getId()).getDisplayItem().toItemStack(quest, owner.getQuestProgressFile(), questProgress));
+ inventory.setItem(invSlot, replaceItemStack(Quests.get().getQuestManager().getQuestById(
+ quest.getId()).getDisplayItem().toItemStack(quest, owner.getQuestProgressFile(), questProgress)));
}
}
invSlot++;
@@ -214,20 +219,33 @@ public class QMenuQuest implements QMenu {
return superMenu;
}
+ public ItemStack replaceItemStack(ItemStack is) {
+ return replaceItemStack(is, Collections.emptyMap());
+ }
+
public ItemStack replaceItemStack(ItemStack is, Map<String, String> placeholders) {
ItemStack newItemStack = is.clone();
List<String> lore = newItemStack.getItemMeta().getLore();
List<String> newLore = new ArrayList<>();
ItemMeta ism = newItemStack.getItemMeta();
+ Player player = Bukkit.getPlayer(owner.getUuid());
if (lore != null) {
for (String s : lore) {
for (Map.Entry<String, String> entry : placeholders.entrySet()) {
s = s.replace(entry.getKey(), entry.getValue());
- ism.setDisplayName(ism.getDisplayName().replace(entry.getKey(), entry.getValue()));
+ if (plugin.getPlaceholderAPIHook() != null && Options.GUI_USE_PLACEHOLDERAPI.getBooleanValue()) {
+ s = plugin.getPlaceholderAPIHook().replacePlaceholders(player, s);
+ }
}
newLore.add(s);
}
}
+ for (Map.Entry<String, String> entry : placeholders.entrySet()) {
+ ism.setDisplayName(ism.getDisplayName().replace(entry.getKey(), entry.getValue()));
+ if (plugin.getPlaceholderAPIHook() != null && Options.GUI_USE_PLACEHOLDERAPI.getBooleanValue()) {
+ ism.setDisplayName(plugin.getPlaceholderAPIHook().replacePlaceholders(player, ism.getDisplayName()));
+ }
+ }
ism.setLore(newLore);
newItemStack.setItemMeta(ism);
return newItemStack;
diff --git a/src/main/java/com/leonardobishop/quests/player/QPlayer.java b/src/main/java/com/leonardobishop/quests/player/QPlayer.java
index 0f4e0da5..6c270fa1 100644
--- a/src/main/java/com/leonardobishop/quests/player/QPlayer.java
+++ b/src/main/java/com/leonardobishop/quests/player/QPlayer.java
@@ -11,23 +11,20 @@ import com.leonardobishop.quests.quests.Quest;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
public class QPlayer {
private final UUID uuid;
private final QuestProgressFile questProgressFile;
- private boolean onlyDataLoaded;
private final Quests plugin;
- public QPlayer(UUID uuid, QuestProgressFile questProgressFile, Quests plugin) {
- this(uuid, questProgressFile, false, plugin);
- }
-
- public QPlayer(UUID uuid, QuestProgressFile questProgressFile, boolean onlyDataLoaded, Quests plugin) {
+ public QPlayer(UUID uuid, QuestProgressFile questProgressFile, Quests plugin) {
this.uuid = uuid;
this.questProgressFile = questProgressFile;
- this.onlyDataLoaded = onlyDataLoaded;
this.plugin = plugin;
}
@@ -39,10 +36,6 @@ public class QPlayer {
* @return 0 if success, 1 if no permission, 2 is only data loaded, 3 if player not found
*/
public int openCategory(Category category, QMenuCategory superMenu, boolean backButton) {
- if (onlyDataLoaded) {
- return 2;
- }
-
Player player = Bukkit.getPlayer(this.uuid);
if (player == null) {
return 3;
@@ -53,7 +46,7 @@ public class QPlayer {
}
// Using `this` instead of searching again for this QPlayer
- QMenuQuest qMenuQuest = new QMenuQuest(this, category.getId(), superMenu);
+ QMenuQuest qMenuQuest = new QMenuQuest(plugin, this, category.getId(), superMenu);
List<Quest> quests = new ArrayList<>();
for (String questid : category.getRegisteredQuestIds()) {
Quest quest = plugin.getQuestManager().getQuestById(questid);
@@ -70,10 +63,6 @@ public class QPlayer {
* @return 0 if success, 1 if no permission, 2 is only data loaded, 3 if player not found
*/
public int openCategory(Category category, QMenuQuest qMenuQuest) {
- if (onlyDataLoaded) {
- return 2;
- }
-
Player player = Bukkit.getPlayer(this.uuid);
if (player == null) {
return 3;
@@ -89,10 +78,6 @@ public class QPlayer {
}
public void openQuests() {
- if (onlyDataLoaded) {
- return;
- }
-
if (this.uuid == null) {
return;
}
@@ -102,10 +87,10 @@ public class QPlayer {
}
if (Options.CATEGORIES_ENABLED.getBooleanValue()) {
- QMenuCategory qMenuCategory = new QMenuCategory(plugin.getPlayerManager().getPlayer(player.getUniqueId()));
+ QMenuCategory qMenuCategory = new QMenuCategory(plugin, plugin.getPlayerManager().getPlayer(player.getUniqueId()));
List<QMenuQuest> questMenus = new ArrayList<>();
for (Category category : plugin.getQuestManager().getCategories()) {
- QMenuQuest qMenuQuest = new QMenuQuest(plugin.getPlayerManager().getPlayer(player.getUniqueId()), category.getId(), qMenuCategory);
+ QMenuQuest qMenuQuest = new QMenuQuest(plugin, plugin.getPlayerManager().getPlayer(player.getUniqueId()), category.getId(), qMenuCategory);
List<Quest> quests = new ArrayList<>();
for (String questid : category.getRegisteredQuestIds()) {
Quest quest = plugin.getQuestManager().getQuestById(questid);
@@ -121,7 +106,7 @@ public class QPlayer {
player.openInventory(qMenuCategory.toInventory(1));
EventInventory.track(player.getUniqueId(), qMenuCategory);
} else {
- QMenuQuest qMenuQuest = new QMenuQuest(plugin.getPlayerManager().getPlayer(player.getUniqueId()), "", null);
+ QMenuQuest qMenuQuest = new QMenuQuest(plugin, plugin.getPlayerManager().getPlayer(player.getUniqueId()), "", null);
List<Quest> quests = new ArrayList<>();
for (Map.Entry<String, Quest> entry : plugin.getQuestManager().getQuests().entrySet()) {
quests.add(entry.getValue());
@@ -134,14 +119,6 @@ public class QPlayer {
}
}
- public boolean isOnlyDataLoaded() {
- return onlyDataLoaded;
- }
-
- public void setOnlyDataLoaded(boolean onlyDataLoaded) {
- this.onlyDataLoaded = onlyDataLoaded;
- }
-
public QuestProgressFile getQuestProgressFile() {
return questProgressFile;
}
diff --git a/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java b/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java
index 13fa644d..d531f168 100644
--- a/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java
+++ b/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java
@@ -1,6 +1,7 @@
package com.leonardobishop.quests.player;
import com.leonardobishop.quests.Quests;
+import com.leonardobishop.quests.QuestsLogger;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
@@ -37,22 +38,28 @@ public class QPlayerManager {
* Gets the QPlayer from a given UUID.
*
* @param uuid the uuid
- * @param loadIfNull load the QPlayer if the result is null and return the QPlayer if successfully loaded
+ * @param loadIfNull do not use
* @return {@link QPlayer} if they are loaded
*/
public QPlayer getPlayer(UUID uuid, boolean loadIfNull) {
QPlayer qPlayer = qPlayers.get(uuid);
- if (qPlayer == null && loadIfNull) {
- plugin.getQuestsLogger().debug("QPlayer of " + uuid + " is null, but was requested! Attempting to load it.");
- loadPlayer(uuid, false);
- return getPlayer(uuid, false);
+ if (qPlayer == null) {
+ plugin.getQuestsLogger().debug("QPlayer of " + uuid + " is null, but was requested:");
+ if (plugin.getQuestsLogger().getServerLoggingLevel() == QuestsLogger.LoggingLevel.DEBUG) {
+ Thread.dumpStack();
+ }
}
- return qPlayers.get(uuid);
+ return qPlayer;
}
public void removePlayer(UUID uuid) {
+ plugin.getQuestsLogger().debug("Unloading and saving player " + uuid + ".");
this.getPlayer(uuid).getQuestProgressFile().saveToDisk(false);
- plugin.getQuestsLogger().debug("Unloading player " + uuid + ".");
+ qPlayers.remove(uuid);
+ }
+
+ public void dropPlayer(UUID uuid) {
+ plugin.getQuestsLogger().debug("Dropping player " + uuid + ".");
qPlayers.remove(uuid);
}
@@ -65,10 +72,9 @@ public class QPlayerManager {
// loadPlayer(uuid, false);
//}
- // TODO redo "onlyData" and use a less confusing way
- public void loadPlayer(UUID uuid, boolean onlyData) {
+ public void loadPlayer(UUID uuid) {
plugin.getQuestsLogger().debug("Loading player " + uuid + " from disk.");
- if (getPlayer(uuid) == null || getPlayer(uuid).isOnlyDataLoaded()) {
+ if (qPlayers.get(uuid) == null) {
QuestProgressFile questProgressFile = new QuestProgressFile(uuid, plugin);
try {
@@ -84,19 +90,23 @@ public class QPlayerManager {
boolean completedBefore = data.getBoolean("quest-progress." + id + ".completed-before");
long completionDate = data.getLong("quest-progress." + id + ".completion-date");
- QuestProgress questProgress = new QuestProgress(id, completed, completedBefore, completionDate, uuid, started, true);
+ QuestProgress questProgress = new QuestProgress(plugin, id, completed, completedBefore, completionDate, uuid, started, true);
- for (String taskid : data.getConfigurationSection("quest-progress." + id + ".task-progress").getKeys(false)) {
- boolean taskCompleted = data.getBoolean("quest-progress." + id + ".task-progress." + taskid + ".completed");
- Object taskProgression = data.get("quest-progress." + id + ".task-progress." + taskid + ".progress");
+ if (data.isConfigurationSection("quest-progress." + id + ".task-progress")) {
+ for (String taskid : data.getConfigurationSection("quest-progress." + id + ".task-progress").getKeys(false)) {
+ boolean taskCompleted = data.getBoolean("quest-progress." + id + ".task-progress." + taskid + ".completed");
+ Object taskProgression = data.get("quest-progress." + id + ".task-progress." + taskid + ".progress");
- TaskProgress taskProgress = new TaskProgress(taskid, taskProgression, uuid, taskCompleted, false);
- questProgress.addTaskProgress(taskProgress);
+ TaskProgress taskProgress = new TaskProgress(questProgress, taskid, taskProgression, uuid, taskCompleted, false);
+ questProgress.addTaskProgress(taskProgress);
+ }
}
questProgressFile.addQuestProgress(questProgress);
}
}
+ } else {
+ plugin.getQuestsLogger().debug("Player " + uuid + " does not have a quest progress file.");
}
}
} catch (Exception ex) {
@@ -105,9 +115,11 @@ public class QPlayerManager {
// fuck
}
- QPlayer qPlayer = new QPlayer(uuid, questProgressFile, onlyData, plugin);
+ QPlayer qPlayer = new QPlayer(uuid, questProgressFile, plugin);
this.qPlayers.put(uuid, qPlayer);
+ } else {
+ plugin.getQuestsLogger().debug("Player " + uuid + " is already loaded.");
}
}
}
diff --git a/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgress.java b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgress.java
index fe9108ce..442b802c 100644
--- a/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgress.java
+++ b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgress.java
@@ -1,5 +1,7 @@
package com.leonardobishop.quests.player.questprogressfile;
+import com.leonardobishop.quests.Quests;
+
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -7,16 +9,20 @@ import java.util.UUID;
public class QuestProgress {
- private Map<String, TaskProgress> taskProgress = new HashMap<>();
- private String questid;
+ private final Quests plugin;
+
+ private final Map<String, TaskProgress> taskProgress = new HashMap<>();
+ private final String questid;
+ private final UUID player;
+
private boolean started;
private boolean completed;
private boolean completedBefore;
private long completionDate;
- private UUID player;
private boolean modified;
- public QuestProgress(String questid, boolean completed, boolean completedBefore, long completionDate, UUID player, boolean started) {
+ public QuestProgress(Quests plugin, String questid, boolean completed, boolean completedBefore, long completionDate, UUID player, boolean started) {
+ this.plugin = plugin;
this.questid = questid;
this.completed = completed;
this.completedBefore = completedBefore;
@@ -25,8 +31,8 @@ public class QuestProgress {
this.started = started;
}
- public QuestProgress(String questid, boolean completed, boolean completedBefore, long completionDate, UUID player, boolean started, boolean modified) {
- this(questid, completed, completedBefore, completionDate, player, started);
+ public QuestProgress(Quests plugin, String questid, boolean completed, boolean completedBefore, long completionDate, UUID player, boolean started, boolean modified) {
+ this(plugin, questid, completed, completedBefore, completionDate, player, started);
this.modified = modified;
}
@@ -82,6 +88,10 @@ public class QuestProgress {
return taskProgress.values();
}
+ public Map<String, TaskProgress> getTaskProgressMap() {
+ return taskProgress;
+ }
+
public TaskProgress getTaskProgress(String taskId) {
TaskProgress tP = taskProgress.getOrDefault(taskId, null);
if (tP == null) {
@@ -92,10 +102,11 @@ public class QuestProgress {
}
public void repairTaskProgress(String taskid) {
- TaskProgress taskProgress = new TaskProgress(taskid, null, player, false, false);
+ TaskProgress taskProgress = new TaskProgress(this, taskid, null, player, false, false);
this.addTaskProgress(taskProgress);
}
+ @Deprecated // this shit is annoying to maintain
public boolean isWorthSaving() {
if (modified) return true;
else {
@@ -106,6 +117,10 @@ public class QuestProgress {
}
}
+ public void queueForCompletionTest() {
+ plugin.getQuestCompleter().queueSingular(this);
+ }
+
public void resetModified() {
this.modified = false;
for (TaskProgress progress : this.taskProgress.values()) {
diff --git a/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java
index d3689185..83dcb80a 100644
--- a/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java
+++ b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java
@@ -36,6 +36,10 @@ public class QuestProgressFile {
public boolean completeQuest(Quest quest) {
QuestProgress questProgress = getQuestProgress(quest);
questProgress.setStarted(false);
+ for (TaskProgress taskProgress : questProgress.getTaskProgress()) {
+ taskProgress.setCompleted(false);
+ taskProgress.setProgress(null);
+ }
questProgress.setCompleted(true);
questProgress.setCompletedBefore(true);
questProgress.setCompletionDate(System.currentTimeMillis());
@@ -76,7 +80,7 @@ public class QuestProgressFile {
*/
public QuestStartResult canStartQuest(Quest quest) {
Player p = Bukkit.getPlayer(playerUUID);
- if (getStartedQuests().size() >= Options.QUESTS_START_LIMIT.getIntValue()) {
+ if (getStartedQuests().size() >= Options.QUESTS_START_LIMIT.getIntValue() && !Options.QUEST_AUTOSTART.getBooleanValue()) {
return QuestStartResult.QUEST_LIMIT_REACHED;
}
QuestProgress questProgress = getQuestProgress(quest);
@@ -194,6 +198,13 @@ public class QuestProgressFile {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', s));
}
}
+ for (Task task : quest.getTasks()) {
+ try {
+ plugin.getTaskTypeManager().getTaskType(task.getType()).onStart(quest, task, playerUUID);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
}
return code;
}
@@ -367,9 +378,9 @@ public class QuestProgressFile {
public boolean generateBlankQuestProgress(String questid) {
if (plugin.getQuestManager().getQuestById(questid) != null) {
Quest quest = plugin.getQuestManager().getQuestById(questid);
- QuestProgress questProgress = new QuestProgress(quest.getId(), false, false, 0, playerUUID, false, false);
+ QuestProgress questProgress = new QuestProgress(plugin, quest.getId(), false, false, 0, playerUUID, false, false);
for (Task task : quest.getTasks()) {
- TaskProgress taskProgress = new TaskProgress(task.getId(), null, playerUUID, false, false);
+ TaskProgress taskProgress = new TaskProgress(questProgress, task.getId(), null, playerUUID, false, false);
questProgress.addTaskProgress(taskProgress);
}
@@ -379,7 +390,15 @@ public class QuestProgressFile {
return false;
}
+ public void saveToDisk() {
+ saveToDisk(false, false);
+ }
+
public void saveToDisk(boolean disable) {
+ saveToDisk(disable, false);
+ }
+
+ public void saveToDisk(boolean disable, boolean fullWrite) {
plugin.getQuestsLogger().debug("Saving player " + playerUUID + " to disk.");
File directory = new File(plugin.getDataFolder() + File.separator + "playerdata");
if (!directory.exists() && !directory.isDirectory()) {
@@ -395,11 +414,8 @@ public class QuestProgressFile {
}
YamlConfiguration data = YamlConfiguration.loadConfiguration(file);
- //data.set("quest-progress", null);
+ data.set("quest-progress", null);
for (QuestProgress questProgress : questProgress.values()) {
- if (!questProgress.isWorthSaving()) {
- continue;
- }
data.set("quest-progress." + questProgress.getQuestId() + ".started", questProgress.isStarted());
data.set("quest-progress." + questProgress.getQuestId() + ".completed", questProgress.isCompleted());
data.set("quest-progress." + questProgress.getQuestId() + ".completed-before", questProgress.isCompletedBefore());
@@ -433,4 +449,33 @@ public class QuestProgressFile {
questProgress.clear();
}
+ /**
+ * Removes any references to quests or tasks which are no longer defined in the config
+ */
+ public void clean() {
+ plugin.getQuestsLogger().debug("Cleaning file " + playerUUID + ".");
+ if (!plugin.getTaskTypeManager().areRegistrationsAccepted()) {
+ ArrayList<String> invalidQuests = new ArrayList<>();
+ for (String questId : this.questProgress.keySet()) {
+ Quest q;
+ if ((q = plugin.getQuestManager().getQuestById(questId)) == null) {
+ invalidQuests.add(questId);
+ } else {
+ ArrayList<String> invalidTasks = new ArrayList<>();
+ for (String taskId : this.questProgress.get(questId).getTaskProgressMap().keySet()) {
+ if (q.getTaskById(taskId) == null) {
+ invalidTasks.add(taskId);
+ }
+ }
+ for (String taskId : invalidTasks) {
+ this.questProgress.get(questId).getTaskProgressMap().remove(taskId);
+ }
+ }
+ }
+ for (String questId : invalidQuests) {
+ this.questProgress.remove(questId);
+ }
+ }
+ }
+
}
diff --git a/src/main/java/com/leonardobishop/quests/player/questprogressfile/TaskProgress.java b/src/main/java/com/leonardobishop/quests/player/questprogressfile/TaskProgress.java
index a4c71460..fa361a7a 100644
--- a/src/main/java/com/leonardobishop/quests/player/questprogressfile/TaskProgress.java
+++ b/src/main/java/com/leonardobishop/quests/player/questprogressfile/TaskProgress.java
@@ -4,20 +4,24 @@ import java.util.UUID;
public class TaskProgress {
+ private final QuestProgress questProgress;
+ private final String taskid;
+ private final UUID player;
+
private boolean modified;
- private String taskid;
private Object progress;
- private UUID player;
private boolean completed;
- public TaskProgress(String taskid, Object progress, UUID player, boolean completed) {
+ public TaskProgress(QuestProgress questProgress, String taskid, Object progress, UUID player, boolean completed) {
+ this.questProgress = questProgress;
this.taskid = taskid;
this.progress = progress;
+ this.player = player;
this.completed = completed;
}
- public TaskProgress(String taskid, Object progress, UUID player, boolean completed, boolean modified) {
- this(taskid, progress, player, completed);
+ public TaskProgress(QuestProgress questProgress, String taskid, Object progress, UUID player, boolean completed, boolean modified) {
+ this(questProgress, taskid, progress, player, completed);
this.modified = modified;
}
@@ -45,6 +49,10 @@ public class TaskProgress {
public void setCompleted(boolean complete) {
this.completed = complete;
this.modified = true;
+
+ if (complete) {
+ questProgress.queueForCompletionTest();
+ }
}
public boolean isModified() {
diff --git a/src/main/java/com/leonardobishop/quests/quests/Category.java b/src/main/java/com/leonardobishop/quests/quests/Category.java
index dd2683ed..0fdedad4 100644
--- a/src/main/java/com/leonardobishop/quests/quests/Category.java
+++ b/src/main/java/com/leonardobishop/quests/quests/Category.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests;
+import org.bukkit.ChatColor;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
@@ -7,9 +8,9 @@ import java.util.List;
public class Category {
- private String id;
- private ItemStack displayItem;
- private boolean permissionRequired;
+ private final String id;
+ private final ItemStack displayItem;
+ private final boolean permissionRequired;
private final List<String> registeredQuestIds = new ArrayList<>();
public Category(String id, ItemStack displayItem, boolean permissionRequired) {
@@ -22,26 +23,14 @@ public class Category {
return id;
}
- public void setId(String id) {
- this.id = id;
- }
-
public boolean isPermissionRequired() {
return permissionRequired;
}
- public void setPermissionRequired(boolean permissionRequired) {
- this.permissionRequired = permissionRequired;
- }
-
public ItemStack getDisplayItem() {
return displayItem;
}
- public void setDisplayItem(ItemStack displayItem) {
- this.displayItem = displayItem;
- }
-
public void registerQuestId(String questid) {
registeredQuestIds.add(questid);
}
@@ -49,4 +38,9 @@ public class Category {
public List<String> getRegisteredQuestIds() {
return registeredQuestIds;
}
+
+
+ public String getDisplayNameStripped() {
+ return ChatColor.stripColor(this.displayItem.getItemMeta().getDisplayName());
+ }
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/Quest.java b/src/main/java/com/leonardobishop/quests/quests/Quest.java
index ab02bd19..78bbc6b0 100644
--- a/src/main/java/com/leonardobishop/quests/quests/Quest.java
+++ b/src/main/java/com/leonardobishop/quests/quests/Quest.java
@@ -8,7 +8,7 @@ import java.util.*;
public class Quest implements Comparable<Quest> {
private Map<String, Task> tasks = new HashMap<>();
- //TODO: maybe store by <tasktypename (string), list<task>> since we never get task by id, but always get tasks by type.
+ //TODO: maybe ALSO store by <tasktypename (string), list<task>>
private final String id;
private final QItemStack displayItem;
private final List<String> rewards;
@@ -19,7 +19,7 @@ public class Quest implements Comparable<Quest> {
private final boolean cooldownEnabled;
private final int cooldown;
private final int sortOrder;
- private boolean permissionRequired;
+ private final boolean permissionRequired;
private String categoryid;
@@ -50,6 +50,10 @@ public class Quest implements Comparable<Quest> {
return tasks.values();
}
+ public Task getTaskById(String id) {
+ return tasks.get(id);
+ }
+
public List<Task> getTasksOfType(String type) {
List<Task> tasks = new ArrayList<>();
for (Task task : getTasks()) {
@@ -65,10 +69,6 @@ public class Quest implements Comparable<Quest> {
return permissionRequired;
}
- public void setPermissionRequired(boolean permissionRequired) {
- this.permissionRequired = permissionRequired;
- }
-
public List<String> getRewardString() {
return rewardString;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/QuestManager.java b/src/main/java/com/leonardobishop/quests/quests/QuestManager.java
index 35c13efc..022c2c89 100644
--- a/src/main/java/com/leonardobishop/quests/quests/QuestManager.java
+++ b/src/main/java/com/leonardobishop/quests/quests/QuestManager.java
@@ -2,7 +2,10 @@ package com.leonardobishop.quests.quests;
import com.leonardobishop.quests.Quests;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
public class QuestManager {
diff --git a/src/main/java/com/leonardobishop/quests/quests/Task.java b/src/main/java/com/leonardobishop/quests/quests/Task.java
index eb9cd1b4..ca0f7150 100644
--- a/src/main/java/com/leonardobishop/quests/quests/Task.java
+++ b/src/main/java/com/leonardobishop/quests/quests/Task.java
@@ -6,9 +6,8 @@ import java.util.Map;
public class Task {
private final Map<String, Object> configValues = new HashMap<>();
-
- private String id;
- private String type;
+ private final String id;
+ private final String type;
public Task(String id, String type) {
this.id = id;
@@ -27,6 +26,10 @@ public class Task {
return configValues.getOrDefault(key, null); //??? this will return null without the need of `OrDefault(key, null)`
}
+ public Object getConfigValue(String key, boolean def) {
+ return configValues.getOrDefault(key, def);
+ }
+
public Map<String, Object> getConfigValues() {
return configValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/ConfigValue.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/ConfigValue.java
index 4232da32..06a8f2f1 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/ConfigValue.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/ConfigValue.java
@@ -8,11 +8,13 @@ public final class ConfigValue {
private final String key;
private final boolean required;
private final String description;
+ private final String[] requirementExceptions;
- public ConfigValue(String key, boolean required, String description) {
+ public ConfigValue(String key, boolean required, String description, String... requirementExceptions) {
this.key = key;
this.required = required;
this.description = description;
+ this.requirementExceptions = requirementExceptions;
}
public String getKey() {
@@ -26,4 +28,8 @@ public final class ConfigValue {
public String getDescription() {
return description;
}
+
+ public String[] getRequirementExceptions() {
+ return requirementExceptions;
+ }
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskType.java
index 1e8a0433..a085a89c 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskType.java
@@ -1,11 +1,11 @@
package com.leonardobishop.quests.quests.tasktypes;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.quests.Quest;
+import com.leonardobishop.quests.quests.Task;
import org.bukkit.event.Listener;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
/**
* A task type which can be used within Quests. A {@link Quest}
@@ -77,14 +77,34 @@ public abstract class TaskType implements Listener {
}
public List<ConfigValue> getCreatorConfigValues() {
+ // not implemented here
return Collections.emptyList();
}
+ /**
+ * Called when Quests has finished registering all quests to the task type
+ * May be called several times if an operator uses /quests admin reload
+ */
public void onReady() {
// not implemented here
}
+ /**
+ * Called when a player starts a quest containing a task of this type
+ */
+ public void onStart(Quest quest, Task task, UUID playerUUID) {
+ // not implemented here
+ }
+
public void onDisable() {
// not implemented here
}
+
+ /**
+ * Called when Quests reloads the configuration - used to detect errors in the configuration of your task type
+ */
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ // not implemented here
+ return Collections.emptyList();
+ }
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskTypeManager.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskTypeManager.java
index 7b01d463..d5196af0 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskTypeManager.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskTypeManager.java
@@ -9,7 +9,7 @@ import java.util.ArrayList;
public class TaskTypeManager {
- private Quests plugin;
+ private final Quests plugin;
private boolean allowRegistrations;
public TaskTypeManager(Quests plugin) {
@@ -21,6 +21,10 @@ public class TaskTypeManager {
allowRegistrations = false;
}
+ public boolean areRegistrationsAccepted() {
+ return allowRegistrations;
+ }
+
private ArrayList<TaskType> taskTypes = new ArrayList<>();
public ArrayList<TaskType> getTaskTypes() {
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskUtils.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskUtils.java
index e036a4c1..f7f2768b 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskUtils.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/TaskUtils.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.quests.Task;
import org.bukkit.entity.Player;
@@ -36,4 +37,51 @@ public class TaskUtils {
return true;
}
+
+ public static void configValidateInt(String path, Object object, List<QuestsConfigLoader.ConfigProblem> problems, boolean allowNull, boolean greaterThanZero, String... args) {
+ if (object == null) {
+ if (!allowNull) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.ERROR,
+ String.format("Expected an integer for '%s', but got null instead", (Object[]) args), path));
+ }
+ return;
+ }
+
+ try {
+ Integer i = (Integer) object;
+ if (greaterThanZero && i <= 0) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.ERROR,
+ String.format("Value for field '%s' must be greater than 0", (Object[]) args), path));
+ }
+ } catch (ClassCastException ex) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.ERROR,
+ String.format("Expected an integer for '%s', but got '" + object + "' instead", (Object[]) args), path));
+ }
+ }
+
+ public static void configValidateBoolean(String path, Object object, List<QuestsConfigLoader.ConfigProblem> problems, boolean allowNull, String... args) {
+ if (object == null) {
+ if (!allowNull) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.ERROR,
+ String.format("Expected a boolean for '%s', but got null instead", (Object[]) args), path));
+ }
+ return;
+ }
+
+ try {
+ Boolean b = (Boolean) object;
+ } catch (ClassCastException ex) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.ERROR,
+ String.format("Expected a boolean for '%s', but got '" + object + "' instead", (Object[]) args), path));
+ }
+ }
+
+ public static boolean configValidateExists(String path, Object object, List<QuestsConfigLoader.ConfigProblem> problems, String... args) {
+ if (object == null) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.ERROR,
+ String.format(QuestsConfigLoader.ConfigProblemDescriptions.TASK_MISSING_FIELD.getDescription(args), (Object[]) args), path));
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BreedingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BreedingTaskType.java
index b18bcd08..5130815e 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BreedingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BreedingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -18,6 +19,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class BreedingTaskType extends TaskType {
@@ -31,6 +33,14 @@ public final class BreedingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingTaskType.java
index fdee1dc9..15a02d03 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BrewingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -38,6 +39,14 @@ public final class BrewingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingCertainTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingCertainTaskType.java
index 73252665..44e49c97 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingCertainTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingCertainTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -18,6 +19,7 @@ import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class BuildingCertainTaskType extends TaskType {
@@ -35,6 +37,43 @@ public final class BuildingCertainTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ if (config.get("block") == null && config.get("blocks") == null) {
+ TaskUtils.configValidateExists(root + ".block", config.get("block"), problems, "block", super.getType());
+ } else {
+ Object configBlock;
+ String source;
+ if (config.containsKey("block")) {
+ source = "block";
+ } else {
+ source = "blocks";
+ }
+ configBlock = config.get(source);
+ List<String> checkBlocks = new ArrayList<>();
+ if (configBlock instanceof List) {
+ checkBlocks.addAll((List) configBlock);
+ } else {
+ checkBlocks.add(String.valueOf(configBlock));
+ }
+
+ for (String materialName : checkBlocks) {
+ String[] split = materialName.split(":");
+ if (Material.getMaterial(String.valueOf(split[0])) == null) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ QuestsConfigLoader.ConfigProblemDescriptions.UNKNOWN_MATERIAL.getDescription(materialName), root + "." + source));
+ }
+ }
+ }
+ TaskUtils.configValidateBoolean(root + ".reverse-if-broken", config.get("reverse-if-broken"), problems, true,"reverse-if-broken");
+ TaskUtils.configValidateBoolean(root + ".use-similar-blocks", config.get("use-similar-blocks"), problems, true,"use-similar-blocks");
+ TaskUtils.configValidateInt(root + ".data", config.get("data"), problems, true,true, "data");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
@@ -123,8 +162,9 @@ public final class BuildingCertainTaskType extends TaskType {
short blockData = block.getData();
- if (blockType.equals(material)) {
- return configData == null || ((int) blockData) == comparableData;
+ if (blockType == material) {
+ if (((split.length == 1 && configData == null) || ((int) blockData) == comparableData))
+ return true;
}
}
return false;
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingTaskType.java
index b25c70af..bf8d9172 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BuildingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -15,6 +16,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockPlaceEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class BuildingTaskType extends TaskType {
@@ -28,6 +30,14 @@ public final class BuildingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CommandTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CommandTaskType.java
new file mode 100644
index 00000000..4a1d096c
--- /dev/null
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CommandTaskType.java
@@ -0,0 +1,96 @@
+package com.leonardobishop.quests.quests.tasktypes.types;
+
+import com.leonardobishop.quests.QuestsConfigLoader;
+import com.leonardobishop.quests.api.QuestsAPI;
+import com.leonardobishop.quests.player.QPlayer;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
+import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
+import com.leonardobishop.quests.quests.Quest;
+import com.leonardobishop.quests.quests.Task;
+import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
+import com.leonardobishop.quests.quests.tasktypes.TaskType;
+import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public final class CommandTaskType extends TaskType {
+
+ private List<ConfigValue> creatorConfigValues = new ArrayList<>();
+
+ public CommandTaskType() {
+ super("command", "LMBishop", "Execute a certain command.");
+ this.creatorConfigValues.add(new ConfigValue("command", true, "The command to execute."));
+ this.creatorConfigValues.add(new ConfigValue("ignore-case", false, "Ignore the casing of the command."));
+ this.creatorConfigValues.add(new ConfigValue("worlds", false, "Permitted worlds the player must be in."));
+ }
+
+ @Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ TaskUtils.configValidateExists(root + ".command", config.get("command"), problems, "command", super.getType());
+ TaskUtils.configValidateBoolean(root + ".ignore-case", config.get("ignore-case"), problems, true, "ignore-case", super.getType());
+ return problems;
+ }
+
+ @Override
+ public List<ConfigValue> getCreatorConfigValues() {
+ return creatorConfigValues;
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void onCommand(PlayerCommandPreprocessEvent e) {
+ Player player = e.getPlayer();
+
+ QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(player.getUniqueId(), true);
+ QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
+
+ for (Quest quest : super.getRegisteredQuests()) {
+ if (questProgressFile.hasStartedQuest(quest)) {
+ QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
+
+ for (Task task : quest.getTasksOfType(super.getType())) {
+ if (!TaskUtils.validateWorld(player, task)) continue;
+
+ TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
+
+ if (taskProgress.isCompleted()) {
+ continue;
+ }
+ Object configCommand = task.getConfigValue("command");
+ Object configIgnoreCase = task.getConfigValue("ignore-case");
+
+ List<String> commands = new ArrayList<>();
+ if (configCommand instanceof List) {
+ commands.addAll((List) configCommand);
+ } else {
+ commands.add(String.valueOf(configCommand));
+ }
+
+ boolean ignoreCasing = false;
+ if (configIgnoreCase != null) {
+ ignoreCasing = (boolean) task.getConfigValue("ignore-case");
+ }
+ String message = e.getMessage();
+ if (message.length() >= 1) {
+ message = message.substring(1);
+ }
+
+ for (String command : commands) {
+ if (ignoreCasing && command.equalsIgnoreCase(message)) {
+ taskProgress.setCompleted(true);
+ } else if (!ignoreCasing && command.equals(message)) {
+ taskProgress.setCompleted(true);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DealDamageTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DealDamageTaskType.java
index 277f1fff..b0c1f48b 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DealDamageTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DealDamageTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -16,6 +17,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class DealDamageTaskType extends TaskType {
@@ -29,6 +31,14 @@ public final class DealDamageTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
@@ -71,6 +81,7 @@ public final class DealDamageTaskType extends TaskType {
taskProgress.setProgress(progressDamage + damage);
if (((double) taskProgress.getProgress()) >= (double) damageNeeded) {
+ taskProgress.setProgress(damageNeeded);
taskProgress.setCompleted(true);
}
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DistancefromTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DistancefromTaskType.java
index bc181249..e40df767 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DistancefromTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DistancefromTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -9,6 +10,7 @@ import com.leonardobishop.quests.quests.Quest;
import com.leonardobishop.quests.quests.Task;
import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
import com.leonardobishop.quests.quests.tasktypes.TaskType;
+import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
@@ -18,6 +20,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class DistancefromTaskType extends TaskType {
@@ -34,10 +37,39 @@ public final class DistancefromTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".x", config.get("x"), problems, "x", super.getType()))
+ TaskUtils.configValidateInt(root + ".x", config.get("x"), problems, false, false, "x");
+ if (TaskUtils.configValidateExists(root + ".y", config.get("y"), problems, "y", super.getType()))
+ TaskUtils.configValidateInt(root + ".y", config.get("y"), problems, false, false, "y");
+ if (TaskUtils.configValidateExists(root + ".z", config.get("z"), problems, "z", super.getType()))
+ TaskUtils.configValidateInt(root + ".z", config.get("z"), problems, false, false, "z");
+ if (TaskUtils.configValidateExists(root + ".distance", config.get("distance"), problems, "distance", super.getType()))
+ TaskUtils.configValidateInt(root + ".distance", config.get("distance"), problems, false, true, "distance");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
+// private HashMap<String, HashMap<String, Integer>> distanceSquaredCache = new HashMap<>();
+//
+// @Override
+// public void onReady() {
+// distanceSquaredCache.clear();
+// for (Quest quest : super.getRegisteredQuests()) {
+// HashMap<String, Integer> squaredDistances = new HashMap<>();
+// for (Task task : quest.getTasksOfType(super.getType())) {
+// int distance = (int) task.getConfigValue("distance");
+// squaredDistances.put(task.getId(), distance);
+// }
+// distanceSquaredCache.put(quest.getId(), squaredDistances);
+// }
+// }
+
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onMove(PlayerMoveEvent event) {
if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) {
@@ -65,14 +97,15 @@ public final class DistancefromTaskType extends TaskType {
int z = (int) task.getConfigValue("z");
String worldString = (String) task.getConfigValue("world");
int distance = (int) task.getConfigValue("distance");
+ int distanceSquared = distance * distance;
World world = Bukkit.getWorld(worldString);
if (world == null) {
- return;
+ continue;
}
Location location = new Location(world, x, y, z);
- if (player.getWorld().equals(world) && player.getLocation().distance(location) > distance) {
+ if (player.getWorld().equals(world) && player.getLocation().distanceSquared(location) > distanceSquared) {
taskProgress.setCompleted(true);
}
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/EnchantingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/EnchantingTaskType.java
index aee02dc4..768c597e 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/EnchantingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/EnchantingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -16,6 +17,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.enchantment.EnchantItemEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class EnchantingTaskType extends TaskType {
@@ -29,6 +31,14 @@ public final class EnchantingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ExpEarnTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ExpEarnTaskType.java
index b1731dd7..b5a70b1a 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ExpEarnTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ExpEarnTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -15,6 +16,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerExpChangeEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class ExpEarnTaskType extends TaskType {
@@ -26,7 +28,15 @@ public final class ExpEarnTaskType extends TaskType {
this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of exp that needs to be earned."));
this.creatorConfigValues.add(new ConfigValue("worlds", false, "Permitted worlds the player must be in."));
}
-
+
+ @Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
@Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FishingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FishingTaskType.java
index 5e57a0c1..340eebc0 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FishingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/FishingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -16,6 +17,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerFishEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class FishingTaskType extends TaskType {
@@ -29,6 +31,14 @@ public final class FishingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/InventoryTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/InventoryTaskType.java
index 74caace5..93a4763f 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/InventoryTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/InventoryTaskType.java
@@ -1,6 +1,7 @@
package com.leonardobishop.quests.quests.tasktypes.types;
import com.leonardobishop.quests.Quests;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -13,16 +14,16 @@ import com.leonardobishop.quests.quests.tasktypes.TaskType;
import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
-import org.bukkit.event.inventory.InventoryClickEvent;
-import org.bukkit.event.inventory.InventoryDragEvent;
-import org.bukkit.event.inventory.InventoryInteractEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class InventoryTaskType extends TaskType {
@@ -33,6 +34,7 @@ public final class InventoryTaskType extends TaskType {
super("inventory", "LMBishop", "Obtain a set of items.");
this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of item to retrieve."));
this.creatorConfigValues.add(new ConfigValue("item", true, "Name or ID of item."));
+ this.creatorConfigValues.add(new ConfigValue("data", false, "Data of item."));
this.creatorConfigValues.add(new ConfigValue("remove-items-when-complete", false, "Take the items away from the player on completion (true/false, " +
"default = false)."));
this.creatorConfigValues.add(new ConfigValue("update-progress", false, "Update the displayed progress (if this causes lag then disable it)."));
@@ -40,6 +42,43 @@ public final class InventoryTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".item", config.get("item"), problems, "item", super.getType())) {
+ Object configBlock = config.get("item");
+ if (configBlock instanceof ConfigurationSection) {
+ ConfigurationSection section = (ConfigurationSection) configBlock;
+ String itemloc = "item";
+ if (!section.contains("item")) {
+ itemloc = "type";
+ }
+ if (!section.contains(itemloc)) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ QuestsConfigLoader.ConfigProblemDescriptions.UNKNOWN_MATERIAL.getDescription(""), root + ".item.type"));
+ } else {
+ String type = String.valueOf(section.get(itemloc));
+ if (!Quests.get().getItemGetter().isValidMaterial(type)) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ QuestsConfigLoader.ConfigProblemDescriptions.UNKNOWN_MATERIAL.getDescription(type), root + ".item." + itemloc));
+ }
+ }
+ } else {
+ if (Material.getMaterial(String.valueOf(configBlock)) == null) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ QuestsConfigLoader.ConfigProblemDescriptions.UNKNOWN_MATERIAL.getDescription(String.valueOf(configBlock)), root + ".item.item"));
+ }
+ }
+ }
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ TaskUtils.configValidateInt(root + ".data", config.get("data"), problems, true, false, "data");
+ TaskUtils.configValidateBoolean(root + ".remove-items-when-complete", config.get("remove-items-when-complete"), problems, true, "remove-items-when-complete", super.getType());
+ TaskUtils.configValidateBoolean(root + ".update-progress", config.get("update-progress"), problems, true, "update-progress", super.getType());
+ return problems;
+ }
+
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
@@ -50,13 +89,17 @@ public final class InventoryTaskType extends TaskType {
Bukkit.getScheduler().runTaskLater(Quests.get(), () -> this.checkInventory(event.getPlayer()), 1L);
}
- @EventHandler(priority = EventPriority.MONITOR/*, ignoreCancelled = true*/)
- public void onInventoryClick(InventoryClickEvent event) {
- Bukkit.getScheduler().runTaskLater(Quests.get(), () -> checkInventory((Player) event.getWhoClicked()), 1L); //Still some work to do as it doesn't really work
+ @EventHandler(priority = EventPriority.MONITOR)
+ public void onInventoryClick(InventoryCloseEvent event) {
+ Bukkit.getScheduler().runTaskLater(Quests.get(), () -> checkInventory((Player) event.getPlayer()), 1L); //Still some work to do as it doesn't really work
}
@SuppressWarnings("deprecation")
private void checkInventory(Player player) {
+ if (player == null || !player.isOnline()) {
+ return;
+ }
+
QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(player.getUniqueId(), true);
if (qPlayer == null) {
return;
@@ -83,21 +126,28 @@ public final class InventoryTaskType extends TaskType {
Object configData = task.getConfigValue("data");
Object remove = task.getConfigValue("remove-items-when-complete");
- material = Material.getMaterial(String.valueOf(configBlock));
-
-
- if (material == null) {
- continue;
- }
ItemStack is;
- if (configData != null) {
- is = new ItemStack(material, 1, ((Integer) configData).shortValue());
+ if (configBlock instanceof ConfigurationSection) {
+ is = Quests.get().getItemStack("", (org.bukkit.configuration.ConfigurationSection) configBlock);
} else {
- is = new ItemStack(material, 1);
+ material = Material.getMaterial(String.valueOf(configBlock));
+
+ if (material == null) {
+ continue;
+ }
+ if (configData != null) {
+ is = new ItemStack(material, 1, ((Integer) configData).shortValue());
+ } else {
+ is = new ItemStack(material, 1);
+ }
}
- if (task.getConfigValue("update-progress") != null && (Boolean) task.getConfigValue("update-progress")) {
- taskProgress.setProgress(getAmount(player, is, amount));
+ if (task.getConfigValue("update-progress") != null
+ && (Boolean) task.getConfigValue("update-progress")) {
+ int inInv = getAmount(player, is, amount);
+ if (taskProgress.getProgress() != null && (int) taskProgress.getProgress() != inInv) {
+ taskProgress.setProgress(inInv);
+ }
}
if (player.getInventory().containsAtLeast(is, amount)) {
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/IridiumSkyblockValueType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/IridiumSkyblockValueType.java
deleted file mode 100644
index 028ae2c1..00000000
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/IridiumSkyblockValueType.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.leonardobishop.quests.quests.tasktypes.types;
-
-import com.iridium.iridiumskyblock.Island;
-import com.iridium.iridiumskyblock.User;
-import com.leonardobishop.quests.Quests;
-import com.leonardobishop.quests.api.QuestsAPI;
-import com.leonardobishop.quests.player.QPlayer;
-import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
-import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
-import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
-import com.leonardobishop.quests.quests.Quest;
-import com.leonardobishop.quests.quests.Task;
-import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
-import com.leonardobishop.quests.quests.tasktypes.TaskType;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-import org.bukkit.scheduler.BukkitRunnable;
-import org.bukkit.scheduler.BukkitTask;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public final class IridiumSkyblockValueType extends TaskType {
-
- private List<ConfigValue> creatorConfigValues = new ArrayList<>();
- private BukkitTask poll;
-
- public IridiumSkyblockValueType() {
- super("iridiumskyblock_value", "LMBishop", "Reach a certain island value for Iridium Skyblock.");
- this.creatorConfigValues.add(new ConfigValue("value", true, "Minimum island value needed."));
- }
-
- @Override
- public void onReady() {
- this.poll = new BukkitRunnable() {
- @Override
- public void run() {
- for (Player player : Bukkit.getOnlinePlayers()) {
- Island island = null;
- if ((island = User.getUser(player).getIsland()) == null) {
- return;
- }
-
- QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(player.getUniqueId(), true);
- if (qPlayer == null) {
- return;
- }
-
- QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
-
- for (Quest quest : IridiumSkyblockValueType.super.getRegisteredQuests()) {
- if (questProgressFile.hasStartedQuest(quest)) {
- QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
-
- for (Task task : quest.getTasksOfType(IridiumSkyblockValueType.super.getType())) {
- TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
-
- if (taskProgress.isCompleted()
- || (taskProgress.getProgress() != null && (int) taskProgress.getProgress() == island.getValue())) {
- continue;
- }
-
- int islandValueNeeded = (int) task.getConfigValue("value");
-
- taskProgress.setProgress(island.getValue());
-
- if (((int) taskProgress.getProgress()) >= islandValueNeeded) {
- taskProgress.setCompleted(true);
- }
- }
- }
- }
- }
- }
- }.runTaskTimer(Quests.get(), 50L, 50L);
- }
-
- @Override
- public void onDisable() {
- if (this.poll != null) {
- this.poll.cancel();
- }
- }
-
- @Override
- public List<ConfigValue> getCreatorConfigValues() {
- return creatorConfigValues;
- }
-
-}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MilkingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MilkingTaskType.java
index 6d81ba4c..e1edbaa3 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MilkingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MilkingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -18,6 +19,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class MilkingTaskType extends TaskType {
@@ -31,6 +33,14 @@ public final class MilkingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningCertainTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningCertainTaskType.java
index 9e28035b..3772b401 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningCertainTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningCertainTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -10,7 +11,6 @@ import com.leonardobishop.quests.quests.Task;
import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
import com.leonardobishop.quests.quests.tasktypes.TaskType;
import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
-import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
@@ -19,6 +19,7 @@ import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class MiningCertainTaskType extends TaskType {
@@ -28,8 +29,8 @@ public final class MiningCertainTaskType extends TaskType {
public MiningCertainTaskType() {
super("blockbreakcertain", "LMBishop", "Break a set amount of a specific block.");
this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of blocks to be broken."));
- this.creatorConfigValues.add(new ConfigValue("block", false, "Name or ID of block.")); // Can use name:datacode
- this.creatorConfigValues.add(new ConfigValue("blocks", false, "List of blocks (alias for block for config readability)."));
+ this.creatorConfigValues.add(new ConfigValue("block", true, "Name or ID of block.", "block")); // Can use name:datacode
+ this.creatorConfigValues.add(new ConfigValue("blocks", true, "List of blocks (alias for block for config readability).", "block"));
this.creatorConfigValues.add(new ConfigValue("data", false, "Data code for block.")); // only used if no datacode provided in block or blocks
this.creatorConfigValues.add(new ConfigValue("reverse-if-placed", false, "Will reverse progression if block of same type is placed."));
this.creatorConfigValues.add(new ConfigValue("use-similar-blocks", false, "(Deprecated) If true, this will ignore orientation of doors, logs etc."));
@@ -37,6 +38,43 @@ public final class MiningCertainTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ if (config.get("block") == null && config.get("blocks") == null) {
+ TaskUtils.configValidateExists(root + ".block", config.get("block"), problems, "block", super.getType());
+ } else {
+ Object configBlock;
+ String source;
+ if (config.containsKey("block")) {
+ source = "block";
+ } else {
+ source = "blocks";
+ }
+ configBlock = config.get(source);
+ List<String> checkBlocks = new ArrayList<>();
+ if (configBlock instanceof List) {
+ checkBlocks.addAll((List) configBlock);
+ } else {
+ checkBlocks.add(String.valueOf(configBlock));
+ }
+
+ for (String materialName : checkBlocks) {
+ String[] split = materialName.split(":");
+ if (Material.getMaterial(String.valueOf(split[0])) == null) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ QuestsConfigLoader.ConfigProblemDescriptions.UNKNOWN_MATERIAL.getDescription(materialName), root + "." + source));
+ }
+ }
+ }
+ TaskUtils.configValidateBoolean(root + ".reverse-if-broken", config.get("reverse-if-broken"), problems, true,"reverse-if-broken");
+ TaskUtils.configValidateBoolean(root + ".use-similar-blocks", config.get("use-similar-blocks"), problems, true,"use-similar-blocks");
+ TaskUtils.configValidateInt(root + ".data", config.get("data"), problems, true,true, "data");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
@@ -125,8 +163,9 @@ public final class MiningCertainTaskType extends TaskType {
short blockData = block.getData();
- if (blockType.equals(material)) {
- return configData == null || ((int) blockData) == comparableData;
+ if (blockType == material) {
+ if (((split.length == 1 && configData == null) || ((int) blockData) == comparableData))
+ return true;
}
}
return false;
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningTaskType.java
index 60712235..462fcdf9 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MiningTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -15,6 +16,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class MiningTaskType extends TaskType {
@@ -31,6 +33,14 @@ public final class MiningTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingCertainTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingCertainTaskType.java
index 61a0a557..b703f216 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingCertainTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingCertainTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -19,6 +20,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDeathEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class MobkillingCertainTaskType extends TaskType {
@@ -33,6 +35,23 @@ public final class MobkillingCertainTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".mob", config.get("mob"), problems, "mob", super.getType())) {
+ try {
+ EntityType.valueOf(String.valueOf(config.get("mob")));
+ } catch (IllegalArgumentException ex) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ QuestsConfigLoader.ConfigProblemDescriptions.UNKNOWN_ENTITY_TYPE.getDescription(String.valueOf(config.get("mob"))), root + ".mob"));
+ }
+ }
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
@@ -79,7 +98,7 @@ public final class MobkillingCertainTaskType extends TaskType {
if (configName != null) {
configName = ChatColor.translateAlternateColorCodes('&', configName);
if (mob.getCustomName() == null || !mob.getCustomName().equals(configName)) {
- return;
+ continue;
}
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingTaskType.java
index 6bcd835e..918306b3 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MobkillingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -19,6 +20,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDeathEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class MobkillingTaskType extends TaskType {
@@ -32,6 +34,15 @@ public final class MobkillingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ TaskUtils.configValidateBoolean(root + ".hostile", config.get("hostile"), problems, true, "hostile");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaceholderAPIEvaluateTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaceholderAPIEvaluateTaskType.java
deleted file mode 100644
index 7e4af335..00000000
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaceholderAPIEvaluateTaskType.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.leonardobishop.quests.quests.tasktypes.types;
-
-import com.leonardobishop.quests.Quests;
-import com.leonardobishop.quests.api.QuestsAPI;
-import com.leonardobishop.quests.player.QPlayer;
-import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
-import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
-import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
-import com.leonardobishop.quests.quests.Quest;
-import com.leonardobishop.quests.quests.Task;
-import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
-import com.leonardobishop.quests.quests.tasktypes.TaskType;
-import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
-import me.clip.placeholderapi.PlaceholderAPI;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-import org.bukkit.scheduler.BukkitRunnable;
-import org.bukkit.scheduler.BukkitTask;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public final class PlaceholderAPIEvaluateTaskType extends TaskType {
-
- private BukkitTask poll;
- private List<ConfigValue> creatorConfigValues = new ArrayList<>();
-
- public PlaceholderAPIEvaluateTaskType() {
- super("placeholderapi_evaluate", "LMBishop", "Evaluate the result of a placeholder");
- this.creatorConfigValues.add(new ConfigValue("placeholder", true, "The placeholder string (including %%)."));
- this.creatorConfigValues.add(new ConfigValue("evaluates", true, "What it should evaluate to be marked as complete."));
- }
-
- @Override
- public void onReady() {
- this.poll = new BukkitRunnable() {
- @Override
- public void run() {
- for (Player player : Bukkit.getOnlinePlayers()) {
- QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(player.getUniqueId(), true);
- QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
- for (Quest quest : PlaceholderAPIEvaluateTaskType.super.getRegisteredQuests()) {
- if (questProgressFile.hasStartedQuest(quest)) {
- QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
- for (Task task : quest.getTasksOfType(PlaceholderAPIEvaluateTaskType.super.getType())) {
- if (!TaskUtils.validateWorld(player, task)) continue;
- TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
- if (taskProgress.isCompleted()) {
- continue;
- }
- String placeholder = (String) task.getConfigValue("placeholder");
- String evaluates = (String) task.getConfigValue("evaluates");
- if (placeholder != null) {
- if (PlaceholderAPI.setPlaceholders(player, placeholder).equals(evaluates)) {
- taskProgress.setCompleted(true);
- }
- }
- }
- }
- }
- }
- }
- }.runTaskTimer(Quests.get(), 30L, 30L);
- }
-
- @Override
- public void onDisable() {
- if (this.poll != null) {
- this.poll.cancel();
- }
- }
-
- @Override
- public List<ConfigValue> getCreatorConfigValues() {
- return creatorConfigValues;
- }
-}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlayerkillingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlayerkillingTaskType.java
index f2ef4981..1b7d8bd2 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlayerkillingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlayerkillingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -17,6 +18,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDeathEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class PlayerkillingTaskType extends TaskType {
@@ -25,8 +27,15 @@ public final class PlayerkillingTaskType extends TaskType {
public PlayerkillingTaskType() {
super("playerkilling", "LMBishop", "Kill a set amount of players.");
- this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of mobs to be killed."));
- this.creatorConfigValues.add(new ConfigValue("hostile", false, "Only allow hostile or non-hostile mobs (unspecified = any type allowed)."));
+ this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of players to be killed."));
+ }
+
+ @Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
}
@Override
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaytimeTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaytimeTaskType.java
index f3940d07..159c1010 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaytimeTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PlaytimeTaskType.java
@@ -1,6 +1,7 @@
package com.leonardobishop.quests.quests.tasktypes.types;
import com.leonardobishop.quests.Quests;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -17,6 +18,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class PlaytimeTaskType extends TaskType {
@@ -30,45 +32,56 @@ public final class PlaytimeTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".minutes", config.get("minutes"), problems, "minutes", super.getType()))
+ TaskUtils.configValidateInt(root + ".minutes", config.get("minutes"), problems, false, true, "minutes");
+ return problems;
+ }
+
+
+ @Override
public void onReady() {
- this.poll = new BukkitRunnable() {
- @Override
- public void run() {
- for (Player player : Bukkit.getOnlinePlayers()) {
- QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(player.getUniqueId(), true);
- QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
- for (Quest quest : PlaytimeTaskType.super.getRegisteredQuests()) {
- if (questProgressFile.hasStartedQuest(quest)) {
- QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
- for (Task task : quest.getTasksOfType(PlaytimeTaskType.super.getType())) {
- if (!TaskUtils.validateWorld(player, task)) continue;
+ if (this.poll == null) {
+ this.poll = new BukkitRunnable() {
+ @Override
+ public void run() {
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(player.getUniqueId(), true);
+ QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
+ for (Quest quest : PlaytimeTaskType.super.getRegisteredQuests()) {
+ if (questProgressFile.hasStartedQuest(quest)) {
+ QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
+ for (Task task : quest.getTasksOfType(PlaytimeTaskType.super.getType())) {
+ if (!TaskUtils.validateWorld(player, task)) continue;
- TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
- if (taskProgress.isCompleted()) {
- continue;
- }
- int minutes = (int) task.getConfigValue("minutes");
- if (taskProgress.getProgress() == null) {
- taskProgress.setProgress(1);
- } else {
- taskProgress.setProgress((int) taskProgress.getProgress() + 1);
- }
- if (((int) taskProgress.getProgress()) >= minutes) {
- taskProgress.setCompleted(true);
+ TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
+ if (taskProgress.isCompleted()) {
+ continue;
+ }
+ int minutes = (int) task.getConfigValue("minutes");
+ if (taskProgress.getProgress() == null) {
+ taskProgress.setProgress(1);
+ } else {
+ taskProgress.setProgress((int) taskProgress.getProgress() + 1);
+ }
+ if (((int) taskProgress.getProgress()) >= minutes) {
+ taskProgress.setCompleted(true);
+ }
}
}
}
}
}
- }
- }.runTaskTimer(Quests.get(), 1200L, 1200L);
+ }.runTaskTimer(Quests.get(), 1200L, 1200L);
+ }
}
@Override
public void onDisable() {
- if (this.poll != null) {
- this.poll.cancel();
- }
+// if (this.poll != null) {
+// this.poll.cancel();
+// }
}
@Override
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PositionTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PositionTaskType.java
index 2f5d7336..03af06ff 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PositionTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PositionTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -19,6 +20,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class PositionTaskType extends TaskType {
@@ -35,6 +37,20 @@ public final class PositionTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ TaskUtils.configValidateExists(root + ".world", config.get("world"), problems, "world", super.getType());
+ if (TaskUtils.configValidateExists(root + ".x", config.get("x"), problems, "x", super.getType()))
+ TaskUtils.configValidateInt(root + ".x", config.get("x"), problems, false, false, "x");
+ if (TaskUtils.configValidateExists(root + ".y", config.get("y"), problems, "y", super.getType()))
+ TaskUtils.configValidateInt(root + ".y", config.get("y"), problems, false, false, "y");
+ if (TaskUtils.configValidateExists(root + ".z", config.get("z"), problems, "z", super.getType()))
+ TaskUtils.configValidateInt(root + ".z", config.get("z"), problems, false, false, "z");
+ TaskUtils.configValidateInt(root + ".distance-padding", config.get("distance-padding"), problems, true, true, "distance-padding");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
@@ -69,15 +85,16 @@ public final class PositionTaskType extends TaskType {
if (task.getConfigValue("distance-padding") != null) {
padding = (int) task.getConfigValue("distance-padding");
}
+ int paddingSquared = padding * padding;
World world = Bukkit.getWorld(worldString);
if (world == null) {
- return;
+ continue;
}
Location location = new Location(world, x, y, z);
if (player.getWorld().equals(world) && player.getLocation().getBlockX() == location.getBlockX() && player.getLocation().getBlockY() == location.getBlockY() && player.getLocation().getBlockZ() == location.getBlockZ()) {
taskProgress.setCompleted(true);
- } else if (player.getWorld().equals(world) && player.getLocation().distance(location) < padding) {
+ } else if (padding != 0 && player.getWorld().equals(world) && player.getLocation().distanceSquared(location) < paddingSquared) {
taskProgress.setCompleted(true);
}
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ShearingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ShearingTaskType.java
index 9c78bb2a..2d739214 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ShearingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ShearingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -17,6 +18,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerShearEntityEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class ShearingTaskType extends TaskType {
@@ -29,6 +31,15 @@ public final class ShearingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/TamingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/TamingTaskType.java
index 53428c8f..e5888a49 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/TamingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/TamingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -16,6 +17,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityTameEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class TamingTaskType extends TaskType {
@@ -28,6 +30,15 @@ public final class TamingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/WalkingTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/WalkingTaskType.java
index 62ced7d9..5eb37a6c 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/WalkingTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/WalkingTaskType.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests.quests.tasktypes.types;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -16,6 +17,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class WalkingTaskType extends TaskType {
@@ -28,6 +30,15 @@ public final class WalkingTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".distance", config.get("distance"), problems, "distance", super.getType()))
+ TaskUtils.configValidateInt(root + ".distance", config.get("distance"), problems, false, true, "distance");
+ return problems;
+ }
+
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ASkyBlockLevelType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/ASkyBlockLevelType.java
index 0e4f3229..cc2089a0 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/ASkyBlockLevelType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/ASkyBlockLevelType.java
@@ -1,5 +1,6 @@
-package com.leonardobishop.quests.quests.tasktypes.types;
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -9,11 +10,13 @@ import com.leonardobishop.quests.quests.Quest;
import com.leonardobishop.quests.quests.Task;
import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
import com.leonardobishop.quests.quests.tasktypes.TaskType;
+import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
import com.wasteofplastic.askyblock.events.IslandPostLevelEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class ASkyBlockLevelType extends TaskType {
@@ -26,6 +29,14 @@ public final class ASkyBlockLevelType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".level", config.get("level"), problems, "level", super.getType()))
+ TaskUtils.configValidateInt(root + ".level", config.get("level"), problems, false, false, "level");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BentoBoxLevelTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/BentoBoxLevelTaskType.java
index 289b2655..2281aecb 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/BentoBoxLevelTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/BentoBoxLevelTaskType.java
@@ -1,5 +1,6 @@
-package com.leonardobishop.quests.quests.tasktypes.types;
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -10,16 +11,14 @@ import com.leonardobishop.quests.quests.Task;
import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
import com.leonardobishop.quests.quests.tasktypes.TaskType;
import com.leonardobishop.quests.quests.tasktypes.TaskTypeManager;
+import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
import org.bukkit.event.EventHandler;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.BentoBoxEvent;
import world.bentobox.bentobox.database.objects.Island;
import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
public final class BentoBoxLevelTaskType extends TaskType {
@@ -33,6 +32,14 @@ public final class BentoBoxLevelTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".level", config.get("level"), problems, "level", super.getType()))
+ TaskUtils.configValidateInt(root + ".level", config.get("level"), problems, false, false, "level");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensDeliverTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/CitizensDeliverTaskType.java
index 8a64d0ac..2d70a8cd 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensDeliverTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/CitizensDeliverTaskType.java
@@ -1,6 +1,7 @@
-package com.leonardobishop.quests.quests.tasktypes.types;
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
import com.leonardobishop.quests.Quests;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
@@ -21,6 +22,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class CitizensDeliverTaskType extends TaskType {
@@ -38,6 +40,41 @@ public final class CitizensDeliverTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".item", config.get("item"), problems, "item", super.getType())) {
+ Object configBlock = config.get("item");
+ if (configBlock instanceof ConfigurationSection) {
+ ConfigurationSection section = (ConfigurationSection) configBlock;
+ String itemloc = "item";
+ if (!section.contains("item")) {
+ itemloc = "type";
+ }
+ if (!section.contains(itemloc)) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ QuestsConfigLoader.ConfigProblemDescriptions.UNKNOWN_MATERIAL.getDescription(""), root + ".item.type"));
+ } else {
+ String type = String.valueOf(section.get(itemloc));
+ if (!Quests.get().getItemGetter().isValidMaterial(type)) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ QuestsConfigLoader.ConfigProblemDescriptions.UNKNOWN_MATERIAL.getDescription(type), root + ".item." + itemloc));
+ }
+ }
+ } else {
+ if (Material.getMaterial(String.valueOf(configBlock)) == null) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ QuestsConfigLoader.ConfigProblemDescriptions.UNKNOWN_MATERIAL.getDescription(String.valueOf(configBlock)), root + ".item.item"));
+ }
+ }
+ }
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ TaskUtils.configValidateExists(root + ".npc-name", config.get("npc-name"), problems, "npc-name", super.getType());
+ TaskUtils.configValidateBoolean(root + ".remove-items-when-complete", config.get("remove-items-when-complete"), problems, true, "remove-items-when-complete", super.getType());
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
@@ -49,6 +86,9 @@ public final class CitizensDeliverTaskType extends TaskType {
@SuppressWarnings("deprecation")
private void checkInventory(Player player, String citizenName) {
+ if (player == null || !player.isOnline()) {
+ return;
+ }
QPlayer qPlayer = Quests.get().getPlayerManager().getPlayer(player.getUniqueId(), true);
if (qPlayer == null) {
return;
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensInteractTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/CitizensInteractTaskType.java
index ed277996..a5e53ea0 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensInteractTaskType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/CitizensInteractTaskType.java
@@ -1,5 +1,6 @@
-package com.leonardobishop.quests.quests.tasktypes.types;
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -16,6 +17,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class CitizensInteractTaskType extends TaskType {
@@ -29,6 +31,15 @@ public final class CitizensInteractTaskType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ TaskUtils.configValidateExists(root + ".npc-name", config.get("npc-name"), problems, "npc-name", super.getType());
+ TaskUtils.configValidateBoolean(root + ".remove-items-when-complete", config.get("remove-items-when-complete"), problems, true, "remove-items-when-complete", super.getType());
+ return problems;
+ }
+
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/EssentialsBalanceTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/EssentialsBalanceTaskType.java
new file mode 100644
index 00000000..54f972ad
--- /dev/null
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/EssentialsBalanceTaskType.java
@@ -0,0 +1,100 @@
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
+
+import com.earth2me.essentials.Essentials;
+import com.leonardobishop.quests.QuestsConfigLoader;
+import com.leonardobishop.quests.api.QuestsAPI;
+import com.leonardobishop.quests.player.QPlayer;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
+import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
+import com.leonardobishop.quests.quests.Quest;
+import com.leonardobishop.quests.quests.Task;
+import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
+import com.leonardobishop.quests.quests.tasktypes.TaskType;
+import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
+import net.ess3.api.events.UserBalanceUpdateEvent;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+
+public class EssentialsBalanceTaskType extends TaskType {
+
+ private List<ConfigValue> creatorConfigValues = new ArrayList<>();
+
+ public EssentialsBalanceTaskType() {
+ super("essentials_balance", "LMBishop", "Reach a set amount of money.");
+ this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of money to reach."));
+ }
+
+ @Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, false, "amount");
+ return problems;
+ }
+
+ @Override
+ public void onStart(Quest quest, Task task, UUID playerUUID) {
+ Player player = Bukkit.getPlayer(playerUUID);
+ Essentials ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials");
+ if (player != null && player.isOnline() && ess != null) {
+ QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(playerUUID);
+ QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
+ QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
+ TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
+
+ int earningsNeeded = (int) task.getConfigValue("amount");
+ BigDecimal money = ess.getUser(player).getMoney();
+ taskProgress.setProgress(money);
+ if (money.compareTo(BigDecimal.valueOf(earningsNeeded)) > 0) {
+ taskProgress.setCompleted(true);
+ }
+ }
+ }
+
+ @Override
+ public List<ConfigValue> getCreatorConfigValues() {
+ return creatorConfigValues;
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void onMoneyEarn(UserBalanceUpdateEvent event) {
+ QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(event.getPlayer().getUniqueId(), true);
+ if (qPlayer == null) {
+ return;
+ }
+
+ QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
+
+ for (Quest quest : super.getRegisteredQuests()) {
+ if (questProgressFile.hasStartedQuest(quest)) {
+ QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
+
+ for (Task task : quest.getTasksOfType(super.getType())) {
+ TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
+
+ if (taskProgress.isCompleted()) {
+ continue;
+ }
+
+ int earningsNeeded = (int) task.getConfigValue("amount");
+
+ taskProgress.setProgress(event.getNewBalance());
+
+ if (event.getNewBalance().compareTo(BigDecimal.valueOf(earningsNeeded)) > 0) {
+ taskProgress.setCompleted(true);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/EssentialsMoneyEarnTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/EssentialsMoneyEarnTaskType.java
new file mode 100644
index 00000000..3d054a86
--- /dev/null
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/EssentialsMoneyEarnTaskType.java
@@ -0,0 +1,83 @@
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
+
+import com.leonardobishop.quests.QuestsConfigLoader;
+import com.leonardobishop.quests.api.QuestsAPI;
+import com.leonardobishop.quests.player.QPlayer;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
+import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
+import com.leonardobishop.quests.quests.Quest;
+import com.leonardobishop.quests.quests.Task;
+import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
+import com.leonardobishop.quests.quests.tasktypes.TaskType;
+import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
+import net.ess3.api.events.UserBalanceUpdateEvent;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class EssentialsMoneyEarnTaskType extends TaskType {
+
+ private List<ConfigValue> creatorConfigValues = new ArrayList<>();
+
+ public EssentialsMoneyEarnTaskType() {
+ super("essentials_moneyearn", "LMBishop", "Earn a set amount of money.");
+ this.creatorConfigValues.add(new ConfigValue("amount", true, "Amount of money to earn."));
+ }
+
+ @Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, false, "amount");
+ return problems;
+ }
+
+
+ @Override
+ public List<ConfigValue> getCreatorConfigValues() {
+ return creatorConfigValues;
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void onMoneyEarn(UserBalanceUpdateEvent event) {
+ QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(event.getPlayer().getUniqueId(), true);
+ if (qPlayer == null) {
+ return;
+ }
+
+ QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
+
+ for (Quest quest : super.getRegisteredQuests()) {
+ if (questProgressFile.hasStartedQuest(quest)) {
+ QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
+
+ for (Task task : quest.getTasksOfType(super.getType())) {
+ TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
+
+ if (taskProgress.isCompleted()) {
+ continue;
+ }
+
+ int earningsNeeded = (int) task.getConfigValue("amount");
+
+ BigDecimal current = (BigDecimal) taskProgress.getProgress();
+ if (current == null) {
+ current = new BigDecimal(0);
+ }
+ BigDecimal newProgress = current.add(event.getNewBalance().subtract(event.getOldBalance()));
+ taskProgress.setProgress(newProgress);
+
+ if (newProgress.compareTo(BigDecimal.valueOf(earningsNeeded)) > 0) {
+ taskProgress.setCompleted(true);
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/IridiumSkyblockValueType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/IridiumSkyblockValueType.java
new file mode 100644
index 00000000..79bb9492
--- /dev/null
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/IridiumSkyblockValueType.java
@@ -0,0 +1,91 @@
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
+
+import com.iridium.iridiumskyblock.Island;
+import com.iridium.iridiumskyblock.api.IslandWorthCalculatedEvent;
+import com.leonardobishop.quests.Quests;
+import com.leonardobishop.quests.QuestsConfigLoader;
+import com.leonardobishop.quests.api.QuestsAPI;
+import com.leonardobishop.quests.player.QPlayer;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
+import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
+import com.leonardobishop.quests.quests.Quest;
+import com.leonardobishop.quests.quests.Task;
+import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
+import com.leonardobishop.quests.quests.tasktypes.TaskType;
+import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+
+public final class IridiumSkyblockValueType extends TaskType {
+
+ private List<ConfigValue> creatorConfigValues = new ArrayList<>();
+
+ public IridiumSkyblockValueType() {
+ super("iridiumskyblock_value", "LMBishop", "Reach a certain island value for Iridium Skyblock.");
+ this.creatorConfigValues.add(new ConfigValue("value", true, "Minimum island value needed."));
+ }
+
+ @Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".value", config.get("value"), problems, "value", super.getType()))
+ TaskUtils.configValidateInt(root + ".value", config.get("value"), problems, false, false, "value");
+ return problems;
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void onIslandLevel(IslandWorthCalculatedEvent event) {
+ Island island = event.getIsland();
+ for (String player : island.members) {
+ UUID uuid;
+ try {
+ uuid = UUID.fromString(player);
+ } catch (Exception e) {
+ Quests.get().getQuestsLogger().debug("Cannot convert from String to UUID for IridiumSkyblock");
+ continue;
+ }
+ QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(uuid, true);
+ if (qPlayer == null) {
+ continue;
+ }
+
+ QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
+
+ for (Quest quest : IridiumSkyblockValueType.super.getRegisteredQuests()) {
+ if (questProgressFile.hasStartedQuest(quest)) {
+ QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
+
+ for (Task task : quest.getTasksOfType(IridiumSkyblockValueType.super.getType())) {
+ TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
+
+ if (taskProgress.isCompleted()) {
+ continue;
+ }
+
+ int islandValueNeeded = (int) task.getConfigValue("value");
+
+ taskProgress.setProgress(event.getIslandWorth());
+
+ if (((double) taskProgress.getProgress()) >= islandValueNeeded) {
+ taskProgress.setCompleted(true);
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public List<ConfigValue> getCreatorConfigValues() {
+ return creatorConfigValues;
+ }
+
+}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MythicMobsKillingType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/MythicMobsKillingType.java
index 75570108..b86fe62d 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/MythicMobsKillingType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/MythicMobsKillingType.java
@@ -1,5 +1,6 @@
-package com.leonardobishop.quests.quests.tasktypes.types;
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -17,6 +18,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class MythicMobsKillingType extends TaskType {
@@ -30,6 +32,15 @@ public final class MythicMobsKillingType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ TaskUtils.configValidateExists(root + ".name", config.get("name"), problems, "name", super.getType());
+ if (TaskUtils.configValidateExists(root + ".amount", config.get("amount"), problems, "amount", super.getType()))
+ TaskUtils.configValidateInt(root + ".amount", config.get("amount"), problems, false, true, "amount");
+ return problems;
+ }
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/PlaceholderAPIEvaluateTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/PlaceholderAPIEvaluateTaskType.java
new file mode 100644
index 00000000..639acbd5
--- /dev/null
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/PlaceholderAPIEvaluateTaskType.java
@@ -0,0 +1,159 @@
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
+
+import com.leonardobishop.quests.Quests;
+import com.leonardobishop.quests.QuestsConfigLoader;
+import com.leonardobishop.quests.api.QuestsAPI;
+import com.leonardobishop.quests.player.QPlayer;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
+import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
+import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
+import com.leonardobishop.quests.quests.Quest;
+import com.leonardobishop.quests.quests.Task;
+import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
+import com.leonardobishop.quests.quests.tasktypes.TaskType;
+import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
+import me.clip.placeholderapi.PlaceholderAPI;
+import net.objecthunter.exp4j.operator.Operator;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public final class PlaceholderAPIEvaluateTaskType extends TaskType {
+
+ private BukkitTask poll;
+ private List<ConfigValue> creatorConfigValues = new ArrayList<>();
+
+ public PlaceholderAPIEvaluateTaskType() {
+ super("placeholderapi_evaluate", "LMBishop", "Evaluate the result of a placeholder");
+ this.creatorConfigValues.add(new ConfigValue("placeholder", true, "The placeholder string (including %%)."));
+ this.creatorConfigValues.add(new ConfigValue("evaluates", true, "What it should evaluate to be marked as complete."));
+ this.creatorConfigValues.add(new ConfigValue("operator", false, "Comparison method."));
+ }
+
+ @Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ TaskUtils.configValidateExists(root + ".placeholder", config.get("placeholder"), problems, "placeholder", super.getType());
+ boolean evalExists = TaskUtils.configValidateExists(root + ".evaluates", config.get("evaluates"), problems, "evaluates", super.getType());
+
+ if (config.containsKey("operator")) {
+ String operatorStr = (String) config.get("operator");
+ Operator operator = null;
+ try {
+ operator = Operator.valueOf(operatorStr);
+ } catch (IllegalArgumentException ex) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ "Operator '" + operatorStr + "' does not exist.", root + ".operator"));
+ }
+ if (operator != null && evalExists) {
+ String evalStr = String.valueOf(config.get("evaluates"));
+ try {
+ Double.parseDouble(evalStr);
+ } catch (IllegalArgumentException ex) {
+ problems.add(new QuestsConfigLoader.ConfigProblem(QuestsConfigLoader.ConfigProblemType.WARNING,
+ "Numeric operator specified, but placeholder evaluation '" + evalStr + "' is not numeric.", root + ".evaluates"));
+ }
+ }
+ }
+ return problems;
+ }
+
+ @Override
+ public void onReady() {
+ this.poll = new BukkitRunnable() {
+ @Override
+ public void run() {
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ QPlayer qPlayer = QuestsAPI.getPlayerManager().getPlayer(player.getUniqueId(), true);
+ QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile();
+ for (Quest quest : PlaceholderAPIEvaluateTaskType.super.getRegisteredQuests()) {
+ if (questProgressFile.hasStartedQuest(quest)) {
+ QuestProgress questProgress = questProgressFile.getQuestProgress(quest);
+ for (Task task : quest.getTasksOfType(PlaceholderAPIEvaluateTaskType.super.getType())) {
+ if (!TaskUtils.validateWorld(player, task)) continue;
+ TaskProgress taskProgress = questProgress.getTaskProgress(task.getId());
+ if (taskProgress.isCompleted()) {
+ 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) {
+ continue;
+ }
+ }
+
+ String evaluated = PlaceholderAPI.setPlaceholders(player, placeholder);
+ if (operator == null && evaluated.equals(evaluates)) {
+ taskProgress.setCompleted(true);
+ } else if (operator != null) {
+ double numericEvaluated;
+ try {
+ numericEvaluated = Double.parseDouble(evaluated);
+ } catch (NumberFormatException ex) {
+ continue;
+ }
+ switch (operator) {
+ case GREATER_THAN:
+ if (numericEvaluated > numericEvaluates)
+ taskProgress.setCompleted(true);
+ continue;
+ case LESS_THAN:
+ if (numericEvaluated < numericEvaluates)
+ taskProgress.setCompleted(true);
+ continue;
+ case GREATER_THAN_OR_EQUAL_TO:
+ if (numericEvaluated >= numericEvaluates)
+ taskProgress.setCompleted(true);
+ continue;
+ case LESS_THAN_OR_EQUAL_TO:
+ if (numericEvaluated <= numericEvaluates)
+ taskProgress.setCompleted(true);
+ continue;
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ }.runTaskTimer(Quests.get(), 30L, 30L);
+ }
+
+ @Override
+ public void onDisable() {
+ if (this.poll != null) {
+ this.poll.cancel();
+ }
+ }
+
+ @Override
+ public List<ConfigValue> getCreatorConfigValues() {
+ return creatorConfigValues;
+ }
+
+ enum Operator {
+ GREATER_THAN,
+ LESS_THAN,
+ GREATER_THAN_OR_EQUAL_TO,
+ LESS_THAN_OR_EQUAL_TO;
+ }
+}
diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/uSkyBlockLevelType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/uSkyBlockLevelType.java
index 2956bf32..81f9138a 100644
--- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/uSkyBlockLevelType.java
+++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/dependent/uSkyBlockLevelType.java
@@ -1,5 +1,6 @@
-package com.leonardobishop.quests.quests.tasktypes.types;
+package com.leonardobishop.quests.quests.tasktypes.types.dependent;
+import com.leonardobishop.quests.QuestsConfigLoader;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.player.QPlayer;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
@@ -9,11 +10,13 @@ import com.leonardobishop.quests.quests.Quest;
import com.leonardobishop.quests.quests.Task;
import com.leonardobishop.quests.quests.tasktypes.ConfigValue;
import com.leonardobishop.quests.quests.tasktypes.TaskType;
+import com.leonardobishop.quests.quests.tasktypes.TaskUtils;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import us.talabrek.ultimateskyblock.api.event.uSkyBlockScoreChangedEvent;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public final class uSkyBlockLevelType extends TaskType {
@@ -26,6 +29,15 @@ public final class uSkyBlockLevelType extends TaskType {
}
@Override
+ public List<QuestsConfigLoader.ConfigProblem> detectProblemsInConfig(String root, HashMap<String, Object> config) {
+ ArrayList<QuestsConfigLoader.ConfigProblem> problems = new ArrayList<>();
+ if (TaskUtils.configValidateExists(root + ".level", config.get("level"), problems, "level", super.getType()))
+ TaskUtils.configValidateInt(root + ".level", config.get("level"), problems, false, false, "level");
+ return problems;
+ }
+
+
+ @Override
public List<ConfigValue> getCreatorConfigValues() {
return creatorConfigValues;
}
diff --git a/src/main/java/com/leonardobishop/quests/updater/Updater.java b/src/main/java/com/leonardobishop/quests/updater/Updater.java
index f0705d1e..6c197b88 100644
--- a/src/main/java/com/leonardobishop/quests/updater/Updater.java
+++ b/src/main/java/com/leonardobishop/quests/updater/Updater.java
@@ -14,10 +14,12 @@ import java.util.concurrent.TimeUnit;
public class Updater {
private static final int PROJECT_ID = 23696;
- private String installedVersion;
+
+ private final String installedVersion;
+ private final Quests plugin;
+
private String returnedVersion;
private URL api;
- private Quests plugin;
private boolean updateReady;
private long lastCheck;