diff options
11 files changed, 285 insertions, 142 deletions
diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java index 22a5cc93..7ad36c08 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java @@ -165,6 +165,7 @@ import java.io.OutputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.function.BiFunction; @@ -340,7 +341,7 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { questsConfig.setItemGetter(itemGetter); // Finish module initialisation - this.taskTypeManager = new BukkitTaskTypeManager(this, questsConfig.getStringList("options.task-type-exclusions")); + this.taskTypeManager = new BukkitTaskTypeManager(this, new HashSet<>(questsConfig.getStringList("options.task-type-exclusions"))); this.qPlayerManager = new QPlayerManager(this, storageProvider, questController); this.menuController = new MenuController(this); this.questItemRegistry = new QuestItemRegistry(); diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminDebugQuestCommandHandler.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminDebugQuestCommandHandler.java index 0d64bcb1..df6ef7bf 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminDebugQuestCommandHandler.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminDebugQuestCommandHandler.java @@ -11,13 +11,14 @@ import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class AdminDebugQuestCommandHandler implements CommandHandler { private final BukkitQuestsPlugin plugin; - public AdminDebugQuestCommandHandler(BukkitQuestsPlugin plugin) { this.plugin = plugin; } @@ -69,10 +70,18 @@ public class AdminDebugQuestCommandHandler implements CommandHandler { ". This may generate a lot of spam."); sender.sendMessage(ChatColor.GRAY + "Use '/quests admin debug " + questId + "' to disable."); } else { - preferences.setDebug(questId, null); + preferences.unsetDebug(questId); sender.sendMessage(ChatColor.GREEN + "Debugging disabled for " + questName + "."); } + // Set it here to optimize debugging on high player count servers + final Set<QPlayer> debuggers = new HashSet<>(); + for (final QPlayer debugger : this.plugin.getPlayerManager().getQPlayers()) { + if (debugger.getPlayerPreferences().isDebug()) { + debuggers.add(debugger); + } + } + QPlayerPreferences.setDebuggers(debuggers); } else { sender.sendMessage(ChatColor.RED + "You must be a player to use this command."); } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/QuestsCommandSwitcher.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/QuestsCommandSwitcher.java index e756fb55..6195e42f 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/QuestsCommandSwitcher.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/QuestsCommandSwitcher.java @@ -39,7 +39,7 @@ public class QuestsCommandSwitcher extends CommandSwitcher implements TabExecuto @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (plugin.getTaskTypeManager().areRegistrationsAccepted()) { + if (plugin.getTaskTypeManager().areRegistrationsOpen()) { sender.sendMessage(ChatColor.RED + "Quests is not ready yet."); return true; } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java index 8f867673..f3b8eac4 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java @@ -43,8 +43,10 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -222,7 +224,7 @@ public class BukkitQuestsLoader implements QuestsLoader { configValues.put(key, config.get(taskRoot + "." + key)); } - List<ConfigProblem> taskProblems = new ArrayList<>(); + Set<ConfigProblem> taskProblems = new HashSet<>(); for (TaskType.ConfigValidator validator : t.getConfigValidators()) { validator.validateConfig(configValues, taskProblems); } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/BukkitTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/BukkitTaskType.java index 179b39ac..aa2d751e 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/BukkitTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/BukkitTaskType.java @@ -3,6 +3,7 @@ package com.leonardobishop.quests.bukkit.tasktype; import com.leonardobishop.quests.common.tasktype.TaskType; import org.bukkit.event.Listener; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.UUID; @@ -10,20 +11,15 @@ public abstract class BukkitTaskType extends TaskType implements Listener { protected BukkitTaskTypeManager taskTypeManager; - public BukkitTaskType(@NotNull String type, String author, String description, String... aliases) { + public BukkitTaskType(final @NotNull String type, final @Nullable String author, final @Nullable String description, final @NotNull String @NotNull ... aliases) { super(type, author, description, aliases); } - public BukkitTaskType(@NotNull String type, String author, String description) { - super(type, author, description); - } - - public BukkitTaskType(@NotNull String type) { + public BukkitTaskType(final @NotNull String type) { super(type); } - public final void debug(@NotNull String message, String questId, String taskId, @NotNull UUID player) { - taskTypeManager.sendDebug(message, super.getType(), questId, taskId, player); + public final void debug(final @NotNull String message, final @NotNull String questId, final @NotNull String taskId, final @NotNull UUID player) { + this.taskTypeManager.sendDebug(message, this.type, questId, taskId, player); } - } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/BukkitTaskTypeManager.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/BukkitTaskTypeManager.java index ec41039d..3b8eb7f8 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/BukkitTaskTypeManager.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/BukkitTaskTypeManager.java @@ -5,55 +5,89 @@ import com.leonardobishop.quests.common.player.QPlayer; import com.leonardobishop.quests.common.player.QPlayerPreferences; import com.leonardobishop.quests.common.tasktype.TaskType; import com.leonardobishop.quests.common.tasktype.TaskTypeManager; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import java.util.List; +import java.util.Set; import java.util.UUID; -public class BukkitTaskTypeManager extends TaskTypeManager { +/** + * The Bukkit task type manager stores all registered Bukkit-specific task types and registers individual quests to each task type. + * This manager ensures that task types specific to Bukkit are registered and handled correctly. + */ +public final class BukkitTaskTypeManager extends TaskTypeManager { private final BukkitQuestsPlugin plugin; - public BukkitTaskTypeManager(BukkitQuestsPlugin plugin) { + /** + * Constructs a new BukkitTaskTypeManager. + * + * @param plugin the Bukkit plugin instance + */ + public BukkitTaskTypeManager(final @NotNull BukkitQuestsPlugin plugin) { this.plugin = plugin; } - public BukkitTaskTypeManager(BukkitQuestsPlugin plugin, List<String> exclusions) { + /** + * Constructs a new BukkitTaskTypeManager with exclusions. + * + * @param plugin the Bukkit plugin instance + * @param exclusions the set of task type exclusions + */ + public BukkitTaskTypeManager(final @NotNull BukkitQuestsPlugin plugin, final @NotNull Set<String> exclusions) { super(exclusions); this.plugin = plugin; } + /** + * Registers a Bukkit-specific task type with the task type manager. + * + * @param taskType the task type to register + * @return true if the task type was successfully registered, false otherwise + * @throws RuntimeException if the task type is not an instance of {@link BukkitTaskType} + */ @Override - public boolean registerTaskType(@NotNull TaskType taskType) { - if (!(taskType instanceof BukkitTaskType bukkitTaskType)) throw new RuntimeException("BukkitTaskTypeManager implementation can only accept instances of BukkitTaskType!"); + public boolean registerTaskType(final @NotNull TaskType taskType) { + if (!(taskType instanceof final BukkitTaskType bukkitTaskType)) { + throw new RuntimeException("BukkitTaskTypeManager implementation can only accept instances of BukkitTaskType!"); + } if (super.registerTaskType(taskType)) { bukkitTaskType.taskTypeManager = this; - plugin.getServer().getPluginManager().registerEvents(bukkitTaskType, plugin); + this.plugin.getServer().getPluginManager().registerEvents(bukkitTaskType, this.plugin); return true; } + return false; } - public void sendDebug(@NotNull String message, @NotNull String taskType, @NotNull String questId, @NotNull String taskId, @NotNull UUID associatedPlayer) { + /** + * Sends a debug message to players based on their debug preferences. + * + * @param message the debug message to send + * @param taskType the type of task + * @param questId the quest ID + * @param taskId the task ID + * @param associatedPlayer the UUID of the associated player + */ + public void sendDebug(final @NotNull String message, final @NotNull String taskType, final @NotNull String questId, final @NotNull String taskId, final @NotNull UUID associatedPlayer) { String chatHeader = null; - for (QPlayer qPlayer : plugin.getPlayerManager().getQPlayers()) { - QPlayerPreferences.DebugType debugType = qPlayer.getPlayerPreferences().getDebug(questId); + + for (final QPlayer qPlayer : QPlayerPreferences.getDebuggers()) { + final QPlayerPreferences.DebugType debugType = qPlayer.getPlayerPreferences().getDebug(questId); if (debugType == null) { continue; } - Player player = Bukkit.getPlayer(qPlayer.getPlayerUUID()); + final Player player = this.plugin.getServer().getPlayer(qPlayer.getPlayerUUID()); if (player == null) { continue; } if (chatHeader == null) { - Player otherPlayer = Bukkit.getPlayer(associatedPlayer); - String associatedName = otherPlayer != null ? otherPlayer.getName() : associatedPlayer.toString(); + final Player otherPlayer = this.plugin.getServer().getPlayer(associatedPlayer); + final String associatedName = otherPlayer != null ? otherPlayer.getName() : associatedPlayer.toString(); chatHeader = ChatColor.GRAY + "[" + associatedName + " - " + questId + "/" + taskId + " - type '" + taskType + "']"; } @@ -71,5 +105,4 @@ public class BukkitTaskTypeManager extends TaskTypeManager { } } } - } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/EssentialsBalanceTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/EssentialsBalanceTaskType.java index 8f1476ed..150bf16d 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/EssentialsBalanceTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/EssentialsBalanceTaskType.java @@ -15,6 +15,7 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.jetbrains.annotations.NotNull; import java.math.BigDecimal; import java.util.UUID; @@ -32,7 +33,7 @@ public final class EssentialsBalanceTaskType extends BukkitTaskType { } @Override - public void onStart(Quest quest, Task task, UUID playerUUID) { + public void onStart(final @NotNull Quest quest, final @NotNull Task task, final @NotNull UUID playerUUID) { Player player = Bukkit.getPlayer(playerUUID); if (player == null || !player.isOnline() || player.hasMetadata("NPC")) { return; diff --git a/common/src/main/java/com/leonardobishop/quests/common/player/QPlayerPreferences.java b/common/src/main/java/com/leonardobishop/quests/common/player/QPlayerPreferences.java index af387906..c6d6ee12 100644 --- a/common/src/main/java/com/leonardobishop/quests/common/player/QPlayerPreferences.java +++ b/common/src/main/java/com/leonardobishop/quests/common/player/QPlayerPreferences.java @@ -1,37 +1,59 @@ package com.leonardobishop.quests.common.player; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; -public class QPlayerPreferences { +public final class QPlayerPreferences { + + private static Set<QPlayer> debuggers = Collections.newSetFromMap(new WeakHashMap<>()); private final Map<String, DebugType> debug = new HashMap<>(); private String trackedQuestId; - public QPlayerPreferences(String trackedQuestId) { + public QPlayerPreferences(final @Nullable String trackedQuestId) { this.trackedQuestId = trackedQuestId; } public @Nullable String getTrackedQuestId() { - return trackedQuestId; + return this.trackedQuestId; } - public void setTrackedQuestId(@Nullable String trackedQuestId) { + public void setTrackedQuestId(final @Nullable String trackedQuestId) { this.trackedQuestId = trackedQuestId; } - public DebugType getDebug(String questId) { - return debug.getOrDefault(questId, debug.get("*")); + public @Nullable DebugType getDebug(final @NotNull String questId) { + return this.debug.getOrDefault(questId, this.debug.get("*")); + } + + public void setDebug(final @NotNull String questId, final @NotNull DebugType debugType) { + this.debug.put(questId, debugType); + } + + public void unsetDebug(final @NotNull String questId) { + this.debug.remove(questId); } - public void setDebug(String questId, DebugType debugType) { - debug.put(questId, debugType); + public boolean isDebug() { + return !this.debug.isEmpty(); } public enum DebugType { SELF, ALL } + + public static @NotNull Set<QPlayer> getDebuggers() { + return QPlayerPreferences.debuggers; + } + + public static void setDebuggers(final @NotNull Set<QPlayer> debuggers) { + QPlayerPreferences.debuggers = debuggers; + } } diff --git a/common/src/main/java/com/leonardobishop/quests/common/player/questprogressfile/QuestProgressFile.java b/common/src/main/java/com/leonardobishop/quests/common/player/questprogressfile/QuestProgressFile.java index 94f4dfda..e711ff67 100644 --- a/common/src/main/java/com/leonardobishop/quests/common/player/questprogressfile/QuestProgressFile.java +++ b/common/src/main/java/com/leonardobishop/quests/common/player/questprogressfile/QuestProgressFile.java @@ -308,7 +308,7 @@ public class QuestProgressFile { @Deprecated public void clean() { plugin.getQuestsLogger().debug("Cleaning file " + playerUUID + "."); - if (!plugin.getTaskTypeManager().areRegistrationsAccepted()) { + if (!plugin.getTaskTypeManager().areRegistrationsOpen()) { ArrayList<String> invalidQuests = new ArrayList<>(); for (String questId : this.questProgress.keySet()) { Quest q; diff --git a/common/src/main/java/com/leonardobishop/quests/common/tasktype/TaskType.java b/common/src/main/java/com/leonardobishop/quests/common/tasktype/TaskType.java index 08774c01..15946c92 100644 --- a/common/src/main/java/com/leonardobishop/quests/common/tasktype/TaskType.java +++ b/common/src/main/java/com/leonardobishop/quests/common/tasktype/TaskType.java @@ -6,11 +6,11 @@ import com.leonardobishop.quests.common.quest.Task; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; -import java.util.List; +import java.util.HashSet; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; /** @@ -21,41 +21,40 @@ import java.util.UUID; */ public abstract class TaskType { - private final List<Quest> quests = new ArrayList<>(); - private final List<String> aliases = new ArrayList<>(); - private final List<ConfigValidator> configValidators = new ArrayList<>(); - private final String type; - private String author; - private String description; + protected final String type; + private final String author; + private final String description; + private final Set<String> aliases; + private final Set<Quest> quests; + private final Set<ConfigValidator> configValidators; /** + * Constructs a TaskType. + * * @param type the name of the task type, should not contain spaces * @param author the name of the person (or people) who wrote it * @param description a short, simple description of the task type + * @param aliases the aliases of the task type, should not contain spaces */ - public TaskType(@NotNull String type, String author, String description, String... aliases) { - this(type, author, description); - Collections.addAll(this.aliases, aliases); - } + public TaskType(final @NotNull String type, final @Nullable String author, final @Nullable String description, final @NotNull String @NotNull ... aliases) { + Objects.requireNonNull(type, "type cannot be null"); + Objects.requireNonNull(aliases, "aliases cannot be null"); - /** - * @param type the name of the task type, should not contain spaces - * @param author the name of the person (or people) who wrote it - * @param description a short, simple description of the task type - */ - public TaskType(@NotNull String type, String author, String description) { - this(type); + this.type = type; this.author = author; this.description = description; + this.aliases = Set.of(aliases); + this.quests = new HashSet<>(); + this.configValidators = new HashSet<>(); } /** + * Constructs a TaskType with the specified type. + * * @param type the name of the task type, should not contain spaces */ - public TaskType(@NotNull String type) { - Objects.requireNonNull(type, "type cannot be null"); - - this.type = type; + public TaskType(final @NotNull String type) { + this(type, null, null); } /** @@ -64,42 +63,62 @@ public abstract class TaskType { * * @param quest the {@link Quest} to register. */ - public final void registerQuest(@NotNull Quest quest) { + public final void registerQuest(final @NotNull Quest quest) { Objects.requireNonNull(quest, "quest cannot be null"); - if (!quests.contains(quest)) { - quests.add(quest); - } + this.quests.add(quest); } /** - * Clears the list which contains the registered quests. + * Clears the set which contains the registered quests. */ protected final void unregisterAll() { - quests.clear(); + this.quests.clear(); } /** - * @return immutable {@link List} of type {@link Quest} of all registered quests. + * Returns an immutable set of all registered quests. + * + * @return immutable {@link Set} of type {@link Quest} of all registered quests. */ - public final @NotNull List<Quest> getRegisteredQuests() { - return Collections.unmodifiableList(quests); + public final @NotNull Set<Quest> getRegisteredQuests() { + return Collections.unmodifiableSet(this.quests); } + /** + * Returns the type of this task type. + * + * @return the type of this task type + */ public final @NotNull String getType() { - return type; + return this.type; } + /** + * Returns the author of this task type. + * + * @return the author of this task type, or null if not specified + */ public @Nullable String getAuthor() { - return author; + return this.author; } + /** + * Returns the description of this task type. + * + * @return the description of this task type, or null if not specified + */ public @Nullable String getDescription() { - return description; + return this.description; } - public @NotNull List<String> getAliases() { - return Collections.unmodifiableList(aliases); + /** + * Returns the aliases of this task type. + * + * @return a set of aliases of this task type + */ + public @NotNull Set<String> getAliases() { + return this.aliases; } /** @@ -112,27 +131,54 @@ public abstract class TaskType { /** * Called when a player starts a quest containing a task of this type. + * + * @param quest the quest containing the task + * @param task the task being started + * @param playerUUID the UUID of the player starting the task */ - public void onStart(Quest quest, Task task, UUID playerUUID) { + public void onStart(final @NotNull Quest quest, final @NotNull Task task, final @NotNull UUID playerUUID) { // not implemented here } + /** + * Called when a task type is disabled. + */ public void onDisable() { // not implemented here } - public void addConfigValidator(@NotNull ConfigValidator validator) { + /** + * Adds a config validator to this task type. + * + * @param validator the config validator to add + */ + public void addConfigValidator(final @NotNull ConfigValidator validator) { Objects.requireNonNull(validator, "validator cannot be null"); - configValidators.add(validator); + this.configValidators.add(validator); } - public List<ConfigValidator> getConfigValidators() { - return configValidators; + /** + * Returns an immutable set of config validators. + * + * @return an immutable set of config validators + */ + public @NotNull Set<ConfigValidator> getConfigValidators() { + return Collections.unmodifiableSet(this.configValidators); } + /** + * A functional interface for config validation. + */ @FunctionalInterface public interface ConfigValidator { - void validateConfig(@NotNull HashMap<String, Object> taskConfig, @NotNull List<ConfigProblem> problems); + + /** + * Validates the configuration of a task. + * + * @param taskConfig the configuration of the task + * @param problems the set of problems to report validation issues + */ + void validateConfig(final @NotNull Map<String, Object> taskConfig, final @NotNull Set<ConfigProblem> problems); } } diff --git a/common/src/main/java/com/leonardobishop/quests/common/tasktype/TaskTypeManager.java b/common/src/main/java/com/leonardobishop/quests/common/tasktype/TaskTypeManager.java index 3461ec6f..84cf5367 100644 --- a/common/src/main/java/com/leonardobishop/quests/common/tasktype/TaskTypeManager.java +++ b/common/src/main/java/com/leonardobishop/quests/common/tasktype/TaskTypeManager.java @@ -5,11 +5,9 @@ import com.leonardobishop.quests.common.quest.Task; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -21,162 +19,197 @@ import java.util.function.Supplier; * Task types can only be registered if registrations are enabled, which is typically only during start-up. * This is to ensure quests are only registered to task types when all task types have been registered first. */ +@SuppressWarnings("UnusedReturnValue") public abstract class TaskTypeManager { private final Map<String, TaskType> taskTypes = new HashMap<>(); private final Map<String, String> aliases = new HashMap<>(); - private final List<String> exclusions; + private final Set<String> exclusions; private int skipped; - private boolean allowRegistrations; + private int unsupported; + private boolean registrationsOpen; public TaskTypeManager() { - allowRegistrations = true; - exclusions = new ArrayList<>(); + this.registrationsOpen = true; + this.exclusions = Collections.emptySet(); } - public TaskTypeManager(List<String> exclusions) { - allowRegistrations = true; + public TaskTypeManager(final @NotNull Set<String> exclusions) { + this.registrationsOpen = true; this.exclusions = exclusions; } + /** + * Closes the task type registrations. This is typically done after start-up. + */ public void closeRegistrations() { - allowRegistrations = false; + this.registrationsOpen = false; } - public boolean areRegistrationsAccepted() { - return allowRegistrations; + /** + * Checks if registrations are still open. + * + * @return true if registrations are open, false otherwise + */ + public boolean areRegistrationsOpen() { + return this.registrationsOpen; } /** + * Returns an immutable collection containing all registered task types. + * * @return immutable {@link Set} containing all registered {@link TaskType} */ public @NotNull Collection<TaskType> getTaskTypes() { - return Collections.unmodifiableCollection(taskTypes.values()); + return Collections.unmodifiableCollection(this.taskTypes.values()); } /** * Resets all quest to task type registrations. This does not clear the task types registered to the task type manager. */ public void resetTaskTypes() { - for (TaskType taskType : taskTypes.values()) { + for (final TaskType taskType : this.taskTypes.values()) { taskType.unregisterAll(); } } /** - * Register a task type with the task type manager. + * Registers a task type with the task type manager. * * @param taskType the task type to register + * @return true if the task type was successfully registered, false otherwise */ - public boolean registerTaskType(@NotNull TaskType taskType) { + public boolean registerTaskType(final @NotNull TaskType taskType) { Objects.requireNonNull(taskType, "taskType cannot be null"); - if (!allowRegistrations) { + if (!this.registrationsOpen) { throw new IllegalStateException("No longer accepting new task types (must be done before quests are loaded)"); } - if (exclusions.contains(taskType.getType()) || taskTypes.containsKey(taskType.getType())) { - skipped++; + final String type = taskType.getType(); + final Set<String> aliasTypes = taskType.getAliases(); + + if (this.exclusions.contains(type) || this.taskTypes.containsKey(type) + || !Collections.disjoint(this.exclusions, aliasTypes) + || !Collections.disjoint(this.taskTypes.keySet(), aliasTypes) + || !Collections.disjoint(this.aliases.keySet(), aliasTypes)) { + this.skipped++; return false; } - taskTypes.put(taskType.getType(), taskType); - for (String alias : taskType.getAliases()) { - aliases.put(alias, taskType.getType()); + this.taskTypes.put(type, taskType); + for (final String alias : taskType.getAliases()) { + this.aliases.put(alias, type); } return true; } /** - * Register a task type with the task type manager. + * Registers a task type with the task type manager using suppliers. * * @param taskTypeSupplier supplier of the task type to register * @param compatibilitySuppliers suppliers to check for task type compatibility + * @return true if the task type was successfully registered, false otherwise */ - public boolean registerTaskType(@NotNull Supplier<TaskType> taskTypeSupplier, @NotNull BooleanSupplier... compatibilitySuppliers) { + public boolean registerTaskType(final @NotNull Supplier<TaskType> taskTypeSupplier, final @NotNull BooleanSupplier @NotNull ... compatibilitySuppliers) { Objects.requireNonNull(taskTypeSupplier, "taskTypeSupplier cannot be null"); - if (!allowRegistrations) { + if (!this.registrationsOpen) { throw new IllegalStateException("No longer accepting new task types (must be done before quests are loaded)"); } - for (BooleanSupplier supplier : compatibilitySuppliers) { + for (final BooleanSupplier supplier : compatibilitySuppliers) { if (!supplier.getAsBoolean()) { + this.unsupported++; return false; } } - return registerTaskType(taskTypeSupplier.get()); + return this.registerTaskType(taskTypeSupplier.get()); } /** - * Register a quest with its task types. This will register the quest to each task type it contains. + * Registers a quest with its task types. This will register the quest to each task type it contains. * * @param quest the quest to register */ - public void registerQuestTasksWithTaskTypes(@NotNull Quest quest) { + public void registerQuestTasksWithTaskTypes(final @NotNull Quest quest) { Objects.requireNonNull(quest, "quest cannot be null"); - if (allowRegistrations) { + if (this.registrationsOpen) { throw new IllegalStateException("Still accepting new task types (type registrations must be closed before registering quests)"); } - for (Task task : quest.getTasks()) { - TaskType t; - if ((t = getTaskType(task.getType())) != null) { - t.registerQuest(quest); + for (final Task task : quest.getTasks()) { + final TaskType taskType = this.getTaskType(task.getType()); + + if (taskType != null) { + taskType.registerQuest(quest); } } } /** - * Get a registered task type by type + * Gets a registered task type by type. * * @param type the type to check - * @return {@link TaskType} + * @return the {@link TaskType} if found, null otherwise */ - public @Nullable TaskType getTaskType(@NotNull String type) { + public @Nullable TaskType getTaskType(final @NotNull String type) { Objects.requireNonNull(type, "type cannot be null"); - TaskType taskType = taskTypes.get(type); - if (taskType == null) { - if (aliases.get(type) != null) { - return taskTypes.get(aliases.get(type)); - } + final TaskType taskType = this.taskTypes.get(type); + if (taskType != null) { + return taskType; } - return taskType; + + final String aliasType = this.aliases.get(type); + if (aliasType != null) { + return this.taskTypes.get(aliasType); + } + + return null; } /** - * Get the actual name of a task type, following aliases + * Gets the actual name of a task type, following aliases. * - * @param taskType name of task type - * @return actual name + * @param type name of task type + * @return the actual name of the task type, or null if not found */ - public @Nullable String resolveTaskTypeName(@NotNull String taskType) { - Objects.requireNonNull(taskType, "taskType cannot be null"); + public @Nullable String resolveTaskTypeName(final @NotNull String type) { + Objects.requireNonNull(type, "type cannot be null"); - if (taskTypes.containsKey(taskType)) { - return taskType; - } - if (aliases.containsKey(taskType)) { - return aliases.get(taskType); - } - return null; + return this.taskTypes.containsKey(type) + ? type + : this.aliases.get(type); } /** - * @return immutable {@link List} containing all task type exclusions + * Returns an immutable set containing all task type exclusions. + * + * @return immutable {@link Set} containing all task type exclusions */ - public @NotNull List<String> getExclusions() { - return Collections.unmodifiableList(exclusions); + public @NotNull Set<String> getExclusions() { + return Collections.unmodifiableSet(this.exclusions); } /** - * @return number of task types skipped due to exclusions / name conflicts + * Returns the number of task types skipped due to exclusions or name conflicts. + * + * @return number of task types skipped */ public int getSkipped() { - return skipped; + return this.skipped; + } + + /** + * Returns the number of task types skipped due to failing to meet specified requirements. + * + * @return number of task types skipped due to failing to meet specified requirements + */ + public int getUnsupported() { + return this.unsupported; } } |
