aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDLL/mods/autodownload/moddownloader.h
diff options
context:
space:
mode:
authorRémy Raes <contact@remyraes.com>2023-11-03 16:32:41 +0100
committerGitHub <noreply@github.com>2023-11-03 16:32:41 +0100
commit13f2facdb6b5a556f01e0d04aaa6bda5d2b29417 (patch)
treeb7375762976373291845c96ba539ece236b17033 /NorthstarDLL/mods/autodownload/moddownloader.h
parent6e32a584804158daec2f57cfe3fa058f1ce3d0a7 (diff)
downloadNorthstarLauncher-13f2facdb6b5a556f01e0d04aaa6bda5d2b29417.tar.gz
NorthstarLauncher-13f2facdb6b5a556f01e0d04aaa6bda5d2b29417.zip
Inital native code for verified mod auto-downloading (#545)
Allows client to download a mod archive from the Thunderstore API, and extract included mods in the remote mods folder of the current game profile. Not all mods can be automatically downloaded, as it would cause some security issues, and Thunderstore mod name cannot be deduced from actual mod name: to be eligible to auto-downloading, a mod must appear in the list of verified mods. Said list and complete mod verification procedure are described here: https://github.com/R2Northstar/VerifiedMods Exposes two commands to test the feature: - `fetch_verified_mods` retrieves verified mods list from the GitHub organization, and stores it locally; - `download_mod` does the actual mod downloading/extraction job.
Diffstat (limited to 'NorthstarDLL/mods/autodownload/moddownloader.h')
-rw-r--r--NorthstarDLL/mods/autodownload/moddownloader.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/NorthstarDLL/mods/autodownload/moddownloader.h b/NorthstarDLL/mods/autodownload/moddownloader.h
new file mode 100644
index 00000000..edaf090b
--- /dev/null
+++ b/NorthstarDLL/mods/autodownload/moddownloader.h
@@ -0,0 +1,141 @@
+class ModDownloader
+{
+ private:
+ const char* VERIFICATION_FLAG = "-disablemodverification";
+ const char* CUSTOM_MODS_URL_FLAG = "-customverifiedurl=";
+ const char* STORE_URL = "https://gcdn.thunderstore.io/live/repository/packages/";
+ const char* DEFAULT_MODS_LIST_URL = "https://raw.githubusercontent.com/R2Northstar/VerifiedMods/master/mods.json";
+ char* modsListUrl;
+
+ struct VerifiedModVersion
+ {
+ std::string checksum;
+ };
+ struct VerifiedModDetails
+ {
+ std::string dependencyPrefix;
+ std::unordered_map<std::string, VerifiedModVersion> versions = {};
+ };
+ std::unordered_map<std::string, VerifiedModDetails> verifiedMods = {};
+
+ /**
+ * Downloads a mod archive from distant store.
+ *
+ * This rebuilds the URI of the mod archive using both a predefined store URI
+ * and the mod dependency string from the `verifiedMods` variable, or using
+ * input mod name as mod dependency string if bypass flag is set up; fetched
+ * archive is then stored in a temporary location.
+ *
+ * If something went wrong during archive download, this will return an empty
+ * optional object.
+ *
+ * @param modName name of the mod to be downloaded
+ * @param modVersion version of the mod to be downloaded
+ * @returns location of the downloaded archive
+ */
+ std::optional<fs::path> FetchModFromDistantStore(std::string_view modName, std::string_view modVersion);
+
+ /**
+ * Checks whether a mod is verified.
+ *
+ * A mod is deemed verified/authorized through a manual validation process that is
+ * described here: https://github.com/R2Northstar/VerifiedMods; in practice, a mod
+ * is considered authorized if their name AND exact version appear in the
+ * `verifiedMods` variable.
+ *
+ * @param modName name of the mod to be checked
+ * @param modVersion version of the mod to be checked, must follow semantic versioning
+ * @returns whether the mod is authorized and can be auto-downloaded
+ */
+ bool IsModAuthorized(std::string_view modName, std::string_view modVersion);
+
+ /**
+ * Tells if a mod archive has not been corrupted.
+ *
+ * The mod validation procedure includes computing the SHA256 hash of the final
+ * archive, which is stored in the verified mods list. This hash is used by this
+ * very method to ensure the archive downloaded from the Internet is the exact
+ * same that has been manually verified.
+ *
+ * @param modPath path of the archive to check
+ * @param expectedChecksum checksum the archive should have
+ * @returns whether archive is legit
+ */
+ bool IsModLegit(fs::path modPath, std::string_view expectedChecksum);
+
+ /**
+ * Extracts a mod archive to the game folder.
+ *
+ * This extracts a downloaded mod archive from its original location to the
+ * current game profile, in the remote mods folder.
+ *
+ * @param modPath location of the downloaded archive
+ * @returns nothing
+ */
+ void ExtractMod(fs::path modPath);
+
+ public:
+ ModDownloader();
+
+ /**
+ * Retrieves the verified mods list from the central authority.
+ *
+ * The Northstar auto-downloading feature does NOT allow automatically installing
+ * all mods for various (notably security) reasons; mods that are candidate to
+ * auto-downloading are rather listed on a GitHub repository
+ * (https://raw.githubusercontent.com/R2Northstar/VerifiedMods/master/mods.json),
+ * which this method gets via a HTTP call to load into local state.
+ *
+ * If list fetching fails, local mods list will be initialized as empty, thus
+ * preventing any mod from being auto-downloaded.
+ *
+ * @returns nothing
+ */
+ void FetchModsListFromAPI();
+
+ /**
+ * Downloads a given mod from Thunderstore API to local game profile.
+ *
+ * @param modName name of the mod to be downloaded
+ * @param modVersion version of the mod to be downloaded
+ * @returns nothing
+ **/
+ void DownloadMod(std::string modName, std::string modVersion);
+
+ enum ModInstallState
+ {
+ // Normal installation process
+ DOWNLOADING,
+ CHECKSUMING,
+ EXTRACTING,
+ DONE, // Everything went great, mod can be used in-game
+
+ // Errors
+ FAILED, // Generic error message, should be avoided as much as possible
+ FAILED_READING_ARCHIVE,
+ FAILED_WRITING_TO_DISK,
+ MOD_FETCHING_FAILED,
+ MOD_CORRUPTED, // Downloaded archive checksum does not match verified hash
+ NO_DISK_SPACE_AVAILABLE,
+ NOT_FOUND // Mod is not currently being auto-downloaded
+ };
+
+ struct MOD_STATE
+ {
+ ModInstallState state;
+ int progress;
+ int total;
+ float ratio;
+ } modState = {};
+
+ /**
+ * Cancels installation of the mod.
+ *
+ * Prevents installation of the mod currently being installed, no matter the install
+ * progress (downloading, checksuming, extracting), and frees all resources currently
+ * being used in this purpose.
+ *
+ * @returns nothing
+ */
+ void CancelDownload();
+};