mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-06-29 01:54:20 +03:00
added auto updating mods on launch functionality
Signed-off-by: dyredhead <danielyentin@gmail.com>
This commit is contained in:
parent
b8d996530c
commit
f0d4bba7eb
4 changed files with 162 additions and 0 deletions
|
|
@ -255,6 +255,8 @@ set(MINECRAFT_SOURCES
|
|||
minecraft/update/FoldersTask.h
|
||||
minecraft/update/LibrariesTask.cpp
|
||||
minecraft/update/LibrariesTask.h
|
||||
minecraft/update/ModUpdateTask.cpp
|
||||
minecraft/update/ModUpdateTask.h
|
||||
|
||||
minecraft/launch/ClaimAccount.cpp
|
||||
minecraft/launch/ClaimAccount.h
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
#include "minecraft/update/FoldersTask.h"
|
||||
#include "minecraft/update/LegacyFMLLibrariesTask.h"
|
||||
#include "minecraft/update/LibrariesTask.h"
|
||||
#include "minecraft/update/ModUpdateTask.h"
|
||||
|
||||
#include "java/JavaUtils.h"
|
||||
|
||||
|
|
@ -1208,6 +1209,13 @@ LaunchTask* MinecraftInstance::createLaunchTask(AuthSessionPtr session, Minecraf
|
|||
process->appendStep(makeShared<ScanModFolders>(pptr));
|
||||
}
|
||||
|
||||
// Update mods if "AutomaticallyUpdateMods" is true.
|
||||
// Must come after ScanModFolders to ensure mods are loaded.
|
||||
if (settings()->get("AutomaticallyUpdateMods").toBool()) {
|
||||
process->appendStep(
|
||||
makeShared<TaskStepWrapper>(pptr, makeShared<ModUpdateTask>(this, settings()->get("AutomaticallyUpdateModsEnabled").toBool())));
|
||||
}
|
||||
|
||||
// make sure we have enough RAM, warn the user if we don't
|
||||
{
|
||||
process->appendStep(makeShared<EnsureAvailableMemory>(pptr, this));
|
||||
|
|
|
|||
125
launcher/minecraft/update/ModUpdateTask.cpp
Normal file
125
launcher/minecraft/update/ModUpdateTask.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#include "ModUpdateTask.h"
|
||||
|
||||
#include <ui/dialogs/ProgressDialog.h>
|
||||
#include <ui/dialogs/ResourceUpdateDialog.h>
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
#include "launch/LaunchStep.h"
|
||||
#include "minecraft/AssetsUtils.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/PackProfile.h"
|
||||
#include "minecraft/mod/Mod.h"
|
||||
#include "minecraft/mod/ModDetails.h"
|
||||
#include "minecraft/mod/ModFolderModel.h"
|
||||
#include "net/ApiDownload.h"
|
||||
#include "net/ChecksumValidator.h"
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
|
||||
ModUpdateTask::ModUpdateTask(MinecraftInstance* inst, bool enabledModsOnly)
|
||||
{
|
||||
m_instance = inst;
|
||||
m_enabledModsOnly = enabledModsOnly;
|
||||
}
|
||||
|
||||
void ModUpdateTask::executeTask()
|
||||
{
|
||||
setStatus(tr("Updating mods..."));
|
||||
qDebug() << "Updating mods...";
|
||||
|
||||
if (m_instance->typeName() != "Minecraft") {
|
||||
return; // this is a null instance or a legacy instance
|
||||
}
|
||||
|
||||
auto* profile = static_cast<MinecraftInstance*>(m_instance)->getPackProfile();
|
||||
if (!profile->getModLoaders().has_value()) {
|
||||
emitFailed(tr("Mod updates are unavailable when mod loader is missing!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) {
|
||||
emitFailed(tr("Mod updates are unavailable when metadata is disabled!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// ResourceUpdateDialog only accepts Resource,
|
||||
// so we convert the Mod* list to a Resource* list with a simple static_cast
|
||||
auto model = m_instance->loaderModList();
|
||||
auto _modsList = model->allMods();
|
||||
QList<Resource*> modsList;
|
||||
modsList.reserve(_modsList.size());
|
||||
for (auto mod : _modsList) {
|
||||
modsList.append(static_cast<Resource*>(mod));
|
||||
}
|
||||
|
||||
// Filter out disabled mods if "AutomaticallyUpdateModsEnabled" is true
|
||||
if (m_enabledModsOnly) {
|
||||
modsList.erase(std::remove_if(modsList.begin(), modsList.end(), [](Resource* resource) { return !resource->enabled(); }),
|
||||
modsList.end());
|
||||
}
|
||||
|
||||
// Spawn ResourceUpdateDialog to handle mod updates
|
||||
// 99% copied from ModFolderPage.cpp
|
||||
auto parent = QApplication::activeWindow();
|
||||
ResourceUpdateDialog updateDialog =
|
||||
ResourceUpdateDialog(parent, m_instance, model, modsList, m_includeDeps, profile->getModLoadersList());
|
||||
updateDialog.checkCandidates();
|
||||
|
||||
if (updateDialog.aborted()) {
|
||||
CustomMessageBox::selectable(parent, tr("Aborted"), tr("The mod updater was aborted!"), QMessageBox::Warning)->show();
|
||||
emitAborted();
|
||||
return;
|
||||
}
|
||||
if (updateDialog.noUpdates()) {
|
||||
QString message{ tr("'%1' is up-to-date! :)").arg(modsList.front()->name()) };
|
||||
if (modsList.size() > 1) {
|
||||
if (!m_enabledModsOnly) {
|
||||
message = tr("All mods are up-to-date! :)");
|
||||
} else {
|
||||
message = tr("All enabled mods are up-to-date! :)");
|
||||
}
|
||||
}
|
||||
CustomMessageBox::selectable(parent, tr("Update checker"), message)->exec();
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateDialog.exec() != 0) {
|
||||
auto* tasks = new ConcurrentTask("Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||
connect(tasks, &Task::failed, [this, parent, tasks](const QString& reason) {
|
||||
CustomMessageBox::selectable(parent, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||
tasks->deleteLater();
|
||||
});
|
||||
connect(tasks, &Task::aborted, [this, parent, tasks]() {
|
||||
CustomMessageBox::selectable(parent, tr("Aborted"), tr("Download stopped by user."), QMessageBox::Information)->show();
|
||||
tasks->deleteLater();
|
||||
});
|
||||
connect(tasks, &Task::succeeded, [this, parent, tasks]() {
|
||||
QStringList warnings = tasks->warnings();
|
||||
if (warnings.count()) {
|
||||
CustomMessageBox::selectable(parent, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
|
||||
}
|
||||
tasks->deleteLater();
|
||||
});
|
||||
|
||||
for (const auto& task : updateDialog.getTasks()) {
|
||||
tasks->addTask(task);
|
||||
}
|
||||
|
||||
ProgressDialog loadDialog(parent);
|
||||
loadDialog.setSkipButton(true, tr("Abort"));
|
||||
loadDialog.execWithTask(tasks);
|
||||
}
|
||||
model->update();
|
||||
qDebug() << "Finished updating mods...";
|
||||
emitSucceeded();
|
||||
}
|
||||
|
||||
bool ModUpdateTask::canAbort() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModUpdateTask::abort()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
27
launcher/minecraft/update/ModUpdateTask.h
Normal file
27
launcher/minecraft/update/ModUpdateTask.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
#include "net/NetJob.h"
|
||||
#include "tasks/Task.h"
|
||||
class MinecraftInstance;
|
||||
|
||||
class ModUpdateTask : public Task {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ModUpdateTask(MinecraftInstance* inst, bool enabled);
|
||||
virtual ~ModUpdateTask() = default;
|
||||
|
||||
void executeTask() override;
|
||||
|
||||
bool canAbort() const override;
|
||||
|
||||
public:
|
||||
static QString resourceUrl();
|
||||
|
||||
public slots:
|
||||
bool abort() override;
|
||||
|
||||
private:
|
||||
MinecraftInstance* m_instance;
|
||||
bool m_enabledModsOnly;
|
||||
bool m_includeDeps = true;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue