diff --git a/loader/src/server/DownloadManager.cpp b/loader/src/server/DownloadManager.cpp index 187262a9..9cd8ff5b 100644 --- a/loader/src/server/DownloadManager.cpp +++ b/loader/src/server/DownloadManager.cpp @@ -101,7 +101,7 @@ public: .percentage = 0, }; - m_downloadListener.bind([this, hash = version.hash](web::WebTask::Event* event) { + m_downloadListener.bind([this, hash = version.hash, version = version](web::WebTask::Event* event) { if (auto value = event->getValue()) { if (value->ok()) { if (auto actualHash = ::calculateHash(value->data()); actualHash != hash) { @@ -134,7 +134,9 @@ public: }; } else { - m_status = DownloadStatusDone(); + m_status = DownloadStatusDone { + .version = version + }; } } } @@ -319,6 +321,11 @@ bool ModDownloadManager::checkAutoConfirm() { if (inc.mod && (!download.getVersion().has_value() || inc.version.compare(download.getVersion().value()))) { return false; } + for (auto download : ModDownloadManager::get()->getDownloads()) { + if (download.isDone() && inc.id == download.getID() && (!download.getVersion().has_value() || inc.version.compare(download.getVersion().value()))) { + return false; + } + } } // If some installed mod is incompatible with this one, // we need to ask for confirmation @@ -329,6 +336,19 @@ bool ModDownloadManager::checkAutoConfirm() { } } } + + // If some newly downloaded mods are incompatible with this one, + // we need to ask for confirmation + for (auto download : ModDownloadManager::get()->getDownloads()) { + auto status = download.getStatus(); + if (auto done = std::get_if(&status)) { + for (auto inc : done->version.metadata.getIncompatibilities()) { + if (inc.id == download.getID() && inc.version.compare(done->version.metadata.getVersion())) { + return false; + } + } + } + } } // If there are mods we aren't sure about yet, we can't auto-confirm else if (std::holds_alternative(status)) { diff --git a/loader/src/server/DownloadManager.hpp b/loader/src/server/DownloadManager.hpp index 569564b9..a6df29d7 100644 --- a/loader/src/server/DownloadManager.hpp +++ b/loader/src/server/DownloadManager.hpp @@ -16,6 +16,7 @@ namespace server { bool operator==(DownloadStatusDownloading const&) const = default; }; struct DownloadStatusDone { + ServerModVersion version; bool operator==(DownloadStatusDone const&) const = default; }; struct DownloadStatusError { diff --git a/loader/src/ui/mods/popups/ConfirmInstall.cpp b/loader/src/ui/mods/popups/ConfirmInstall.cpp index 5fe2b71d..70f59a2b 100644 --- a/loader/src/ui/mods/popups/ConfirmInstall.cpp +++ b/loader/src/ui/mods/popups/ConfirmInstall.cpp @@ -12,6 +12,7 @@ void askConfirmModInstalls() { size_t replacementCount = 0; size_t dependencyCount = 0; std::unordered_set toDisable; + std::unordered_set toDisableModId; std::unordered_set toEnable; }; @@ -39,6 +40,11 @@ void askConfirmModInstalls() { if (inc.mod && inc.version.compare(conf->version.metadata.getVersion()) && inc.mod->isOrWillBeEnabled()) { toConfirm.toDisable.insert(inc.mod); } + for (auto download : ModDownloadManager::get()->getDownloads()) { + if (download.isDone() && inc.id == download.getID() && inc.version.compare(conf->version.metadata.getVersion())) { + toConfirm.toDisableModId.insert(inc.id); + } + } } // If some installed mods are incompatible with this one, disable them for (auto mod : Loader::get()->getAllMods()) { @@ -48,6 +54,17 @@ void askConfirmModInstalls() { } } } + // If some newly downloaded mods are incompatible with this one, disable them + for (auto download : ModDownloadManager::get()->getDownloads()) { + auto status = download.getStatus(); + if (auto done = std::get_if(&status)) { + for (auto inc : done->version.metadata.getIncompatibilities()) { + if (inc.id == conf->version.metadata.getID() && inc.version.compare(done->version.metadata.getVersion())) { + toConfirm.toDisableModId.insert(download.getID()); + } + } + } + } // If this mod has required dependencies that are disabled, enable them for (auto dep : conf->version.metadata.getDependencies()) { @@ -71,6 +88,20 @@ void askConfirmModInstalls() { ); }; + auto joinIdsToIDs = [](std::unordered_set const& ids) { + return ranges::join( + ranges::map>( + ids, [](std::string const& id) { return fmt::format("{}", id); } + ), + ", " + ); + }; + + std::unordered_set idsToDisable = toConfirm.toDisableModId; + for (auto mod : toConfirm.toDisable) { + idsToDisable.insert(mod->getID()); + } + createQuickPopup( "Confirm Install", fmt::format( @@ -78,7 +109,7 @@ void askConfirmModInstalls() { "{} mods will be force-disabled, as they are incompatible: {}\n" "{} mods will be force-enabled: {}", toConfirm.modCount, toConfirm.dependencyCount, toConfirm.replacementCount, - toConfirm.toDisable.size(), joinModsToIDs(toConfirm.toDisable), + idsToDisable.size(), joinIdsToIDs(idsToDisable), toConfirm.toEnable.size(), joinModsToIDs(toConfirm.toEnable) ), "Cancel", "Continue", @@ -87,6 +118,9 @@ void askConfirmModInstalls() { for (auto mod : toConfirm.toDisable) { (void)mod->disable(); } + for (auto modId : toConfirm.toDisableModId) { + Mod::get()->setSavedValue("should-load-" + modId, false); + } for (auto mod : toConfirm.toEnable) { (void)mod->enable(); }