From 2b998bb8cc8e83efafb20ed2fbe1a245d4d5ec5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 26 Sep 2017 13:38:34 +0200 Subject: NOISSUE implement LEgacy instance migration --- api/logic/minecraft/legacy/LegacyMigrationTask.cpp | 51 -------- api/logic/minecraft/legacy/LegacyMigrationTask.h | 37 ------ api/logic/minecraft/legacy/LegacyUpgradeTask.cpp | 133 +++++++++++++++++++++ api/logic/minecraft/legacy/LegacyUpgradeTask.h | 38 ++++++ 4 files changed, 171 insertions(+), 88 deletions(-) delete mode 100644 api/logic/minecraft/legacy/LegacyMigrationTask.cpp delete mode 100644 api/logic/minecraft/legacy/LegacyMigrationTask.h create mode 100644 api/logic/minecraft/legacy/LegacyUpgradeTask.cpp create mode 100644 api/logic/minecraft/legacy/LegacyUpgradeTask.h (limited to 'api/logic/minecraft/legacy') diff --git a/api/logic/minecraft/legacy/LegacyMigrationTask.cpp b/api/logic/minecraft/legacy/LegacyMigrationTask.cpp deleted file mode 100644 index 0d3cef35..00000000 --- a/api/logic/minecraft/legacy/LegacyMigrationTask.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "LegacyMigrationTask.h" -#include "BaseInstanceProvider.h" -#include "settings/INISettingsObject.h" -#include "FileSystem.h" -#include "NullInstance.h" -#include "pathmatcher/RegexpMatcher.h" -#include - -LegacyMigrationTask::LegacyMigrationTask(SettingsObjectPtr settings, const QString & stagingPath, InstancePtr origInstance) -{ - m_globalSettings = settings; - m_stagingPath = stagingPath; - m_origInstance = origInstance; -} - -void LegacyMigrationTask::executeTask() -{ - setStatus(tr("Copying instance %1").arg(m_origInstance->name())); - - FS::copy folderCopy(m_origInstance->instanceRoot(), m_stagingPath); - folderCopy.followSymlinks(true); - - m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), folderCopy); - connect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &LegacyMigrationTask::copyFinished); - connect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &LegacyMigrationTask::copyAborted); - m_copyFutureWatcher.setFuture(m_copyFuture); -} - -void LegacyMigrationTask::copyFinished() -{ - auto successful = m_copyFuture.result(); - if(!successful) - { - emitFailed(tr("Instance folder copy failed.")); - return; - } - // FIXME: shouldn't this be able to report errors? - auto instanceSettings = std::make_shared(FS::PathCombine(m_stagingPath, "instance.cfg")); - instanceSettings->registerSetting("InstanceType", "Legacy"); - - InstancePtr inst(new NullInstance(m_globalSettings, instanceSettings, m_stagingPath)); - inst->setName(tr("%1 (Migrated)").arg(m_origInstance->name())); - emitSucceeded(); -} - -void LegacyMigrationTask::copyAborted() -{ - emitFailed(tr("Instance folder copy has been aborted.")); - return; -} - diff --git a/api/logic/minecraft/legacy/LegacyMigrationTask.h b/api/logic/minecraft/legacy/LegacyMigrationTask.h deleted file mode 100644 index 36cfa240..00000000 --- a/api/logic/minecraft/legacy/LegacyMigrationTask.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "tasks/Task.h" -#include "multimc_logic_export.h" -#include "net/NetJob.h" -#include -#include -#include -#include "settings/SettingsObject.h" -#include "BaseVersion.h" -#include "BaseInstance.h" - - -class BaseInstanceProvider; - -class MULTIMC_LOGIC_EXPORT LegacyMigrationTask : public Task -{ - Q_OBJECT -public: - explicit LegacyMigrationTask(SettingsObjectPtr settings, const QString & stagingPath, InstancePtr origInstance); - -protected: - //! Entry point for tasks. - virtual void executeTask() override; - void copyFinished(); - void copyAborted(); - -private: /* data */ - SettingsObjectPtr m_globalSettings; - InstancePtr m_origInstance; - QString m_stagingPath; - QFuture m_copyFuture; - QFutureWatcher m_copyFutureWatcher; -}; - - - diff --git a/api/logic/minecraft/legacy/LegacyUpgradeTask.cpp b/api/logic/minecraft/legacy/LegacyUpgradeTask.cpp new file mode 100644 index 00000000..cb0572ed --- /dev/null +++ b/api/logic/minecraft/legacy/LegacyUpgradeTask.cpp @@ -0,0 +1,133 @@ +#include "LegacyUpgradeTask.h" +#include "BaseInstanceProvider.h" +#include "settings/INISettingsObject.h" +#include "FileSystem.h" +#include "NullInstance.h" +#include "pathmatcher/RegexpMatcher.h" +#include +#include "LegacyInstance.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/MinecraftProfile.h" + +LegacyUpgradeTask::LegacyUpgradeTask(SettingsObjectPtr settings, const QString & stagingPath, InstancePtr origInstance, const QString & newName) +{ + m_globalSettings = settings; + m_stagingPath = stagingPath; + m_origInstance = origInstance; + m_newName = newName; +} + +void LegacyUpgradeTask::executeTask() +{ + setStatus(tr("Copying instance %1").arg(m_origInstance->name())); + + FS::copy folderCopy(m_origInstance->instanceRoot(), m_stagingPath); + folderCopy.followSymlinks(true); + + m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), folderCopy); + connect(&m_copyFutureWatcher, &QFutureWatcher::finished, this, &LegacyUpgradeTask::copyFinished); + connect(&m_copyFutureWatcher, &QFutureWatcher::canceled, this, &LegacyUpgradeTask::copyAborted); + m_copyFutureWatcher.setFuture(m_copyFuture); +} + +static QString decideVersion(const QString& currentVersion, const QString& intendedVersion) +{ + if(intendedVersion != currentVersion) + { + if(!intendedVersion.isEmpty()) + { + return intendedVersion; + } + else if(!currentVersion.isEmpty()) + { + return currentVersion; + } + } + else + { + if(!intendedVersion.isEmpty()) + { + return intendedVersion; + } + } + // TODO: possibly add fallback to the old jar/classfile analysis method from MultiMC4 + return QString(); +} + +void LegacyUpgradeTask::copyFinished() +{ + auto successful = m_copyFuture.result(); + if(!successful) + { + emitFailed(tr("Instance folder copy failed.")); + return; + } + auto legacyInst = std::dynamic_pointer_cast(m_origInstance); + + auto instanceSettings = std::make_shared(FS::PathCombine(m_stagingPath, "instance.cfg")); + instanceSettings->registerSetting("InstanceType", "Legacy"); + instanceSettings->set("InstanceType", "OneSix"); + std::shared_ptr inst(new MinecraftInstance(m_globalSettings, instanceSettings, m_stagingPath)); + inst->setName(m_newName); + inst->init(); + + QString preferredVersionNumber = decideVersion(legacyInst->currentVersionId(), legacyInst->intendedVersionId()); + if(preferredVersionNumber.isNull()) + { + // FIXME: let the user decide + emitFailed(tr("Could not decide Minecraft version.")); + return; + } + inst->setComponentVersion("net.minecraft", preferredVersionNumber); + + // BUG: reloadProfile should not be necessary, but setComponentVersion voids the profile created by init()! + inst->reloadProfile(); + auto profile = inst->getMinecraftProfile(); + + if(legacyInst->shouldUseCustomBaseJar()) + { + QString jarPath = legacyInst->customBaseJar(); + qDebug() << "Base jar is custom! : " << jarPath; + // FIXME: handle case when the jar is unreadable? + // TODO: check the hash, if it's the same as the upstream jar, do not do this + profile->installCustomJar(jarPath); + } + + auto jarMods = legacyInst->getJarMods(); + for(auto & jarMod: jarMods) + { + QString modPath = jarMod.filename().absoluteFilePath(); + qDebug() << "jarMod: " << modPath; + profile->installJarMods({modPath}); + } + + // remove all the extra garbage we no longer need + auto removeAll = [&](const QString &root, const QStringList &things) + { + for(auto &thing : things) + { + auto removePath = FS::PathCombine(root, thing); + QFileInfo stat(removePath); + if(stat.isDir()) + { + FS::deletePath(removePath); + } + else + { + QFile::remove(removePath); + } + } + }; + QStringList rootRemovables = {"modlist", "version", "instMods"}; + QStringList mcRemovables = {"bin", "MultiMCLauncher.jar", "icon.png"}; + removeAll(inst->instanceRoot(), rootRemovables); + removeAll(inst->minecraftRoot(), mcRemovables); + emitSucceeded(); +} + +void LegacyUpgradeTask::copyAborted() +{ + emitFailed(tr("Instance folder copy has been aborted.")); + return; +} + diff --git a/api/logic/minecraft/legacy/LegacyUpgradeTask.h b/api/logic/minecraft/legacy/LegacyUpgradeTask.h new file mode 100644 index 00000000..56896385 --- /dev/null +++ b/api/logic/minecraft/legacy/LegacyUpgradeTask.h @@ -0,0 +1,38 @@ +#pragma once + +#include "tasks/Task.h" +#include "multimc_logic_export.h" +#include "net/NetJob.h" +#include +#include +#include +#include "settings/SettingsObject.h" +#include "BaseVersion.h" +#include "BaseInstance.h" + + +class BaseInstanceProvider; + +class MULTIMC_LOGIC_EXPORT LegacyUpgradeTask : public Task +{ + Q_OBJECT +public: + explicit LegacyUpgradeTask(SettingsObjectPtr settings, const QString & stagingPath, InstancePtr origInstance, const QString & newName); + +protected: + //! Entry point for tasks. + virtual void executeTask() override; + void copyFinished(); + void copyAborted(); + +private: /* data */ + SettingsObjectPtr m_globalSettings; + InstancePtr m_origInstance; + QString m_stagingPath; + QString m_newName; + QFuture m_copyFuture; + QFutureWatcher m_copyFutureWatcher; +}; + + + -- cgit v1.2.3