diff --git a/cxx/.gitignore b/cxx/.gitignore index e9881e13..796b96d1 100644 --- a/cxx/.gitignore +++ b/cxx/.gitignore @@ -1,2 +1 @@ /build -/include diff --git a/cxx/include/loot/api.h b/cxx/include/loot/api.h new file mode 100644 index 00000000..33dd52ec --- /dev/null +++ b/cxx/include/loot/api.h @@ -0,0 +1,116 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2013-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ + +#ifndef LOOT_API_H +#define LOOT_API_H + +#include +#include +#include +#include + +#include "loot/api_decorator.h" +#include "loot/enum/game_type.h" +#include "loot/enum/log_level.h" +#include "loot/exception/condition_syntax_error.h" +#include "loot/exception/cyclic_interaction_error.h" +#include "loot/exception/error_categories.h" +#include "loot/exception/file_access_error.h" +#include "loot/exception/undefined_group_error.h" +#include "loot/game_interface.h" +#include "loot/loot_version.h" + +namespace loot { +/** + * @} + * @name Logging Functions + * @{ + */ + +/** + * @brief Set the callback function that is called when logging. + * @details If this function is not called, the default behaviour is to + * print messages to the console. + * @param callback + * The function called when logging. The first parameter is the + * level of the message being logged, and the second is the message. + */ +LOOT_API void SetLoggingCallback( + std::function callback); + +/** + * @} + * @name Version Functions + * @{ + */ + +/** + * @brief Checks for API compatibility. + * @details Checks whether the loaded API is compatible with the given + * version of the API, abstracting API stability policy away from + * clients. The version numbering used is major.minor.patch. + * @param major + * The major version number to check. + * @param minor + * The minor version number to check. + * @param patch + * The patch version number to check. + * @returns True if the API versions are compatible, false otherwise. + */ +LOOT_API bool IsCompatible(const unsigned int major, + const unsigned int minor, + const unsigned int patch); + +/** + * @} + * @name Lifecycle Management Functions + * @{ + */ + +/** + * @brief Initialise a new game handle. + * @details Creates a handle for a game, which is then used by all + * game-specific functions. + * @param game + * A game code for which to create the handle. + * @param game_path + * The relative or absolute path to the directory containing the + * game's executable. + * @param game_local_path + * The relative or absolute path to the game's local data folder, or an + * empty path. The local data folder is usually in `%%LOCALAPPDATA%`, but + * Morrowind has no local data folder and OpenMW's is in the user's + * My Games folder on Windows and in `$HOME/.config` on Linux. If an + * empty path is provided, the API will attempt to look up the relevant + * local data path, which may fail in some situations (e.g. when running + * libloot natively on Linux for a game other than Morrowind or OpenMW). + * @returns The new game handle. + */ +LOOT_API std::unique_ptr CreateGameHandle( + const GameType game, + const std::filesystem::path& game_path, + const std::filesystem::path& game_local_path = ""); +} + +#endif diff --git a/cxx/include/loot/api_decorator.h b/cxx/include/loot/api_decorator.h new file mode 100644 index 00000000..8a64d730 --- /dev/null +++ b/cxx/include/loot/api_decorator.h @@ -0,0 +1,44 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2013-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ + +#ifndef LOOT_API_DECORATOR +#define LOOT_API_DECORATOR + +/* set up dll import/export decorators + when compiling the dll on windows, ensure LOOT_EXPORT is defined. clients + that use this header do not need to define anything to import the symbols + properly. */ +#if defined(_WIN32) +#ifdef LOOT_STATIC +#define LOOT_API +#elif defined LOOT_EXPORT +#define LOOT_API __declspec(dllexport) +#else +#define LOOT_API __declspec(dllimport) +#endif +#else +#define LOOT_API +#endif + +#endif diff --git a/cxx/include/loot/database_interface.h b/cxx/include/loot/database_interface.h new file mode 100644 index 00000000..3ce1263e --- /dev/null +++ b/cxx/include/loot/database_interface.h @@ -0,0 +1,235 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_DATABASE_INTERFACE +#define LOOT_DATABASE_INTERFACE + +#include +#include +#include +#include + +#include "loot/exception/cyclic_interaction_error.h" +#include "loot/metadata/group.h" +#include "loot/metadata/message.h" +#include "loot/metadata/plugin_metadata.h" + +namespace loot { +/** @brief The interface provided by API's database handle. */ +class DatabaseInterface { +public: + virtual ~DatabaseInterface() = default; + + /** + * @name Data Reading & Writing + * @{ + */ + + /** + * @brief Loads the masterlist, userlist and masterlist prelude from the + * paths specified. + * @details Can be called multiple times, each time replacing the + * previously-loaded data. + * @param masterlist_path + * The relative or absolute path to the masterlist file that should be + * loaded. + * @param userlist_path + * The relative or absolute path to the userlist file that should be + * loaded, or an empty path. If an empty path, no userlist will be + * loaded. + * @param masterlist_prelude_path + * The relative or absolute path to the masterlist prelude file that + * should be loaded. If an empty path, no masterlist prelude will be + * loaded. + */ + virtual void LoadLists( + const std::filesystem::path& masterlist_path, + const std::filesystem::path& userlist_path = "", + const std::filesystem::path& masterlist_prelude_path = "") = 0; + + /** + * Writes a metadata file containing all loaded user-added metadata. + * @param outputFile + * The path to which the file shall be written. + * @param overwrite + * If `false` and `outputFile` already exists, no data will be + * written. Otherwise, data will be written. + */ + virtual void WriteUserMetadata(const std::filesystem::path& outputFile, + const bool overwrite) const = 0; + + /** + * @brief Writes a minimal metadata file that only contains plugins with + * Bash Tag suggestions and/or dirty info, plus the suggestions and + * info themselves. + * @param outputFile + * The path to which the file shall be written. + * @param overwrite + * If `false` and `outputFile` already exists, no data will be + * written. Otherwise, data will be written. + */ + virtual void WriteMinimalList(const std::filesystem::path& outputFile, + const bool overwrite) const = 0; + + /** + * @} + * @name Non-plugin Data Access + * @{ + */ + + /** + * @brief Gets the Bash Tags that are listed in the loaded metadata lists. + * @details Bash Tag suggestions can include Bash Tags not in this list. + * @returns A set of Bash Tag names. + */ + virtual std::vector GetKnownBashTags() const = 0; + + /** + * @brief Get all general messages listen in the loaded metadata lists. + * @param evaluateConditions + * If true, any metadata conditions are evaluated before the metadata + * is returned, otherwise unevaluated metadata is returned. Evaluating + * general message conditions also clears the condition cache before + * evaluating conditions. + * @returns A vector of messages supplied in the metadata lists but not + * attached to any particular plugin. + */ + virtual std::vector GetGeneralMessages( + bool evaluateConditions = false) const = 0; + + /** + * @brief Gets the groups that are defined in the loaded metadata lists. + * @param includeUserMetadata + * If true, any group metadata present in the userlist is included in + * the returned metadata, otherwise the metadata returned only includes + * metadata from the masterlist. + * @returns An vector of Group objects. Each Group's name is unique, if a + * group has masterlist and user metadata the two are merged into a + * single group object. + */ + virtual std::vector GetGroups( + bool includeUserMetadata = true) const = 0; + + /** + * @brief Gets the groups that are defined or extended in the loaded userlist. + * @returns An unordered set of Group objects. + */ + virtual std::vector GetUserGroups() const = 0; + + /** + * @brief Sets the group definitions to store in the userlist, overwriting any + * existing definitions there. + * @param groups + * The unordered set of Group objects to set. + */ + virtual void SetUserGroups(const std::vector& groups) = 0; + + /** + * @brief Get the "shortest" path between the two given groups according to + * their load after metadata. + * @details The "shortest" path is defined as the path that maximises the + * amount of user metadata involved while minimising the amount of + * masterlist metadata involved. It's not the path involving the + * fewest groups. + * @param fromGroupName + * The name of the source group, that loads earlier. + * @param toGroupName + * The name of the destination group, that loads later. + * @returns A vector of Vertex elements representing the path from the source + * group to the destination group, or an empty vector if no path + * exists. + */ + virtual std::vector GetGroupsPath( + const std::string& fromGroupName, + const std::string& toGroupName) const = 0; + + /** + * @} + * @name Plugin Data Access + * @{ + */ + + /** + * @brief Get all a plugin's loaded metadata. + * @param plugin + * The filename of the plugin to look up metadata for. + * @param includeUserMetadata + * If true, any user metadata the plugin has is included in the + * returned metadata, otherwise the metadata returned only includes + * metadata from the masterlist. + * @param evaluateConditions + * If true, any metadata conditions are evaluated before the metadata + * is returned, otherwise unevaluated metadata is returned. Evaluating + * plugin metadata conditions does not clear the condition cache. + * @returns If the plugin has metadata, an optional containing that metadata, + * otherwise an optional containing no value. + */ + virtual std::optional GetPluginMetadata( + const std::string& plugin, + bool includeUserMetadata = true, + bool evaluateConditions = false) const = 0; + + /** + * @brief Get a plugin's metadata loaded from the given userlist. + * @param plugin + * The filename of the plugin to look up user-added metadata for. + * @param evaluateConditions + * If true, any metadata conditions are evaluated before the metadata + * is returned, otherwise unevaluated metadata is returned. Evaluating + * plugin metadata conditions does not clear the condition cache. + * @returns If the plugin has user-added metadata, an optional containing + * that metadata, otherwise an optional containing no value. + */ + virtual std::optional GetPluginUserMetadata( + const std::string& plugin, + bool evaluateConditions = false) const = 0; + + /** + * @brief Sets a plugin's user metadata, overwriting any existing user + * metadata. + * @param pluginMetadata + * The user metadata you want to set, with plugin.Name() being the + * filename of the plugin the metadata is for. + */ + virtual void SetPluginUserMetadata(const PluginMetadata& pluginMetadata) = 0; + + /** + * @brief Discards all loaded user metadata for the plugin with the given + * filename. + * @param plugin + * The filename of the plugin for which all user-added metadata + * should be deleted. + */ + virtual void DiscardPluginUserMetadata(const std::string& plugin) = 0; + + /** + * @brief Discards all loaded user metadata for all plugins, and any + * user-added general messages and known bash tags. + */ + virtual void DiscardAllUserMetadata() = 0; + + /** @} */ +}; +} + +#endif diff --git a/cxx/include/loot/enum/edge_type.h b/cxx/include/loot/enum/edge_type.h new file mode 100644 index 00000000..db7b135c --- /dev/null +++ b/cxx/include/loot/enum/edge_type.h @@ -0,0 +1,53 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2012-2016 WrinklyNinja + +This file is part of LOOT. + +LOOT is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +LOOT is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LOOT. If not, see +. +*/ + +#ifndef LOOT_EDGE_TYPE +#define LOOT_EDGE_TYPE + +/** + * The namespace used by libloot. + */ +namespace loot { +/** + * @brief An enum representing the different possible types of interactions + * between plugins or groups. + */ +enum struct EdgeType : unsigned int { + hardcoded, + masterFlag, + master, + masterlistRequirement, + userRequirement, + masterlistLoadAfter, + userLoadAfter, + masterlistGroup, + userGroup, + recordOverlap, + assetOverlap, + tieBreak, + blueprintMaster, +}; +} + +#endif diff --git a/cxx/include/loot/enum/game_type.h b/cxx/include/loot/enum/game_type.h new file mode 100644 index 00000000..ccec865c --- /dev/null +++ b/cxx/include/loot/enum/game_type.h @@ -0,0 +1,59 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2012-2016 WrinklyNinja + +This file is part of LOOT. + +LOOT is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +LOOT is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LOOT. If not, see +. +*/ + +#ifndef LOOT_GAME_TYPE +#define LOOT_GAME_TYPE + +/** + * The namespace used by libloot. + */ +namespace loot { +/** @brief Codes used to create database handles for specific games. */ +enum struct GameType : unsigned int { + /** The Elder Scrolls IV: Oblivion */ + tes4, + /** The Elder Scrolls V: Skyrim */ + tes5, + /** Fallout 3 */ + fo3, + /** Fallout: New Vegas */ + fonv, + /** Fallout 4 */ + fo4, + /** The Elder Scrolls V: Skyrim Special Edition */ + tes5se, + /** Fallout 4 VR */ + fo4vr, + /** Skyrim VR */ + tes5vr, + /** The Elder Scrolls III: Morrowind */ + tes3, + /** Starfield */ + starfield, + /** OpenMW */ + openmw +}; +} + +#endif diff --git a/cxx/include/loot/enum/log_level.h b/cxx/include/loot/enum/log_level.h new file mode 100644 index 00000000..5fbb0e84 --- /dev/null +++ b/cxx/include/loot/enum/log_level.h @@ -0,0 +1,45 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2012-2016 WrinklyNinja + +This file is part of LOOT. + +LOOT is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +LOOT is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LOOT. If not, see +. +*/ + +#ifndef LOOT_LOG_LEVEL +#define LOOT_LOG_LEVEL + +/** + * The namespace used by libloot. + */ +namespace loot { +/** + * @brief Codes used to specify different levels of API logging. + */ +enum struct LogLevel : unsigned int { + trace, + debug, + info, + warning, + error, + fatal +}; +} + +#endif diff --git a/cxx/include/loot/enum/message_type.h b/cxx/include/loot/enum/message_type.h new file mode 100644 index 00000000..c726b7c5 --- /dev/null +++ b/cxx/include/loot/enum/message_type.h @@ -0,0 +1,49 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2012-2016 WrinklyNinja + +This file is part of LOOT. + +LOOT is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +LOOT is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LOOT. If not, see +. +*/ + +#ifndef LOOT_MESSAGE_TYPE +#define LOOT_MESSAGE_TYPE + +/** + * The namespace used by libloot. + */ +namespace loot { +/** @brief Codes used to indicate the type of a message. */ +enum struct MessageType : unsigned int { + /** A notification message that is of no significant severity. */ + say, + /** + * A warning message, used to indicate that an issue may be present that the + * user may wish to act on. + */ + warn, + /** + * An error message, used to indicate that an issue that requires user action + * is present. + */ + error, +}; +} + +#endif diff --git a/cxx/include/loot/exception/condition_syntax_error.h b/cxx/include/loot/exception/condition_syntax_error.h new file mode 100644 index 00000000..105e0a86 --- /dev/null +++ b/cxx/include/loot/exception/condition_syntax_error.h @@ -0,0 +1,41 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ + +#ifndef LOOT_EXCEPTION_CONDITION_SYNTAX_ERROR +#define LOOT_EXCEPTION_CONDITION_SYNTAX_ERROR + +#include + +namespace loot { +/** + * @brief An exception class thrown if invalid syntax is encountered when + * parsing a metadata condition. + */ +class ConditionSyntaxError : public std::system_error { +public: + using std::system_error::system_error; +}; +} + +#endif diff --git a/cxx/include/loot/exception/cyclic_interaction_error.h b/cxx/include/loot/exception/cyclic_interaction_error.h new file mode 100644 index 00000000..dea19fde --- /dev/null +++ b/cxx/include/loot/exception/cyclic_interaction_error.h @@ -0,0 +1,61 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ + +#ifndef LOOT_EXCEPTION_CYCLIC_INTERACTION_ERROR +#define LOOT_EXCEPTION_CYCLIC_INTERACTION_ERROR + +#include +#include + +#include "loot/api_decorator.h" +#include "loot/vertex.h" + +namespace loot { +/** + * @brief An exception class thrown if a cyclic interaction is detected when + * sorting a load order. + */ +class CyclicInteractionError : public std::runtime_error { +public: + /** + * @brief Construct an exception detailing a plugin or group graph cycle. + * @param cycle A representation of the cyclic path. + */ + LOOT_API CyclicInteractionError(std::vector cycle); + + /** + * @brief Get a representation of the cyclic path. + * @details Each Vertex is the name of a graph element (plugin or group) and + * the type of the edge going to the next Vertex. The last Vertex + * has an edge going to the first Vertex. + * @return A vector of Vertex elements representing the cyclic path. + */ + LOOT_API std::vector GetCycle() const; + +private: + std::vector cycle_; +}; +} + +#endif diff --git a/cxx/include/loot/exception/error_categories.h b/cxx/include/loot/exception/error_categories.h new file mode 100644 index 00000000..710cfa5a --- /dev/null +++ b/cxx/include/loot/exception/error_categories.h @@ -0,0 +1,58 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ + +#ifndef LOOT_ERROR_CATEGORIES +#define LOOT_ERROR_CATEGORIES + +#include + +#include "loot/api_decorator.h" + +namespace loot { +/** + * @brief Get the error category that can be used to identify system_error + * exceptions that are due to esplugin errors. + * @returns A reference to the static object of unspecified runtime type, + * derived from std::error_category. + */ +LOOT_API const std::error_category& esplugin_category(); + +/** + * @brief Get the error category that can be used to identify system_error + * exceptions that are due to libloadorder errors. + * @returns A reference to the static object of unspecified runtime type, + * derived from std::error_category. + */ +LOOT_API const std::error_category& libloadorder_category(); + +/** + * @brief Get the error category that can be used to identify system_error + * exceptions that are due to loot condition interpreter errors. + * @returns A reference to the static object of unspecified runtime type, + * derived from std::error_category. + */ +LOOT_API const std::error_category& loot_condition_interpreter_category(); +} + +#endif diff --git a/cxx/include/loot/exception/file_access_error.h b/cxx/include/loot/exception/file_access_error.h new file mode 100644 index 00000000..af4ab237 --- /dev/null +++ b/cxx/include/loot/exception/file_access_error.h @@ -0,0 +1,41 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ + +#ifndef LOOT_EXCEPTION_FILE_ACCESS_ERROR +#define LOOT_EXCEPTION_FILE_ACCESS_ERROR + +#include + +namespace loot { +/** + * @brief An exception class thrown if an error is encountered while reading or + * writing a file. + */ +class FileAccessError : public std::runtime_error { +public: + using std::runtime_error::runtime_error; +}; +} + +#endif diff --git a/cxx/include/loot/exception/undefined_group_error.h b/cxx/include/loot/exception/undefined_group_error.h new file mode 100644 index 00000000..008b3ae0 --- /dev/null +++ b/cxx/include/loot/exception/undefined_group_error.h @@ -0,0 +1,55 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ + +#ifndef LOOT_EXCEPTION_UNDEFINED_GROUP_ERROR +#define LOOT_EXCEPTION_UNDEFINED_GROUP_ERROR + +#include + +#include "loot/api_decorator.h" + +namespace loot { +/** + * @brief An exception class thrown if group is referenced but is undefined. + */ +class UndefinedGroupError : public std::runtime_error { +public: + /** + * @brief Construct an exception for an undefined group. + * @param groupName The name of the group that is undefined. + */ + LOOT_API UndefinedGroupError(const std::string& groupName); + + /** + * Get the name of the undefined group. + * @return A group name. + */ + LOOT_API std::string GetGroupName() const; + +private: + std::string groupName_; +}; +} + +#endif diff --git a/cxx/include/loot/game_interface.h b/cxx/include/loot/game_interface.h new file mode 100644 index 00000000..a0115027 --- /dev/null +++ b/cxx/include/loot/game_interface.h @@ -0,0 +1,241 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_GAME_INTERFACE +#define LOOT_GAME_INTERFACE + +#include "loot/database_interface.h" +#include "loot/plugin_interface.h" + +namespace loot { +/** @brief The interface provided for accessing game-specific functionality. */ +class GameInterface { +public: + virtual ~GameInterface() = default; + + /** + * @brief Get the game's type. + * @returns The game's type. + */ + virtual GameType GetType() const = 0; + + /** + * @brief Gets the currently-set additional data paths. + * @details The following games are configured with additional data paths by + * default: + * - Fallout 4, when installed from the Microsoft Store + * - Starfield + * - OpenMW + */ + virtual std::vector GetAdditionalDataPaths() const = 0; + + /** + * @brief Set additional data paths. + * @details The additional data paths are used when interacting with the load + * order, evaluating conditions and scanning for archives (BSA/BA2 + * depending on the game). Additional data paths are used in the + * order they are given (except with OpenMW, which checks them in + * reverse order), and take precedence over the game's main data + * path. + */ + virtual void SetAdditionalDataPaths( + const std::vector& additionalDataPaths) = 0; + + /** + * @name Metadata Access + * @{ + */ + + /** + * @brief Get the database interface used for accessing metadata-related + * functionality. + * @returns A reference to the game's DatabaseInterface. The reference remains + * valid for the lifetime of the GameInterface instance. + */ + virtual DatabaseInterface& GetDatabase() = 0; + + /** + * @brief Get the database interface used for accessing metadata-related + * functionality. + * @returns A reference to the game's DatabaseInterface. The reference remains + * valid for the lifetime of the GameInterface instance. + */ + virtual const DatabaseInterface& GetDatabase() const = 0; + + /** + * @} + * @name Plugin Data Access + * @{ + */ + + /** + * @brief Check if a file is a valid plugin. + * @details The validity check is not exhaustive: it generally checks that the + * file is a valid plugin file extension for the game and that its + * header (if applicable) can be parsed. + * @param pluginPath + * The path to the file to check. Relative paths are resolved relative + * to the game's plugins directory, while absolute paths are used + * as given. + * @returns True if the file is a valid plugin, false otherwise. + */ + virtual bool IsValidPlugin(const std::filesystem::path& pluginPath) const = 0; + + /** + * @brief Parses plugins and loads their data. + * @details If a given plugin filename (or one that is case-insensitively + * equal) has already been loaded, its previously-loaded data + * data is discarded, invalidating any existing shared pointers to + * that plugin's PluginInterface object. + * + * If the game is Morrowind, OpenMW or Starfield, it's only valid to + * fully load a plugin if its masters are already loaded or included + * in the same input vector. + * @param pluginPaths + * The plugin paths to load. Relative paths are resolved relative to + * the game's plugins directory, while absolute paths are used as + * given. Each plugin filename must be unique within the vector. + * @param loadHeadersOnly + * If true, only the plugins' headers are loaded. If false, all records + * in the plugins are parsed. + */ + virtual void LoadPlugins( + const std::vector& pluginPaths, + bool loadHeadersOnly) = 0; + + /** + * @brief Clears the plugins loaded by previous calls to `LoadPlugins()`. + * @details This invalidates any PluginInterface pointers retrieved using + * `GetPlugin()` or `GetLoadedPlugins()`. + */ + virtual void ClearLoadedPlugins() = 0; + + /** + * @brief Get data for a loaded plugin. + * @param pluginName + * The filename of the plugin to get data for. + * @returns A shared pointer to a const PluginInterface implementation. The + * pointer is null if the given plugin has not been loaded. The + * pointer remains valid until the `ClearLoadedPlugins()` function + * is called, this GameInterface is destroyed, or until a plugin with + * a case-insensitively equal filename is loaded. + */ + virtual const PluginInterface* GetPlugin( + const std::string& pluginName) const = 0; + + /** + * @brief Get a set of const references to all loaded plugins' PluginInterface + * objects. + * @returns A set of shared pointers to const PluginInterface. The pointers + * remain valid until the `ClearLoadedPlugins()` function is called, + * this GameInterface is destroyed, or until a plugin with a + * case-insensitively equal filename is loaded. + */ + virtual std::vector GetLoadedPlugins() const = 0; + + /** + * @} + * @name Sorting + * @{ + */ + + /** + * @brief Calculates a new load order for the game's installed plugins + * (including inactive plugins) and outputs the sorted order. + * @details Pulls metadata from the masterlist and userlist if they are + * loaded, and reads the contents of each plugin. No changes are + * applied to the load order used by the game. This function does + * not load or evaluate the masterlist or userlist. + * @param pluginPaths + * The plugins to sort, in their current load order. All given plugins + * must have been loaded using `LoadPlugins()`. + * @returns A vector of the given plugin filenames in their sorted load + * order. + */ + virtual std::vector SortPlugins( + const std::vector& pluginFilenames) = 0; + + /** + * @} + * @name Load Order Interaction + * @{ + */ + + /** + * + * @brief Load the current load order state, discarding any previously held + * state. + * @details This function should be called whenever the load order or active + * state of plugins "on disk" changes, so that the cached state is + * updated to reflect the changes. + */ + virtual void LoadCurrentLoadOrderState() = 0; + + /** + * @brief Check if the load order is ambiguous. + * @details This checks that all plugins in the current load order state have + * a well-defined position in the "on disk" state, and that all data + * sources are consistent. If the load order is ambiguous, different + * applications may read different load orders from the same source + * data. + * @returns True if the load order is ambiguous, false otherwise. + */ + virtual bool IsLoadOrderAmbiguous() const = 0; + + /** + * @brief Gets the path to the file that holds the list of active plugins. + * @details The active plugins file path is often within the game's local + path, but its name and location varies by game and game + configuration, so this function exposes the path that libloot + uses. + * @returns The file path. + */ + virtual std::filesystem::path GetActivePluginsFilePath() const = 0; + + /** + * @brief Check if a plugin is active. + * @param plugin + * The filename of the plugin for which to check the active state. + * @returns True if the plugin is active, false otherwise. + */ + virtual bool IsPluginActive(const std::string& plugin) const = 0; + + /** + * @brief Get the current load order. + * @returns A vector of plugin filenames in their load order. + */ + virtual std::vector GetLoadOrder() const = 0; + + /** + * @brief Set the game's load order. + * @details There is no way to persist the load order of inactive OpenMW + * plugins, so setting an OpenMW load order will have no effect if + * the relative order of active plugins is unchanged. + * @param loadOrder + * A vector of plugin filenames sorted in the load order to set. + */ + virtual void SetLoadOrder(const std::vector& loadOrder) = 0; +}; +} + +#endif diff --git a/cxx/include/loot/loot_version.h b/cxx/include/loot/loot_version.h new file mode 100644 index 00000000..65e8916d --- /dev/null +++ b/cxx/include/loot/loot_version.h @@ -0,0 +1,55 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2014-2016 WrinklyNinja + +This file is part of LOOT. + +LOOT is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +LOOT is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LOOT. If not, see +. +*/ + +#ifndef LOOT_LOOT_VERSION +#define LOOT_LOOT_VERSION + +#include + +#include "loot/api_decorator.h" + +namespace loot { +/** @brief libloot's major version number. */ +inline constexpr unsigned int LIBLOOT_VERSION_MAJOR = 0; + +/** @brief libloot's minor version number. */ +inline constexpr unsigned int LIBLOOT_VERSION_MINOR = 25; + +/** @brief libloot's patch version number. */ +inline constexpr unsigned int LIBLOOT_VERSION_PATCH = 3; + +/** + * @brief Get the library version. + * @return A string of the form "major.minor.patch". + */ +LOOT_API std::string GetLiblootVersion(); + +/** + * @brief Get the source control revision that libloot was built from. + * @return A string containing the revision ID. + */ +LOOT_API std::string GetLiblootRevision(); +} + +#endif diff --git a/cxx/include/loot/metadata/conditional_metadata.h b/cxx/include/loot/metadata/conditional_metadata.h new file mode 100644 index 00000000..cd47658b --- /dev/null +++ b/cxx/include/loot/metadata/conditional_metadata.h @@ -0,0 +1,69 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_METADATA_CONDITIONAL_METADATA +#define LOOT_METADATA_CONDITIONAL_METADATA + +#include + +#include "loot/api_decorator.h" + +namespace loot { +/** + * A base class for metadata that can be conditional based on the result of + * evaluating a condition string. + */ +class ConditionalMetadata { +public: + /** + * Construct a ConditionalMetadata object with an empty condition string. + * @return A ConditionalMetadata object. + */ + LOOT_API ConditionalMetadata() = default; + + /** + * Construct a ConditionalMetadata object with a given condition string. + * @param condition + * A condition string, as defined in the LOOT metadata syntax + * documentation. + * @return A ConditionalMetadata object. + */ + LOOT_API explicit ConditionalMetadata(const std::string& condition); + + /** + * Check if the condition string is non-empty. + * @return True if the condition string is not empty, false otherwise. + */ + LOOT_API bool IsConditional() const; + + /** + * Get the condition string. + * @return The object's condition string. + */ + LOOT_API std::string GetCondition() const; + +private: + std::string condition_; +}; +} +#endif diff --git a/cxx/include/loot/metadata/file.h b/cxx/include/loot/metadata/file.h new file mode 100644 index 00000000..e7d1934d --- /dev/null +++ b/cxx/include/loot/metadata/file.h @@ -0,0 +1,137 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_METADATA_FILE +#define LOOT_METADATA_FILE + +#include + +#include "loot/api_decorator.h" +#include "loot/metadata/conditional_metadata.h" +#include "loot/metadata/filename.h" +#include "loot/metadata/message_content.h" + +namespace loot { +/** + * Represents a file in a game's Data folder, including files in subdirectories. + */ +class File : public ConditionalMetadata { +public: + /** + * Construct a File with blank name, display and condition strings. + * @return A File object. + */ + LOOT_API File() = default; + + /** + * Construct a File with the given name, display name and condition strings. + * @param name + * The filename of the file. + * @param display + * The name to be displayed for the file in messages, formatted using + * CommonMark. + * @param condition + * The File's condition string. + * @param detail + * The detail message content, which may be appended to any messages + * generated for this file. If multilingual, one language must be + * English. + * @return A File object. + */ + LOOT_API explicit File(const std::string& name, + const std::string& display = "", + const std::string& condition = "", + const std::vector& detail = {}); + + /** + * Get the filename of the file. + * @return The file's filename. + */ + LOOT_API Filename GetName() const; + + /** + * Get the display name of the file. + * @return The file's display name. + */ + LOOT_API std::string GetDisplayName() const; + + /** + * Get the detail message content of the file. + * + * If this file causes an error message to be displayed, the detail message + * content should be appended to that message, as it provides more detail + * about the error (e.g. suggestions for how to resolve it). + */ + LOOT_API std::vector GetDetail() const; + +private: + Filename name_; + std::string display_; + std::vector detail_; +}; + +/** + * Check if two File objects are equal by comparing their fields. + * @returns True if the objects' fields are equal, false otherwise. + */ +LOOT_API bool operator==(const File& lhs, const File& rhs); + +/** + * Check if two File objects are not equal. + * @returns True if the File objects are not equal, false otherwise. + */ +LOOT_API bool operator!=(const File& lhs, const File& rhs); + +/** + * A less-than operator implemented with no semantics so that File objects can + * be stored in sets. + * @returns True if the first File is less than the second File, false + * otherwise. + */ +LOOT_API bool operator<(const File& lhs, const File& rhs); + +/** + * Check if the first File object is greater than the second File object. + * @returns True if the second File object is less than the first File object, + * false otherwise. + */ +LOOT_API bool operator>(const File& lhs, const File& rhs); + +/** + * Check if the first File object is less than or equal to the second File + * object. + * @returns True if the first File object is not greater than the second File + * object, false otherwise. + */ +LOOT_API bool operator<=(const File& lhs, const File& rhs); + +/** + * Check if the first File object is greater than or equal to the second File + * object. + * @returns True if the first File object is not less than the second File + * object, false otherwise. + */ +LOOT_API bool operator>=(const File& lhs, const File& rhs); +} + +#endif diff --git a/cxx/include/loot/metadata/filename.h b/cxx/include/loot/metadata/filename.h new file mode 100644 index 00000000..b09fa2be --- /dev/null +++ b/cxx/include/loot/metadata/filename.h @@ -0,0 +1,104 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_METADATA_FILENAME +#define LOOT_METADATA_FILENAME + +#include + +#include "loot/api_decorator.h" + +namespace loot { +/** + * Represents a case-insensitive filename. + */ +class Filename { +public: + /** + * Construct a Filename using an empty string. + * @return A Filename object. + */ + LOOT_API Filename() = default; + + /** + * Construct a Filename using the given string. + * @return A Filename object. + */ + LOOT_API explicit Filename(const std::string& filename); + + /** + * Get this Filename as a string. + */ + LOOT_API explicit operator std::string() const; + +private: + std::string filename_; +}; + +/** + * Check if two Filename objects are equal by comparing their fields. + * @returns True if the filenames are case-insensitively equal and all other + * fields are case-sensitively equal, false otherwise. + */ +LOOT_API bool operator==(const Filename& lhs, const Filename& rhs); + +/** + * Check if two Filename objects are not equal. + * @returns True if the Filename objects are not equal, false otherwise. + */ +LOOT_API bool operator!=(const Filename& lhs, const Filename& rhs); + +/** + * A less-than operator implemented with no semantics so that Filename objects + * can be stored in sets. + * @returns True if this Filename is less than the given Filename, false + * otherwise. + */ +LOOT_API bool operator<(const Filename& lhs, const Filename& rhs); + +/** + * Check if the first Filename object is greater than the second Filename + * object. + * @returns True if the second Filename object is less than the first Filename + * object, false otherwise. + */ +LOOT_API bool operator>(const Filename& lhs, const Filename& rhs); + +/** + * Check if the first Filename object is less than or equal to the second + * Filename object. + * @returns True if the first Filename object is not greater than the second + * Filename object, false otherwise. + */ +LOOT_API bool operator<=(const Filename& lhs, const Filename& rhs); + +/** + * Check if the first Filename object is greater than or equal to the second + * Filename object. + * @returns True if the first Filename object is not less than the second + * Filename object, false otherwise. + */ +LOOT_API bool operator>=(const Filename& lhs, const Filename& rhs); +} + +#endif diff --git a/cxx/include/loot/metadata/group.h b/cxx/include/loot/metadata/group.h new file mode 100644 index 00000000..adf78ce3 --- /dev/null +++ b/cxx/include/loot/metadata/group.h @@ -0,0 +1,134 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2018 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_METADATA_GROUP +#define LOOT_METADATA_GROUP + +#include +#include + +#include "loot/api_decorator.h" + +namespace loot { +/** + * Represents a group to which plugin metadata objects can belong. + */ +class Group { +public: + /** + * The name of the group to which all plugins belong by default. + */ + static constexpr const char* DEFAULT_NAME = "default"; + + /** + * Construct a Group with the name "default" and an empty set of groups to + * load after. + * @return A Group object. + */ + LOOT_API Group() = default; + + /** + * Construct a Group with the given name, description and set of groups to + * load after. + * @param name + * The group name. + * @param afterGroups + * The names of groups this group loads after. + * @param description + * A description of the group. + * @return A Group object. + */ + LOOT_API explicit Group(const std::string& name, + const std::vector& afterGroups = {}, + const std::string& description = ""); + + /** + * Get the name of the group. + * @return The group's name. + */ + LOOT_API std::string GetName() const; + + /** + * Get the description of the group. + * @return The group's description. + */ + LOOT_API std::string GetDescription() const; + + /** + * Get the set of groups this group loads after. + * @return A set of group names. + */ + LOOT_API std::vector GetAfterGroups() const; + +private: + std::string name_{DEFAULT_NAME}; + std::string description_; + std::vector afterGroups_; +}; + +/** + * Check if two Group objects are equal by comparing their names. + * @returns True if the objects' fields are equal, false otherwise. + */ +LOOT_API bool operator==(const Group& lhs, const Group& rhs); + +/** + * Check if two Group objects are not equal. + * @returns True if the Group objects are not equal, false otherwise. + */ +LOOT_API bool operator!=(const Group& lhs, const Group& rhs); + +/** + * A less-than operator implemented with no semantics so that Group objects + * can be stored in sets. + * @returns True if the first Group is less than the second Group, false + * otherwise. + */ +LOOT_API bool operator<(const Group& lhs, const Group& rhs); + +/** + * Check if the first Group object is greater than the second Group + * object. + * @returns True if the second Group object is less than the first Group + * object, false otherwise. + */ +LOOT_API bool operator>(const Group& lhs, const Group& rhs); + +/** + * Check if the first Group object is less than or equal to the second + * Group object. + * @returns True if the first Group object is not greater than the second + * Group object, false otherwise. + */ +LOOT_API bool operator<=(const Group& lhs, const Group& rhs); + +/** + * Check if the first Group object is greater than or equal to the second + * Group object. + * @returns True if the first Group object is not less than the second + * Group object, false otherwise. + */ +LOOT_API bool operator>=(const Group& lhs, const Group& rhs); +} + +#endif diff --git a/cxx/include/loot/metadata/location.h b/cxx/include/loot/metadata/location.h new file mode 100644 index 00000000..66b319f7 --- /dev/null +++ b/cxx/include/loot/metadata/location.h @@ -0,0 +1,117 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_METADATA_LOCATION +#define LOOT_METADATA_LOCATION + +#include +#include + +#include "loot/api_decorator.h" + +namespace loot { +/** + * Represents a URL at which the parent plugin can be found. + */ +class Location { +public: + /** + * Construct a Location with empty URL and name strings. + * @return A Location object. + */ + LOOT_API Location() = default; + + /** + * Construct a Location with the given URL and name. + * @param url + * The URL at which the plugin can be found. + * @param name + * A name for the URL, eg. the page or site name. + * @return A Location object. + */ + LOOT_API explicit Location(const std::string& url, + const std::string& name = ""); + + /** + * Get the object's URL. + * @return A URL string. + */ + LOOT_API std::string GetURL() const; + + /** + * Get the object's name. + * @return The name of the location. + */ + LOOT_API std::string GetName() const; + +private: + std::string url_; + std::string name_; +}; + +/** + * Check if two Location objects are equal by comparing their fields. + * @returns True if the objects' fields are equal, false otherwise. + */ +LOOT_API bool operator==(const Location& lhs, const Location& rhs); + +/** + * Check if two Location objects are not equal. + * @returns True if the Location objects are not equal, false otherwise. + */ +LOOT_API bool operator!=(const Location& lhs, const Location& rhs); + +/** + * A less-than operator implemented with no semantics so that Location objects + * can be stored in sets. + * @returns True if the first Location is less than the second Location, false + * otherwise. + */ +LOOT_API bool operator<(const Location& lhs, const Location& rhs); + +/** + * Check if the first Location object is greater than the second Location + * object. + * @returns True if the second Location object is less than the first Location + * object, false otherwise. + */ +LOOT_API bool operator>(const Location& lhs, const Location& rhs); + +/** + * Check if the first Location object is less than or equal to the second + * Location object. + * @returns True if the first Location object is not greater than the second + * Location object, false otherwise. + */ +LOOT_API bool operator<=(const Location& lhs, const Location& rhs); + +/** + * Check if the first Location object is greater than or equal to the second + * Location object. + * @returns True if the first Location object is not less than the second + * Location object, false otherwise. + */ +LOOT_API bool operator>=(const Location& lhs, const Location& rhs); +} + +#endif diff --git a/cxx/include/loot/metadata/message.h b/cxx/include/loot/metadata/message.h new file mode 100644 index 00000000..735d59b1 --- /dev/null +++ b/cxx/include/loot/metadata/message.h @@ -0,0 +1,139 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_METADATA_MESSAGE +#define LOOT_METADATA_MESSAGE + +#include +#include + +#include "loot/api_decorator.h" +#include "loot/enum/message_type.h" +#include "loot/metadata/conditional_metadata.h" +#include "loot/metadata/message_content.h" + +namespace loot { +/** + * Represents a message with localisable text content. + */ +class Message : public ConditionalMetadata { +public: + /** + * Construct a Message object of type 'say' with blank content and condition + * strings. + * @return A Message object. + */ + LOOT_API Message() = default; + + /** + * Construct a Message object with the given type, English content and + * condition string. + * @param type + * The message type. + * @param content + * The English message content text. + * @param condition + * A condition string. + * @return A Message object. + */ + LOOT_API explicit Message(const MessageType type, + const std::string& content, + const std::string& condition = ""); + + /** + * Construct a Message object with the given type, content and condition + * string. + * @param type + * The message type. + * @param content + * The message content. If multilingual, one language must be English. + * @param condition + * A condition string. + * @return A Message object. + */ + LOOT_API explicit Message(const MessageType type, + const std::vector& content, + const std::string& condition = ""); + + /** + * Get the message type. + * @return The message type. + */ + LOOT_API MessageType GetType() const; + + /** + * Get the message content. + * @return The message's MessageContent objects. + */ + LOOT_API std::vector GetContent() const; + +private: + MessageType type_{MessageType::say}; + std::vector content_; +}; + +/** + * Check if two Message objects are equal by comparing their fields. + * @returns True if the objects' fields are equal, false otherwise. + */ +LOOT_API bool operator==(const Message& lhs, const Message& rhs); + +/** + * Check if two Message objects are not equal. + * @returns True if the Message objects are not equal, false otherwise. + */ +LOOT_API bool operator!=(const Message& lhs, const Message& rhs); + +/** + * A less-than operator implemented with no semantics so that Message objects + * can be stored in sets. + * @returns Returns true if the first Message is less than the second Message, + * and false otherwise. + */ +LOOT_API bool operator<(const Message& lhs, const Message& rhs); + +/** + * Check if the first Message object is greater than the second Message object. + * @returns True if the second Message object is less than the first Message + * object, false otherwise. + */ +LOOT_API bool operator>(const Message& lhs, const Message& rhs); + +/** + * Check if the first Message object is less than or equal to the second + * Message object. + * @returns True if the first Message object is not greater than the second + * Message object, false otherwise. + */ +LOOT_API bool operator<=(const Message& lhs, const Message& rhs); + +/** + * Check if the first Message object is greater than or equal to the second + * Message object. + * @returns True if the first Message object is not less than the second + * Message object, false otherwise. + */ +LOOT_API bool operator>=(const Message& lhs, const Message& rhs); +} + +#endif diff --git a/cxx/include/loot/metadata/message_content.h b/cxx/include/loot/metadata/message_content.h new file mode 100644 index 00000000..9a3b4c07 --- /dev/null +++ b/cxx/include/loot/metadata/message_content.h @@ -0,0 +1,150 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_METADATA_MESSAGE_CONTENT +#define LOOT_METADATA_MESSAGE_CONTENT + +#include +#include +#include + +#include "loot/api_decorator.h" + +namespace loot { +/** + * Represents a message's localised text content. + */ +class MessageContent { +public: + /** + * The code for the default language assumed for message content, which is + * "en" (English). + */ + static constexpr const char* DEFAULT_LANGUAGE = "en"; + + /** + * Construct a MessageContent object with an empty English message string. + * @return A MessageContent object. + */ + LOOT_API MessageContent() = default; + + /** + * Construct a Message object with the given text in the given language. + * @param text + * The message text. + * @param language + * The language that the message is written in. + * @return A MessageContent object. + */ + LOOT_API explicit MessageContent( + const std::string& text, + const std::string& language = DEFAULT_LANGUAGE); + + /** + * Get the message text. + * @return A string containing the message text. + */ + LOOT_API std::string GetText() const; + + /** + * Get the message language. + * @return A code representing the language that the message is written in. + */ + LOOT_API std::string GetLanguage() const; + +private: + std::string text_; + std::string language_{DEFAULT_LANGUAGE}; +}; + +/** + * Check if two MessageContent objects are equal by comparing their fields. + * @returns True if the objects' fields are equal, false otherwise. + */ +LOOT_API bool operator==(const MessageContent& lhs, const MessageContent& rhs); + +/** + * Check if two MessageContent objects are not equal. + * @returns True if the MessageContent objects are not equal, false otherwise. + */ +LOOT_API bool operator!=(const MessageContent& lhs, const MessageContent& rhs); + +/** + * A less-than operator implemented with no semantics so that MessageContent + * objects can be stored in sets. + * @returns True if the first MessageContent is less than the second + * MessageContent, false otherwise. + */ +LOOT_API bool operator<(const MessageContent& lhs, const MessageContent& rhs); + +/** + * Check if the first MessageContent object is greater than the second + * MessageContent object. + * @returns True if the second MessageContent object is less than the first + * MessageContent object, false otherwise. + */ +LOOT_API bool operator>(const MessageContent& lhs, const MessageContent& rhs); + +/** + * Check if the first MessageContent object is less than or equal to the second + * MessageContent object. + * @returns True if the first MessageContent object is not greater than the + * second MessageContent object, false otherwise. + */ +LOOT_API bool operator<=(const MessageContent& lhs, const MessageContent& rhs); + +/** + * Check if the first MessageContent object is greater than or equal to the + * second MessageContent object. + * @returns True if the first MessageContent object is not less than the second + * MessageContent object, false otherwise. + */ +LOOT_API bool operator>=(const MessageContent& lhs, const MessageContent& rhs); + +/** + * Choose a MessageContent object from a vector given a language. + * @param content + * The MessageContent objects to choose between. + * @param language + * The locale or language code for the preferred language to select. + * Locale codes are of the form `[language code]_[country code]`. + * @return A MessageContent object. + * * If the vector only contains a single element, that element is + * returned. + * * If content with a language that exactly matches the given locale + * or language code is present, that content is returned. + * * If a locale code is given and there is no exact match but content + * for that locale's language is present, that content is returned. + * * If a language code is given and there is no exact match but + * content for a locale in that langauge is present, that content is + * returned. + * * If no locale or language code matches are found and content in + * the default language is present, that content is returned. + * * Otherwise, an empty optional is returned. + */ +LOOT_API std::optional SelectMessageContent( + const std::vector content, + const std::string& language); +} + +#endif diff --git a/cxx/include/loot/metadata/plugin_cleaning_data.h b/cxx/include/loot/metadata/plugin_cleaning_data.h new file mode 100644 index 00000000..8ed59662 --- /dev/null +++ b/cxx/include/loot/metadata/plugin_cleaning_data.h @@ -0,0 +1,188 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ + +#ifndef LOOT_METADATA_PLUGIN_CLEANING_DATA +#define LOOT_METADATA_PLUGIN_CLEANING_DATA + +#include +#include + +#include "loot/api_decorator.h" +#include "loot/metadata/message.h" + +namespace loot { +/** + * Represents data identifying the plugin under which it is stored as dirty or + * clean. + */ +class PluginCleaningData { +public: + /** + * Construct a PluginCleaningData object with zero CRC, ITM count, deleted + * reference count and deleted navmesh count values, an empty utility string + * and no detail. + * @return A PluginCleaningData object. + */ + LOOT_API PluginCleaningData() = default; + + /** + * Construct a PluginCleaningData object with the given CRC and utility, + * zero ITM count, deleted reference count and deleted navmesh count + * values and no detail. + * @param crc + * The CRC of a plugin. + * @param utility + * The utility that the plugin cleanliness was checked with. + * @return A PluginCleaningData object. + */ + LOOT_API explicit PluginCleaningData(uint32_t crc, + const std::string& utility); + + /** + * Construct a PluginCleaningData object with the given values. + * @param crc + * A clean or dirty plugin's CRC. + * @param utility + * The utility that the plugin cleanliness was checked with. + * @param detail + * A vector of localised information message strings about the plugin + * cleanliness. + * @param itm + * The number of Identical To Master records found in the plugin. + * @param ref + * The number of deleted references found in the plugin. + * @param nav + * The number of deleted navmeshes found in the plugin. + * @return A PluginCleaningData object. + */ + LOOT_API explicit PluginCleaningData( + uint32_t crc, + const std::string& utility, + const std::vector& detail, + unsigned int itm, + unsigned int ref, + unsigned int nav); + + /** + * Get the CRC that identifies the plugin that the cleaning data is for. + * @return A CRC-32 checksum. + */ + LOOT_API uint32_t GetCRC() const; + + /** + * Get the number of Identical To Master records in the plugin. + * @return The number of Identical To Master records in the plugin. + */ + LOOT_API unsigned int GetITMCount() const; + + /** + * Get the number of deleted references in the plugin. + * @return The number of deleted references in the plugin. + */ + LOOT_API unsigned int GetDeletedReferenceCount() const; + + /** + * Get the number of deleted navmeshes in the plugin. + * @return The number of deleted navmeshes in the plugin. + */ + LOOT_API unsigned int GetDeletedNavmeshCount() const; + + /** + * Get the name of the cleaning utility that was used to check the plugin. + * @return A cleaning utility name, possibly related information such as + * a version number and/or a CommonMark-formatted URL to the utility's + * download location. + */ + LOOT_API std::string GetCleaningUtility() const; + + /** + * Get any additional informative message content supplied with the cleaning + * data, eg. a link to a cleaning guide or information on wild edits or manual + * cleaning steps. + * @return A vector of localised MessageContent objects. + */ + LOOT_API std::vector GetDetail() const; + +private: + uint32_t crc_{0}; + unsigned int itm_{0}; + unsigned int ref_{0}; + unsigned int nav_{0}; + std::string utility_; + std::vector detail_; +}; + +/** + * Check if two PluginCleaningData objects are equal by comparing their + * fields. + * @returns True if the objects' fields are equal, false otherwise. + */ +LOOT_API bool operator==(const PluginCleaningData& lhs, + const PluginCleaningData& rhs); + +/** + * Check if two MessageContent objects are not equal. + * @returns True if the MessageContent objects are not equal, false otherwise. + */ +LOOT_API bool operator!=(const PluginCleaningData& lhs, + const PluginCleaningData& rhs); + +/** + * A less-than operator implemented with no semantics so that + * PluginCleaningData objects can be stored in sets. + * @returns True if the first PluginCleaningData is less than the second + * PluginCleaningData, false otherwise. + */ +LOOT_API bool operator<(const PluginCleaningData& lhs, + const PluginCleaningData& rhs); + +/** + * Check if the first PluginCleaningData object is greater than the second + * PluginCleaningData object. + * @returns True if the second PluginCleaningData object is less than the first + * PluginCleaningData object, false otherwise. + */ +LOOT_API bool operator>(const PluginCleaningData& lhs, + const PluginCleaningData& rhs); + +/** + * Check if the first PluginCleaningData object is less than or equal to the + * second PluginCleaningData object. + * @returns True if the first PluginCleaningData object is not greater than the + * second PluginCleaningData object, false otherwise. + */ +LOOT_API bool operator<=(const PluginCleaningData& lhs, + const PluginCleaningData& rhs); + +/** + * Check if the first PluginCleaningData object is greater than or equal to the + * second PluginCleaningData object. + * @returns True if the first PluginCleaningData object is not less than the + * second PluginCleaningData object, false otherwise. + */ +LOOT_API bool operator>=(const PluginCleaningData& lhs, + const PluginCleaningData& rhs); +} + +#endif diff --git a/cxx/include/loot/metadata/plugin_metadata.h b/cxx/include/loot/metadata/plugin_metadata.h new file mode 100644 index 00000000..da821a90 --- /dev/null +++ b/cxx/include/loot/metadata/plugin_metadata.h @@ -0,0 +1,254 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_METADATA_PLUGIN_METADATA +#define LOOT_METADATA_PLUGIN_METADATA + +#include +#include +#include +#include +#include +#include +#include + +#include "loot/api_decorator.h" +#include "loot/metadata/file.h" +#include "loot/metadata/location.h" +#include "loot/metadata/message.h" +#include "loot/metadata/plugin_cleaning_data.h" +#include "loot/metadata/tag.h" + +namespace loot { +/** + * Represents a plugin's metadata. + */ +class PluginMetadata { +public: + /** + * Construct a PluginMetadata object with a blank plugin name and no metadata. + * @return A PluginMetadata object. + */ + LOOT_API PluginMetadata() = default; + + /** + * Construct a PluginMetadata object with no metadata for a plugin with the + * given filename. + * @param name + * The filename of the plugin that the object is constructed for. + * @return A PluginMetadata object. + */ + LOOT_API explicit PluginMetadata(const std::string& name); + + /** + * Merge metadata from the given PluginMetadata object into this object. + * + * If an equal metadata object already exists in this PluginMetadata object, + * it is not duplicated. This object's group is replaced by the given object's + * group if the latter is explicit. + * @param plugin + * The plugin metadata to merge. + */ + LOOT_API void MergeMetadata(const PluginMetadata& plugin); + + /** + * Get the plugin name. + * @return The plugin name. + */ + LOOT_API std::string GetName() const; + + /** + * Get the plugin's group. + * @return An optional containing the name of the group this plugin belongs to + * if it was explicitly set, otherwise an optional containing no + * value. + */ + LOOT_API std::optional GetGroup() const; + + /** + * Get the plugins that the plugin must load after. + * @return The plugins that the plugin must load after. + */ + LOOT_API std::vector GetLoadAfterFiles() const; + + /** + * Get the files that the plugin requires to be installed. + * @return The files that the plugin requires to be installed. + */ + LOOT_API std::vector GetRequirements() const; + + /** + * Get the files that the plugin is incompatible with. + * @return The files that the plugin is incompatible with. + */ + LOOT_API std::vector GetIncompatibilities() const; + + /** + * Get the plugin's messages. + * @return The plugin's messages. + */ + LOOT_API std::vector GetMessages() const; + + /** + * Get the plugin's Bash Tag suggestions. + * @return The plugin's Bash Tag suggestions. + */ + LOOT_API std::vector GetTags() const; + + /** + * Get the plugin's dirty plugin information. + * @return The PluginCleaningData objects that identify the plugin as dirty. + */ + LOOT_API std::vector GetDirtyInfo() const; + + /** + * Get the plugin's clean plugin information. + * @return The PluginCleaningData objects that identify the plugin as clean. + */ + LOOT_API std::vector GetCleanInfo() const; + + /** + * Get the locations at which this plugin can be found. + * @return The locations at which this plugin can be found. + */ + LOOT_API std::vector GetLocations() const; + + /** + * Set the plugin's group. + * @param group + * The name of the group this plugin belongs to. + */ + LOOT_API void SetGroup(const std::string& group); + + /** + * Unsets the plugin's group. + */ + LOOT_API void UnsetGroup(); + + /** + * Set the files that the plugin must load after. + * @param after + * The files to set. + */ + LOOT_API void SetLoadAfterFiles(const std::vector& after); + + /** + * Set the files that the plugin requires to be installed. + * @param requirements + * The files to set. + */ + LOOT_API void SetRequirements(const std::vector& requirements); + + /** + * Set the files that the plugin must load after. + * @param incompatibilities + * The files to set. + */ + LOOT_API void SetIncompatibilities( + const std::vector& incompatibilities); + + /** + * Set the plugin's messages. + * @param messages + * The messages to set. + */ + LOOT_API void SetMessages(const std::vector& messages); + + /** + * Set the plugin's Bash Tag suggestions. + * @param tags + * The Bash Tag suggestions to set. + */ + LOOT_API void SetTags(const std::vector& tags); + + /** + * Set the plugin's dirty information. + * @param info + * The dirty information to set. + */ + LOOT_API void SetDirtyInfo(const std::vector& info); + + /** + * Set the plugin's clean information. + * @param info + * The clean information to set. + */ + LOOT_API void SetCleanInfo(const std::vector& info); + + /** + * Set the plugin's locations. + * @param locations + * The locations to set. + */ + LOOT_API void SetLocations(const std::vector& locations); + + /** + * Check if no plugin metadata is set. + * @return True if the group is implicit and the metadata containers are all + * empty, false otherwise. + */ + LOOT_API bool HasNameOnly() const; + + /** + * Check if the plugin name is a regular expression. + * @return True if the plugin name contains any of the characters `:\*?|`, + * false otherwise. + */ + LOOT_API bool IsRegexPlugin() const; + + /** + * Check if the given plugin name matches this plugin metadata object's + * name field. + * + * If the name field is a regular expression, the given plugin name will be + * matched against it, otherwise the strings will be compared + * case-insensitively. The given plugin name must be literal, i.e. not a + * regular expression. + * @returns True if the given plugin name matches this metadata's plugin + * name, false otherwise. + */ + LOOT_API bool NameMatches(const std::string& pluginName) const; + + /** + * @brief Serialises the plugin metadata as YAML. + * @returns The serialised plugin metadata. + */ + LOOT_API std::string AsYaml() const; + +private: + std::string name_; + std::optional nameRegex_; + + std::optional group_; + std::vector loadAfter_; + std::vector requirements_; + std::vector incompatibilities_; + std::vector messages_; + std::vector tags_; + std::vector dirtyInfo_; + std::vector cleanInfo_; + std::vector locations_; +}; +} + +#endif diff --git a/cxx/include/loot/metadata/tag.h b/cxx/include/loot/metadata/tag.h new file mode 100644 index 00000000..1138b3cc --- /dev/null +++ b/cxx/include/loot/metadata/tag.h @@ -0,0 +1,120 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_METADATA_TAG +#define LOOT_METADATA_TAG + +#include + +#include "loot/api_decorator.h" +#include "loot/metadata/conditional_metadata.h" + +namespace loot { +/** + * Represents a Bash Tag suggestion for a plugin. + */ +class Tag : public ConditionalMetadata { +public: + /** + * Construct a Tag object with an empty tag name suggested for addition, with + * an empty condition string. + * @return A Tag object. + */ + LOOT_API explicit Tag() = default; + + /** + * Construct a Tag object with the given name, for addition or removal, with + * the given condition string. + * @param tag + * The name of the Bash Tag. + * @param isAddition + * True if the tag should be added, false if it should be removed. + * @param condition + * A condition string. + * @return A Tag object. + */ + LOOT_API explicit Tag(const std::string& tag, + const bool isAddition = true, + const std::string& condition = ""); + + /** + * Check if the tag should be added. + * @return True if the tag should be added, false if it should be removed. + */ + LOOT_API bool IsAddition() const; + + /** + * Get the tag's name. + * @return The tag's name. + */ + LOOT_API std::string GetName() const; + +private: + std::string name_; + bool addTag_{true}; +}; + +/** + * Check if two Tag objects are equal. + * @returns True if the objects' fields are equal, false otherwise. + */ +LOOT_API bool operator==(const Tag& lhs, const Tag& rhs); + +/** + * Check if two Tag objects are not equal. + * @returns True if the Tag objects are not equal, false otherwise. + */ +LOOT_API bool operator!=(const Tag& lhs, const Tag& rhs); + +/** + * A less-than operator implemented with no semantics so that Tag objects + * can be stored in sets. + * @returns True if the first Tag is less than the second Tag, false otherwise. + */ +LOOT_API bool operator<(const Tag& lhs, const Tag& rhs); + +/** + * Check if the first Tag object is greater than the second Tag object. + * @returns True if the second Tag object is less than the first Tag object, + * false otherwise. + */ +LOOT_API bool operator>(const Tag& lhs, const Tag& rhs); + +/** + * Check if the first Tag object is less than or equal to the second Tag + * object. + * @returns True if the first Tag object is not greater than the second Tag + * object, false otherwise. + */ +LOOT_API bool operator<=(const Tag& lhs, const Tag& rhs); + +/** + * Check if the first Tag object is greater than or equal to the second Tag + * object. + * @returns True if the first Tag object is not less than the second Tag + * object, false otherwise. + */ +LOOT_API bool operator>=(const Tag& lhs, const Tag& rhs); +} + +#endif diff --git a/cxx/include/loot/plugin_interface.h b/cxx/include/loot/plugin_interface.h new file mode 100644 index 00000000..4bec165d --- /dev/null +++ b/cxx/include/loot/plugin_interface.h @@ -0,0 +1,178 @@ +/* LOOT + + A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and + Fallout: New Vegas. + + Copyright (C) 2012-2016 WrinklyNinja + + This file is part of LOOT. + + LOOT is free software: you can redistribute + it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + LOOT is distributed in the hope that it will + be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LOOT. If not, see + . + */ +#ifndef LOOT_PLUGIN_INTERFACE +#define LOOT_PLUGIN_INTERFACE + +#include +#include +#include +#include +#include + +#include "loot/metadata/message.h" +#include "loot/metadata/tag.h" + +namespace loot { +/** + * Represents a plugin file that has been parsed by LOOT. + */ +class PluginInterface { +public: + virtual ~PluginInterface() = default; + + /** + * Get the plugin's filename. + * @return The plugin filename. If the plugin was ghosted when it was loaded, + * this filename will be without the .ghost suffix, unless the game is + * OpenMW, in which case ghosted plugins are not supported. + */ + virtual std::string GetName() const = 0; + + /** + * Get the value of the version field in the HEDR subrecord of the plugin's + * TES4 record. + * @return The value of the version field, or an empty optional if that value + * is NaN or could not be found. + */ + virtual std::optional GetHeaderVersion() const = 0; + + /** + * Get the plugin's version number from its description field. + * + * The description field may not contain a version number, or LOOT may be + * unable to detect it. The description field parsing may fail to extract the + * version number correctly, though it functions correctly in all known cases. + * @return An optional containing a version string if one is found, otherwise + * an optional containing no value. + */ + virtual std::optional GetVersion() const = 0; + + /** + * Get the plugin's masters. + * @return The plugin's masters in the same order they are listed in the file. + */ + virtual std::vector GetMasters() const = 0; + + /** + * Get any Bash Tags found in the plugin's description field. + * @return A set of Bash Tags. The order of elements in the set holds no + * semantics. + */ + virtual std::vector GetBashTags() const = 0; + + /** + * Get the plugin's CRC-32 checksum. + * @return An optional containing the plugin's CRC-32 checksum if the plugin + * has been fully loaded, otherwise an optional containing no value. + */ + virtual std::optional GetCRC() const = 0; + + /** + * Check if the plugin is a master plugin. + * + * What causes a plugin to be a master plugin varies by game, but is usually + * indicated by the plugin having its master flag set and/or by its file + * extension. However, OpenMW uses neither for determining plugins' load order + * so all OpenMW plugins are treated as non-masters. + * + * The term "master" is potentially confusing: a plugin A may not be a *master + * plugin*, but may still be a *master of* another plugin by being listed as + * such in that plugin's header record. Master plugins are sometimes referred + * to as *master files* or simply *masters*, while the other meaning is always + * referenced in relation to another plugin. + * @return True if the plugin is a master plugin, false otherwise. + */ + virtual bool IsMaster() const = 0; + + /** + * Check if the plugin is a light plugin. + * @return True if plugin is a light plugin, false otherwise. + */ + virtual bool IsLightPlugin() const = 0; + + /** + * Check if the plugin is a medium plugin. + * @return True if plugin is a medium plugin, false otherwise. + */ + virtual bool IsMediumPlugin() const = 0; + + /** + * Check if the plugin is an update plugin. + * @return True if plugin is an update plugin, false otherwise. + */ + virtual bool IsUpdatePlugin() const = 0; + + /** + * Check if the plugin is a blueprint plugin. + * @return True if plugin is a blueprint plugin, false otherwise. + */ + virtual bool IsBlueprintPlugin() const = 0; + + /** + * Check if the plugin is or would be valid as a light plugin. + * @return True if the plugin is a valid light plugin or would be a valid + * light plugin, false otherwise. + */ + virtual bool IsValidAsLightPlugin() const = 0; + + /** + * Check if the plugin is or would be valid as a medium plugin. + * @return True if the plugin is a valid medium plugin or would be a valid + * medium plugin, false otherwise. + */ + virtual bool IsValidAsMediumPlugin() const = 0; + + /** + * Check if the plugin is or would be valid as an update plugin. + * @return True if the plugin is a valid update plugin or would be a valid + * update plugin, false otherwise. + */ + virtual bool IsValidAsUpdatePlugin() const = 0; + + /** + * Check if the plugin contains any records other than its TES4 header. + * @return True if the plugin only contains a TES4 header, false otherwise. + */ + virtual bool IsEmpty() const = 0; + + /** + * Check if the plugin loads an archive (BSA/BA2 depending on the game). + * @return True if the plugin loads an archive, false otherwise. + */ + virtual bool LoadsArchive() const = 0; + + /** + * Check if two plugins contain a record with the same ID. + * @param plugin + * The other plugin to check for overlap with. + * @return True if the plugins both contain at least one record with the same + * ID, false otherwise. FormIDs are compared for all games apart from + * Morrowind, which doesn't have FormIDs and so has other identifying + * data compared. + */ + virtual bool DoRecordsOverlap(const PluginInterface& plugin) const = 0; +}; +} + +#endif diff --git a/cxx/include/loot/vertex.h b/cxx/include/loot/vertex.h new file mode 100644 index 00000000..861d652c --- /dev/null +++ b/cxx/include/loot/vertex.h @@ -0,0 +1,74 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2014-2016 WrinklyNinja + +This file is part of LOOT. + +LOOT is free software: you can redistribute +it and/or modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +LOOT is distributed in the hope that it will +be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LOOT. If not, see +. +*/ + +#ifndef LOOT_VERTEX +#define LOOT_VERTEX + +#include +#include + +#include "loot/api_decorator.h" +#include "loot/enum/edge_type.h" + +namespace loot { +/** + * @brief A class representing a plugin or group vertex in a path, and the + type of the edge to the next vertex in the path if one exists. + */ +class Vertex { +public: + /** + * @brief Construct a Vertex with the given name and no out edge. + * @param name The name of the plugin or group that this vertex represents. + */ + LOOT_API explicit Vertex(std::string name); + + /** + * @brief Construct a Vertex with the given name and out edge type. + * @param name The name of the plugin or group that this vertex represents. + * @param outEdgeType The type of the edge going out from this vertex. + */ + LOOT_API explicit Vertex(std::string name, EdgeType outEdgeType); + + /** + * @brief Get the name of the plugin or group. + * @return The name of the plugin or group. + */ + LOOT_API std::string GetName() const; + + /** + * @brief Get the type of the edge going to the next vertex. + * @details Each edge goes from the vertex that loads earlier to the vertex + * that loads later. + * @return The edge type. + */ + LOOT_API std::optional GetTypeOfEdgeToNextVertex() const; + +private: + std::string name_; + std::optional outEdgeType_; +}; +} + +#endif