From 5c2460c93cc2746816893607c966eba2b5284d05 Mon Sep 17 00:00:00 2001 From: LMBishop <13875753+LMBishop@users.noreply.github.com> Date: Wed, 3 Feb 2021 16:08:21 +0000 Subject: Add CommandTaskType & DistancefromTaskType + internal changes - removed confusing "onlyDataLoaded" and fixed reset command --- .../com/leonardobishop/quests/QuestCompleter.java | 3 - .../java/com/leonardobishop/quests/Quests.java | 18 ++-- .../leonardobishop/quests/QuestsConfigLoader.java | 2 +- .../com/leonardobishop/quests/QuestsLogger.java | 38 +++++---- .../quests/commands/CommandQuests.java | 6 +- .../com/leonardobishop/quests/player/QPlayer.java | 28 +------ .../quests/player/QPlayerManager.java | 24 ++++-- .../questprogressfile/QuestProgressFile.java | 1 + .../com/leonardobishop/quests/quests/Task.java | 4 + .../tasktypes/types/CitizensDeliverTaskType.java | 3 + .../quests/tasktypes/types/CommandTaskType.java | 97 ++++++++++++++++++++++ .../tasktypes/types/DistancefromTaskType.java | 18 +++- .../quests/tasktypes/types/PositionTaskType.java | 3 +- 13 files changed, 175 insertions(+), 70 deletions(-) create mode 100644 src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CommandTaskType.java (limited to 'src/main/java') diff --git a/src/main/java/com/leonardobishop/quests/QuestCompleter.java b/src/main/java/com/leonardobishop/quests/QuestCompleter.java index b783540c..2e3c4de7 100644 --- a/src/main/java/com/leonardobishop/quests/QuestCompleter.java +++ b/src/main/java/com/leonardobishop/quests/QuestCompleter.java @@ -21,9 +21,6 @@ public class QuestCompleter implements Runnable { 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; - } QuestProgressFile questProgressFile = qPlayer.getQuestProgressFile(); for (QuestProgress questProgress : questProgressFile.getAllQuestProgress()) { Quest quest = plugin.getQuestManager().getQuestById(questProgress.getQuestId()); diff --git a/src/main/java/com/leonardobishop/quests/Quests.java b/src/main/java/com/leonardobishop/quests/Quests.java index 8b201b77..ee22dcff 100644 --- a/src/main/java/com/leonardobishop/quests/Quests.java +++ b/src/main/java/com/leonardobishop/quests/Quests.java @@ -97,7 +97,7 @@ public class Quests extends JavaPlugin { @Override public void onEnable() { - questsLogger = new QuestsLogger(this, LoggingLevel.INFO); + questsLogger = new QuestsLogger(this, QuestsLogger.LoggingLevel.INFO); taskTypeManager = new TaskTypeManager(this); questManager = new QuestManager(this); @@ -145,6 +145,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")) { @@ -206,9 +208,6 @@ public class Quests extends JavaPlugin { } catch (Exception ignored) { } } for (QPlayer qPlayer : qPlayerManager.getQPlayers()) { - if (qPlayer.isOnlyDataLoaded()) { - continue; - } qPlayer.getQuestProgressFile().saveToDisk(true); } } @@ -229,20 +228,21 @@ public class Quests extends JavaPlugin { if (questAutosaveTask != null) { try { questAutosaveTask.cancel(); - } catch (Exception ignored) { } + } catch (Exception ex) { + questsLogger.debug("Cannot cancel quest autosave task"); + } } questAutosaveTask = Bukkit.getScheduler().runTaskTimer(this, () -> { for (QPlayer qPlayer : qPlayerManager.getQPlayers()) { - if (qPlayer.isOnlyDataLoaded()) { - continue; - } qPlayer.getQuestProgressFile().saveToDisk(false); } }, autocompleteInterval, autocompleteInterval); if (questCompleterTask != null) { try { questCompleterTask.cancel(); - } catch (Exception ignored) { } + } catch (Exception ignored) { + questsLogger.debug("Cannot cancel quest completer task"); + } } questCompleterTask = Bukkit.getScheduler().runTaskTimer(this, new QuestCompleter(this), 20, completerPollInterval); } diff --git a/src/main/java/com/leonardobishop/quests/QuestsConfigLoader.java b/src/main/java/com/leonardobishop/quests/QuestsConfigLoader.java index c5ef1115..b11544d1 100644 --- a/src/main/java/com/leonardobishop/quests/QuestsConfigLoader.java +++ b/src/main/java/com/leonardobishop/quests/QuestsConfigLoader.java @@ -57,7 +57,7 @@ public class QuestsConfigLoader { Category category = new Category(id, displayItem, permissionRequired); plugin.getQuestManager().registerCategory(category); } - plugin.getQuestsLogger().setServerLoggingLevel(LoggingLevel.fromNumber(plugin.getConfig().getInt("options.verbose-logging-level", 2))); + plugin.getQuestsLogger().setServerLoggingLevel(QuestsLogger.LoggingLevel.fromNumber(plugin.getConfig().getInt("options.verbose-logging-level", 2))); HashMap pathToQuest = new HashMap<>(); diff --git a/src/main/java/com/leonardobishop/quests/QuestsLogger.java b/src/main/java/com/leonardobishop/quests/QuestsLogger.java index 212592c2..3d8c6515 100644 --- a/src/main/java/com/leonardobishop/quests/QuestsLogger.java +++ b/src/main/java/com/leonardobishop/quests/QuestsLogger.java @@ -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/commands/CommandQuests.java b/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java index 4393d785..ef824dcc 100644 --- a/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java +++ b/src/main/java/com/leonardobishop/quests/commands/CommandQuests.java @@ -39,6 +39,10 @@ public class CommandQuests implements TabExecutor { @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")) && @@ -270,7 +274,7 @@ public class CommandQuests implements TabExecutor { } 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")) { diff --git a/src/main/java/com/leonardobishop/quests/player/QPlayer.java b/src/main/java/com/leonardobishop/quests/player/QPlayer.java index 0f4e0da5..0b12b91f 100644 --- a/src/main/java/com/leonardobishop/quests/player/QPlayer.java +++ b/src/main/java/com/leonardobishop/quests/player/QPlayer.java @@ -17,17 +17,11 @@ 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 +33,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; @@ -70,10 +60,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 +75,6 @@ public class QPlayer { } public void openQuests() { - if (onlyDataLoaded) { - return; - } - if (this.uuid == null) { return; } @@ -134,14 +116,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 d6bf631d..397f6fb6 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,23 @@ 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); - 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) { - this.getPlayer(uuid).getQuestProgressFile().saveToDisk(false); plugin.getQuestsLogger().debug("Unloading and saving player " + uuid + "."); + this.getPlayer(uuid).getQuestProgressFile().saveToDisk(false); qPlayers.remove(uuid); } @@ -72,7 +74,7 @@ public class QPlayerManager { public void loadPlayer(UUID uuid) { plugin.getQuestsLogger().debug("Loading player " + uuid + " from disk."); - if (getPlayer(uuid) == null) { + if (qPlayers.get(uuid) == null) { QuestProgressFile questProgressFile = new QuestProgressFile(uuid, plugin); try { @@ -90,7 +92,7 @@ public class QPlayerManager { QuestProgress questProgress = new QuestProgress(id, completed, completedBefore, completionDate, uuid, started, true); - if (data.isConfigurationSection("quest.progress." + id + ".task-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"); @@ -103,6 +105,8 @@ public class QPlayerManager { questProgressFile.addQuestProgress(questProgress); } } + } else { + plugin.getQuestsLogger().debug("Player " + uuid + " does not have a quest progress file."); } } } catch (Exception ex) { @@ -114,6 +118,8 @@ public class QPlayerManager { 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/QuestProgressFile.java b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java index 242c454b..7a7fde21 100644 --- a/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java +++ b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java @@ -447,6 +447,7 @@ public class QuestProgressFile { * 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 invalidQuests = new ArrayList<>(); for (String questId : this.questProgress.keySet()) { diff --git a/src/main/java/com/leonardobishop/quests/quests/Task.java b/src/main/java/com/leonardobishop/quests/quests/Task.java index eb9cd1b4..d986a9bc 100644 --- a/src/main/java/com/leonardobishop/quests/quests/Task.java +++ b/src/main/java/com/leonardobishop/quests/quests/Task.java @@ -27,6 +27,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 getConfigValues() { return configValues; } diff --git a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensDeliverTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensDeliverTaskType.java index 12077fca..33c59b0f 100644 --- a/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensDeliverTaskType.java +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CitizensDeliverTaskType.java @@ -85,6 +85,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/CommandTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CommandTaskType.java new file mode 100644 index 00000000..520b2103 --- /dev/null +++ b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/CommandTaskType.java @@ -0,0 +1,97 @@ +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.entity.EntityDamageByEntityEvent; +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 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 detectProblemsInConfig(String root, HashMap config) { + ArrayList 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 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 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/DistancefromTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/DistancefromTaskType.java index f4f46fd3..690d9650 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 @@ -55,6 +55,21 @@ public final class DistancefromTaskType extends TaskType { return creatorConfigValues; } +// private HashMap> distanceSquaredCache = new HashMap<>(); +// +// @Override +// public void onReady() { +// distanceSquaredCache.clear(); +// for (Quest quest : super.getRegisteredQuests()) { +// HashMap 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()) { @@ -82,6 +97,7 @@ 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) { @@ -89,7 +105,7 @@ public final class DistancefromTaskType extends TaskType { } 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/PositionTaskType.java b/src/main/java/com/leonardobishop/quests/quests/tasktypes/types/PositionTaskType.java index e585f77f..fba8a0c4 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 @@ -85,6 +85,7 @@ 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; @@ -93,7 +94,7 @@ public final class PositionTaskType extends TaskType { 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); } } -- cgit v1.2.3-70-g09d2