From 6585d629ca60e2ce457750f12d40dd9cf742ff8c Mon Sep 17 00:00:00 2001 From: Rémy Raes Date: Fri, 22 Nov 2024 15:18:38 +0100 Subject: mods(MAD): Make MAD process cancellable (#815) Adds logic to make an active mod download via MAD cancellable. --- primedev/mods/autodownload/moddownloader.cpp | 35 +++++++++++++++++++++++++--- primedev/mods/autodownload/moddownloader.h | 1 + 2 files changed, 33 insertions(+), 3 deletions(-) (limited to 'primedev/mods') diff --git a/primedev/mods/autodownload/moddownloader.cpp b/primedev/mods/autodownload/moddownloader.cpp index c20a3adb..21b98942 100644 --- a/primedev/mods/autodownload/moddownloader.cpp +++ b/primedev/mods/autodownload/moddownloader.cpp @@ -156,6 +156,14 @@ int ModDownloader::ModFetchingProgressCallback( { NOTE_UNUSED(totalToUpload); NOTE_UNUSED(nowUploaded); + + // Abort download + ModDownloader* instance = static_cast(ptr); + if (instance->modState.state == ABORTED) + { + return 1; + } + if (totalDownloadSize != 0 && finishedDownloadSize != 0) { ModDownloader* instance = static_cast(ptr); @@ -563,6 +571,13 @@ void ModDownloader::ExtractMod(fs::path modPath, VerifiedModPlatform platform) } } + // Abort mod extraction if needed + if (modState.state == ABORTED) + { + spdlog::info("User cancelled mod installation, aborting mod extraction."); + return; + } + // Go to next file if ((i + 1) < gi.number_entry) { @@ -602,8 +617,7 @@ void ModDownloader::DownloadMod(std::string modName, std::string modVersion) spdlog::error("Error while removing downloaded archive: {}", a.what()); } - modState.state = DONE; - spdlog::info("Done downloading {}.", modName); + spdlog::info("Done cleaning after downloading {}.", modName); }); // Download mod archive @@ -613,7 +627,10 @@ void ModDownloader::DownloadMod(std::string modName, std::string modVersion) if (!fetchingResult.has_value()) { spdlog::error("Something went wrong while fetching archive, aborting."); - modState.state = MOD_FETCHING_FAILED; + if (modState.state != ABORTED) + { + modState.state = MOD_FETCHING_FAILED; + } return; } archiveLocation = fetchingResult.value(); @@ -626,11 +643,17 @@ void ModDownloader::DownloadMod(std::string modName, std::string modVersion) // Extract downloaded mod archive ExtractMod(archiveLocation, fullVersion.platform); + modState.state = DONE; }); requestThread.detach(); } +void ModDownloader::CancelDownload() +{ + modState.state = ABORTED; +} + ON_DLL_LOAD_RELIESON("engine.dll", ModDownloader, (ConCommand), (CModule module)) { g_pModDownloader = new ModDownloader(); @@ -687,3 +710,9 @@ ADD_SQFUNC("ModInstallState", NSGetModInstallState, "", "", ScriptContext::SERVE return SQRESULT_NOTNULL; } + +ADD_SQFUNC("void", NSCancelModDownload, "", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) +{ + g_pModDownloader->CancelDownload(); + return SQRESULT_NULL; +} diff --git a/primedev/mods/autodownload/moddownloader.h b/primedev/mods/autodownload/moddownloader.h index c7a88c19..2ac72a48 100644 --- a/primedev/mods/autodownload/moddownloader.h +++ b/primedev/mods/autodownload/moddownloader.h @@ -129,6 +129,7 @@ public: CHECKSUMING, EXTRACTING, DONE, // Everything went great, mod can be used in-game + ABORTED, // User cancelled mod install process // Errors FAILED, // Generic error message, should be avoided as much as possible -- cgit v1.2.3