summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/logic/CMakeLists.txt4
-rw-r--r--api/logic/Env.cpp2
-rw-r--r--api/logic/Env.h1
-rw-r--r--api/logic/FolderInstanceProvider.cpp5
-rw-r--r--api/logic/minecraft/ModList.h1
-rw-r--r--api/logic/minecraft/legacy/LegacyInstance.cpp313
-rw-r--r--api/logic/minecraft/legacy/LegacyInstance.h128
-rw-r--r--api/logic/minecraft/legacy/LegacyModList.cpp171
-rw-r--r--api/logic/minecraft/legacy/LegacyModList.h56
-rw-r--r--application/CMakeLists.txt5
-rw-r--r--application/InstancePageProvider.h7
-rw-r--r--application/pages/LegacyUpgradePage.cpp25
-rw-r--r--application/pages/LegacyUpgradePage.h60
-rw-r--r--application/pages/LegacyUpgradePage.ui47
14 files changed, 821 insertions, 4 deletions
diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt
index 909e51a9..5cd80166 100644
--- a/api/logic/CMakeLists.txt
+++ b/api/logic/CMakeLists.txt
@@ -228,6 +228,10 @@ set(MINECRAFT_SOURCES
minecraft/launch/LauncherPartLaunch.h
minecraft/launch/PrintInstanceInfo.cpp
minecraft/launch/PrintInstanceInfo.h
+ minecraft/legacy/LegacyModList.h
+ minecraft/legacy/LegacyModList.cpp
+ minecraft/legacy/LegacyInstance.h
+ minecraft/legacy/LegacyInstance.cpp
minecraft/GradleSpecifier.h
minecraft/MinecraftInstance.cpp
minecraft/MinecraftInstance.h
diff --git a/api/logic/Env.cpp b/api/logic/Env.cpp
index e2abda49..cf321af2 100644
--- a/api/logic/Env.cpp
+++ b/api/logic/Env.cpp
@@ -19,8 +19,6 @@ struct Env::Private
shared_qobject_ptr<HttpMetaCache> m_metacache;
std::shared_ptr<IIconList> m_iconlist;
shared_qobject_ptr<Meta::Index> m_metadataIndex;
- // FIXME: replace with mojang format LWJGL in meta store
- std::shared_ptr<LWJGLVersionList> m_lwjgllist;
QString m_jarsPath;
};
diff --git a/api/logic/Env.h b/api/logic/Env.h
index 3dadc58e..276d762d 100644
--- a/api/logic/Env.h
+++ b/api/logic/Env.h
@@ -13,7 +13,6 @@ class QNetworkAccessManager;
class HttpMetaCache;
class BaseVersionList;
class BaseVersion;
-class LWJGLVersionList;
namespace Meta
{
diff --git a/api/logic/FolderInstanceProvider.cpp b/api/logic/FolderInstanceProvider.cpp
index a0fbd46a..25e9bb84 100644
--- a/api/logic/FolderInstanceProvider.cpp
+++ b/api/logic/FolderInstanceProvider.cpp
@@ -2,6 +2,7 @@
#include "settings/INISettingsObject.h"
#include "FileSystem.h"
#include "minecraft/MinecraftInstance.h"
+#include "minecraft/legacy/LegacyInstance.h"
#include "NullInstance.h"
#include <QDir>
@@ -90,6 +91,10 @@ InstancePtr FolderInstanceProvider::loadInstance(const InstanceId& id)
{
inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
}
+ else if (inst_type == "Legacy")
+ {
+ inst.reset(new LegacyInstance(m_globalSettings, instanceSettings, instanceRoot));
+ }
else
{
inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot));
diff --git a/api/logic/minecraft/ModList.h b/api/logic/minecraft/ModList.h
index f9b6b1c5..8cdd2d9a 100644
--- a/api/logic/minecraft/ModList.h
+++ b/api/logic/minecraft/ModList.h
@@ -24,6 +24,7 @@
#include "multimc_logic_export.h"
+class LegacyInstance;
class BaseInstance;
class QFileSystemWatcher;
diff --git a/api/logic/minecraft/legacy/LegacyInstance.cpp b/api/logic/minecraft/legacy/LegacyInstance.cpp
new file mode 100644
index 00000000..532e8307
--- /dev/null
+++ b/api/logic/minecraft/legacy/LegacyInstance.cpp
@@ -0,0 +1,313 @@
+/* Copyright 2013-2017 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <QFileInfo>
+#include <minecraft/launch/LauncherPartLaunch.h>
+#include <QDir>
+#include <settings/Setting.h>
+
+#include "LegacyInstance.h"
+
+#include "minecraft/legacy/LegacyModList.h"
+#include "minecraft/ModList.h"
+#include "minecraft/WorldList.h"
+#include <MMCZip.h>
+#include <FileSystem.h>
+
+LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
+ : BaseInstance(globalSettings, settings, rootDir)
+{
+ settings->registerSetting("NeedsRebuild", true);
+ settings->registerSetting("ShouldUpdate", false);
+ settings->registerSetting("JarVersion", "Unknown");
+ settings->registerSetting("IntendedJarVersion", "");
+ /*
+ * custom base jar has no default. it is determined in code... see the accessor methods for
+ *it
+ *
+ * for instances that DO NOT have the CustomBaseJar setting (legacy instances),
+ * [.]minecraft/bin/mcbackup.jar is the default base jar
+ */
+ settings->registerSetting("UseCustomBaseJar", true);
+ settings->registerSetting("CustomBaseJar", "");
+}
+
+QString LegacyInstance::baseJar() const
+{
+ bool customJar = m_settings->get("UseCustomBaseJar").toBool();
+ if (customJar)
+ {
+ return customBaseJar();
+ }
+ else
+ return defaultBaseJar();
+}
+
+QString LegacyInstance::customBaseJar() const
+{
+ QString value = m_settings->get("CustomBaseJar").toString();
+ if (value.isNull() || value.isEmpty())
+ {
+ return defaultCustomBaseJar();
+ }
+ return value;
+}
+
+bool LegacyInstance::shouldUseCustomBaseJar() const
+{
+ return m_settings->get("UseCustomBaseJar").toBool();
+}
+
+
+shared_qobject_ptr<Task> LegacyInstance::createUpdateTask()
+{
+ return nullptr;
+}
+
+/*
+class LegacyJarModTask : public Task
+{
+ //Q_OBJECT
+public:
+ explicit LegacyJarModTask(std::shared_ptr<LegacyInstance> inst) : Task(nullptr), m_inst(inst)
+ {
+ }
+ virtual void executeTask()
+ {
+ if (!m_inst->shouldRebuild())
+ {
+ emitSucceeded();
+ return;
+ }
+
+ // Get the mod list
+ auto modList = m_inst->getJarMods();
+
+ QFileInfo runnableJar(m_inst->runnableJar());
+ QFileInfo baseJar(m_inst->baseJar());
+ bool base_is_custom = m_inst->shouldUseCustomBaseJar();
+
+ // Nothing to do if there are no jar mods to install, no backup and just the mc jar
+ if (base_is_custom)
+ {
+ // yes, this can happen if the instance only has the runnable jar and not the base jar
+ // it *could* be assumed that such an instance is vanilla, but that wouldn't be safe
+ // because that's not something mmc4 guarantees
+ if (runnableJar.isFile() && !baseJar.exists() && modList.empty())
+ {
+ m_inst->setShouldRebuild(false);
+ emitSucceeded();
+ return;
+ }
+
+ setStatus(tr("Installing mods: Backing up minecraft.jar ..."));
+ if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath()))
+ {
+ emitFailed("It seems both the active and base jar are gone. A fresh base jar will "
+ "be used on next run.");
+ m_inst->setShouldRebuild(true);
+ m_inst->setShouldUpdate(true);
+ m_inst->setShouldUseCustomBaseJar(false);
+ return;
+ }
+ }
+
+ if (!baseJar.exists())
+ {
+ emitFailed("The base jar " + baseJar.filePath() + " does not exist");
+ return;
+ }
+
+ if (runnableJar.exists() && !QFile::remove(runnableJar.filePath()))
+ {
+ emitFailed("Failed to delete old minecraft.jar");
+ return;
+ }
+
+ setStatus(tr("Installing mods: Opening minecraft.jar ..."));
+
+ QString outputJarPath = runnableJar.filePath();
+ QString inputJarPath = baseJar.filePath();
+
+ if(!MMCZip::createModdedJar(inputJarPath, outputJarPath, modList))
+ {
+ emitFailed(tr("Failed to create the custom Minecraft jar file."));
+ return;
+ }
+ m_inst->setShouldRebuild(false);
+ // inst->UpdateVersion(true);
+ emitSucceeded();
+ return;
+
+ }
+ std::shared_ptr<LegacyInstance> m_inst;
+};
+*/
+
+std::shared_ptr<LegacyModList> LegacyInstance::jarModList() const
+{
+ if (!jar_mod_list)
+ {
+ auto list = new LegacyModList(jarModsDir(), modListFile());
+ jar_mod_list.reset(list);
+ }
+ jar_mod_list->update();
+ return jar_mod_list;
+}
+
+QList<Mod> LegacyInstance::getJarMods() const
+{
+ return jarModList()->allMods();
+}
+
+QString LegacyInstance::minecraftRoot() const
+{
+ QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
+ QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
+
+ if (dotMCDir.exists() && !mcDir.exists())
+ return dotMCDir.filePath();
+ else
+ return mcDir.filePath();
+}
+
+QString LegacyInstance::binRoot() const
+{
+ return FS::PathCombine(minecraftRoot(), "bin");
+}
+
+QString LegacyInstance::jarModsDir() const
+{
+ return FS::PathCombine(instanceRoot(), "instMods");
+}
+
+QString LegacyInstance::libDir() const
+{
+ return FS::PathCombine(minecraftRoot(), "lib");
+}
+
+QString LegacyInstance::savesDir() const
+{
+ return FS::PathCombine(minecraftRoot(), "saves");
+}
+
+QString LegacyInstance::loaderModsDir() const
+{
+ return FS::PathCombine(minecraftRoot(), "mods");
+}
+
+QString LegacyInstance::coreModsDir() const
+{
+ return FS::PathCombine(minecraftRoot(), "coremods");
+}
+
+QString LegacyInstance::resourceDir() const
+{
+ return FS::PathCombine(minecraftRoot(), "resources");
+}
+QString LegacyInstance::texturePacksDir() const
+{
+ return FS::PathCombine(minecraftRoot(), "texturepacks");
+}
+
+QString LegacyInstance::runnableJar() const
+{
+ return FS::PathCombine(binRoot(), "minecraft.jar");
+}
+
+QString LegacyInstance::modListFile() const
+{
+ return FS::PathCombine(instanceRoot(), "modlist");
+}
+
+QString LegacyInstance::instanceConfigFolder() const
+{
+ return FS::PathCombine(minecraftRoot(), "config");
+}
+
+bool LegacyInstance::shouldRebuild() const
+{
+ return m_settings->get("NeedsRebuild").toBool();
+}
+
+QString LegacyInstance::currentVersionId() const
+{
+ return m_settings->get("JarVersion").toString();
+}
+
+QString LegacyInstance::intendedVersionId() const
+{
+ return m_settings->get("IntendedJarVersion").toString();
+}
+
+bool LegacyInstance::shouldUpdate() const
+{
+ QVariant var = settings()->get("ShouldUpdate");
+ if (!var.isValid() || var.toBool() == false)
+ {
+ return intendedVersionId() != currentVersionId();
+ }
+ return true;
+}
+
+QString LegacyInstance::defaultBaseJar() const
+{
+ return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
+}
+
+QString LegacyInstance::defaultCustomBaseJar() const
+{
+ return FS::PathCombine(binRoot(), "mcbackup.jar");
+}
+
+QString LegacyInstance::typeName() const
+{
+ return tr("Legacy");
+}
+
+QString LegacyInstance::getStatusbarDescription()
+{
+ return tr("Instance from previous versions.");
+}
+
+QStringList LegacyInstance::verboseDescription(AuthSessionPtr session)
+{
+ QStringList out;
+
+ auto alltraits = traits();
+ if(alltraits.size())
+ {
+ out << "Traits:";
+ for (auto trait : alltraits)
+ {
+ out << " " + trait;
+ }
+ out << "";
+ }
+
+ QString windowParams;
+ if (settings()->get("LaunchMaximized").toBool())
+ {
+ out << "Window size: max (if available)";
+ }
+ else
+ {
+ auto width = settings()->get("MinecraftWinWidth").toInt();
+ auto height = settings()->get("MinecraftWinHeight").toInt();
+ out << "Window size: " + QString::number(width) + " x " + QString::number(height);
+ }
+ out << "";
+ return out;
+}
diff --git a/api/logic/minecraft/legacy/LegacyInstance.h b/api/logic/minecraft/legacy/LegacyInstance.h
new file mode 100644
index 00000000..9c5cedd3
--- /dev/null
+++ b/api/logic/minecraft/legacy/LegacyInstance.h
@@ -0,0 +1,128 @@
+/* Copyright 2013-2017 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BaseInstance.h"
+#include "minecraft/Mod.h"
+
+#include "multimc_logic_export.h"
+
+class ModList;
+class LegacyModList;
+class Task;
+/*
+ * WHY: Legacy instances - from MultiMC 3 and 4 - are here only to provide a way to upgrade them to the current format.
+ */
+class MULTIMC_LOGIC_EXPORT LegacyInstance : public BaseInstance
+{
+ Q_OBJECT
+public:
+
+ explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
+
+ virtual void init() override {};
+
+ /// Path to the instance's minecraft.jar
+ QString runnableJar() const;
+
+ //! Path to the instance's modlist file.
+ QString modListFile() const;
+
+ ////// Directories //////
+ QString libDir() const;
+ QString savesDir() const;
+ QString texturePacksDir() const;
+ QString jarModsDir() const;
+ QString loaderModsDir() const;
+ QString coreModsDir() const;
+ QString resourceDir() const;
+ virtual QString instanceConfigFolder() const override;
+ QString minecraftRoot() const; // Path to the instance's minecraft directory.
+ QString binRoot() const; // Path to the instance's minecraft bin directory.
+
+ /// Get the curent base jar of this instance. By default, it's the
+ /// versions/$version/$version.jar
+ QString baseJar() const;
+
+ /// the default base jar of this instance
+ QString defaultBaseJar() const;
+ /// the default custom base jar of this instance
+ QString defaultCustomBaseJar() const;
+
+ /*!
+ * Whether or not custom base jar is used
+ */
+ bool shouldUseCustomBaseJar() const;
+
+ /*!
+ * The value of the custom base jar
+ */
+ QString customBaseJar() const;
+
+ std::shared_ptr<LegacyModList> jarModList() const;
+ QList<Mod> getJarMods() const;
+
+ /*!
+ * Whether or not the instance's minecraft.jar needs to be rebuilt.
+ * If this is true, when the instance launches, its jar mods will be
+ * re-added to a fresh minecraft.jar file.
+ */
+ bool shouldRebuild() const;
+
+ QString currentVersionId() const;
+ QString intendedVersionId() const;
+
+ QSet<QString> traits() override
+ {
+ return {"legacy-instance", "texturepacks"};
+ };
+
+ virtual bool shouldUpdate() const;
+ virtual shared_qobject_ptr<Task> createUpdateTask() override;
+
+ virtual QString typeName() const override;
+
+ bool canExport() const override
+ {
+ return false;
+ }
+ std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override
+ {
+ return nullptr;
+ }
+ IPathMatcher::Ptr getLogFileMatcher() override
+ {
+ return nullptr;
+ }
+ QString getLogFileRoot() override
+ {
+ return minecraftRoot();
+ }
+
+ QString getStatusbarDescription() override;
+ QStringList verboseDescription(AuthSessionPtr session) override;
+
+ QProcessEnvironment createEnvironment() override
+ {
+ return QProcessEnvironment();
+ }
+ QMap<QString, QString> getVariables() const override
+ {
+ return {};
+ }
+protected:
+ mutable std::shared_ptr<LegacyModList> jar_mod_list;
+};
diff --git a/api/logic/minecraft/legacy/LegacyModList.cpp b/api/logic/minecraft/legacy/LegacyModList.cpp
new file mode 100644
index 00000000..061752e0
--- /dev/null
+++ b/api/logic/minecraft/legacy/LegacyModList.cpp
@@ -0,0 +1,171 @@
+/* Copyright 2013-2017 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "LegacyModList.h"
+#include <FileSystem.h>
+#include <QString>
+#include <QDebug>
+
+LegacyModList::LegacyModList(const QString &dir, const QString &list_file)
+ : m_dir(dir), m_list_file(list_file)
+{
+ FS::ensureFolderPathExists(m_dir.absolutePath());
+ m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
+ QDir::NoSymLinks);
+ m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
+}
+
+ struct OrderItem
+ {
+ QString id;
+ bool enabled = false;
+ };
+ typedef QList<OrderItem> OrderList;
+
+static void internalSort(QList<Mod> &what)
+{
+ auto predicate = [](const Mod &left, const Mod &right)
+ {
+ if (left.name() == right.name())
+ {
+ return left.mmc_id().localeAwareCompare(right.mmc_id()) < 0;
+ }
+ return left.name().localeAwareCompare(right.name()) < 0;
+ };
+ std::sort(what.begin(), what.end(), predicate);
+}
+
+static OrderList readListFile(const QString &m_list_file)
+{
+ OrderList itemList;
+ if (m_list_file.isNull() || m_list_file.isEmpty())
+ return itemList;
+
+ QFile textFile(m_list_file);
+ if (!textFile.open(QIODevice::ReadOnly | QIODevice::Text))
+ return OrderList();
+
+ QTextStream textStream;
+ textStream.setAutoDetectUnicode(true);
+ textStream.setDevice(&textFile);
+ while (true)
+ {
+ QString line = textStream.readLine();
+ if (line.isNull() || line.isEmpty())
+ break;
+ else
+ {
+ OrderItem it;
+ it.enabled = !line.endsWith(".disabled");
+ if (!it.enabled)
+ {
+ line.chop(9);
+ }
+ it.id = line;
+ itemList.append(it);
+ }
+ }
+ textFile.close();
+ return itemList;
+}
+
+bool LegacyModList::update()
+{
+ if (!m_dir.exists() || !m_dir.isReadable())
+ return false;
+
+ QList<Mod> orderedMods;
+ QList<Mod> newMods;
+ m_dir.refresh();
+ auto folderContents = m_dir.entryInfoList();
+ bool orderOrStateChanged = false;
+
+ // first, process the ordered items (if any)
+ OrderList listOrder = readListFile(m_list_file);
+ for (auto item : listOrder)
+ {
+ QFileInfo infoEnabled(m_dir.filePath(item.id));
+ QFileInfo infoDisabled(m_dir.filePath(item.id + ".disabled"));
+ int idxEnabled = folderContents.indexOf(infoEnabled);
+ int idxDisabled = folderContents.indexOf(infoDisabled);
+ bool isEnabled;
+ // if both enabled and disabled versions are present, it's a special case...
+ if (idxEnabled >= 0 && idxDisabled >= 0)
+ {
+ // we only process the one we actually have in the order file.
+ // and exactly as we have it.
+ // THIS IS A CORNER CASE
+ isEnabled = item.enabled;
+ }
+ else
+ {
+ // only one is present.
+ // we pick the one that we found.
+ // we assume the mod was enabled/disabled by external means
+ isEnabled = idxEnabled >= 0;
+ }
+ int idx = isEnabled ? idxEnabled : idxDisabled;
+ QFileInfo &info = isEnabled ? infoEnabled : infoDisabled;
+ // if the file from the index file exists
+ if (idx != -1)
+ {
+ // remove from the actual folder contents list
+ folderContents.takeAt(idx);
+ // append the new mod
+ orderedMods.append(Mod(info));
+ if (isEnabled != item.enabled)
+ orderOrStateChanged = true;
+ }
+ else
+ {
+ orderOrStateChanged = true;
+ }
+ }
+ // if there are any untracked files...
+ if (folderContents.size())
+ {
+ // the order surely changed!
+ for (auto entry : folderContents)
+ {
+ newMods.append(Mod(entry));
+ }
+ internalSort(newMods);
+ orderedMods.append(newMods);
+ orderOrStateChanged = true;
+ }
+ // otherwise, if we were already tracking some mods
+ else if (mods.size())
+ {
+ // if the number doesn't match, order changed.
+ if (mods.size() != orderedMods.size())
+ orderOrStateChanged = true;
+ // if it does match, compare the mods themselves
+ else
+ for (int i = 0; i < mods.size(); i++)
+ {
+ if (!mods[i].strongCompare(orderedMods[i]))
+ {
+ orderOrStateChanged = true;
+ break;
+ }
+ }
+ }
+ mods.swap(orderedMods);
+ if (orderOrStateChanged && !m_list_file.isEmpty())
+ {
+ qDebug() << "Mod list " << m_list_file << " changed!";
+ }
+ return true;
+}
diff --git a/api/logic/minecraft/legacy/LegacyModList.h b/api/logic/minecraft/legacy/LegacyModList.h
new file mode 100644
index 00000000..3fe90ac3
--- /dev/null
+++ b/api/logic/minecraft/legacy/LegacyModList.h
@@ -0,0 +1,56 @@
+/* Copyright 2013-2017 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <QList>
+#include <QString>
+#include <QDir>
+
+#include "minecraft/Mod.h"
+
+#include "multimc_logic_export.h"
+
+class LegacyInstance;
+class BaseInstance;
+
+/**
+ * A legacy mod list.
+ * Backed by a folder.
+ */
+class MULTIMC_LOGIC_EXPORT LegacyModList
+{
+public:
+
+ LegacyModList(const QString &dir, const QString &list_file = QString());
+
+ /// Reloads the mod list and returns true if the list changed.
+ bool update();
+
+ QDir dir()
+ {
+ return m_dir;
+ }
+
+ const QList<Mod> & allMods()
+ {
+ return mods;
+ }
+
+protected:
+ QDir m_dir;
+ QString m_list_file;
+ QList<Mod> mods;
+};
diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt
index 70cb1e93..17e19b58 100644
--- a/application/CMakeLists.txt
+++ b/application/CMakeLists.txt
@@ -131,6 +131,8 @@ SET(MULTIMC_SOURCES
pages/ScreenshotsPage.h
pages/OtherLogsPage.cpp
pages/OtherLogsPage.h
+ pages/LegacyUpgradePage.cpp
+ pages/LegacyUpgradePage.h
pages/WorldListPage.cpp
pages/WorldListPage.h
@@ -229,7 +231,7 @@ SET(MULTIMC_SOURCES
######## UIs ########
SET(MULTIMC_UIS
- # Option pages
+ # Instance pages
pages/VersionPage.ui
pages/ModFolderPage.ui
pages/LogPage.ui
@@ -237,6 +239,7 @@ SET(MULTIMC_UIS
pages/NotesPage.ui
pages/ScreenshotsPage.ui
pages/OtherLogsPage.ui
+ pages/LegacyUpgradePage.ui
pages/WorldListPage.ui
# Global settings pages
diff --git a/application/InstancePageProvider.h b/application/InstancePageProvider.h
index ac5306c0..3b361e3e 100644
--- a/application/InstancePageProvider.h
+++ b/application/InstancePageProvider.h
@@ -1,5 +1,6 @@
#pragma once
#include "minecraft/MinecraftInstance.h"
+#include "minecraft/legacy/LegacyInstance.h"
#include <FileSystem.h>
#include "pages/BasePage.h"
#include "pages/LogPage.h"
@@ -12,6 +13,7 @@
#include "pages/InstanceSettingsPage.h"
#include "pages/OtherLogsPage.h"
#include "pages/BasePageProvider.h"
+#include "pages/LegacyUpgradePage.h"
#include "pages/WorldListPage.h"
@@ -44,6 +46,11 @@ public:
values.append(new ScreenshotsPage(FS::PathCombine(onesix->minecraftRoot(), "screenshots")));
values.append(new InstanceSettingsPage(onesix.get()));
}
+ std::shared_ptr<LegacyInstance> legacy = std::dynamic_pointer_cast<LegacyInstance>(inst);
+ if(legacy)
+ {
+ values.append(new LegacyUpgradePage(legacy.get()));
+ }
auto logMatcher = inst->getLogFileMatcher();
if(logMatcher)
{
diff --git a/application/pages/LegacyUpgradePage.cpp b/application/pages/LegacyUpgradePage.cpp
new file mode 100644
index 00000000..14cb916d
--- /dev/null
+++ b/application/pages/LegacyUpgradePage.cpp
@@ -0,0 +1,25 @@
+#include "LegacyUpgradePage.h"
+#include "ui_LegacyUpgradePage.h"
+
+#include "minecraft/legacy/LegacyInstance.h"
+
+LegacyUpgradePage::LegacyUpgradePage(LegacyInstance *inst, QWidget *parent)
+ : QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst)
+{
+ ui->setupUi(this);
+}
+
+LegacyUpgradePage::~LegacyUpgradePage()
+{
+ delete ui;
+}
+
+void LegacyUpgradePage::on_upgradeButton_clicked()
+{
+ // now what?
+}
+
+bool LegacyUpgradePage::shouldDisplay() const
+{
+ return !m_inst->isRunning();
+}
diff --git a/application/pages/LegacyUpgradePage.h b/application/pages/LegacyUpgradePage.h
new file mode 100644
index 00000000..4731bb82
--- /dev/null
+++ b/application/pages/LegacyUpgradePage.h
@@ -0,0 +1,60 @@
+/* Copyright 2013-2017 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <QWidget>
+
+#include "minecraft/legacy/LegacyInstance.h"
+#include "pages/BasePage.h"
+#include <MultiMC.h>
+
+namespace Ui
+{
+class LegacyUpgradePage;
+}
+
+class LegacyUpgradePage : public QWidget, public BasePage
+{
+ Q_OBJECT
+
+public:
+ explicit LegacyUpgradePage(LegacyInstance *inst, QWidget *parent = 0);
+ virtual ~LegacyUpgradePage();
+ virtual QString displayName() const override
+ {
+ return tr("Upgrade");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("checkupdate");
+ }
+ virtual QString id() const override
+ {
+ return "upgrade";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Legacy-upgrade";
+ }
+ virtual bool shouldDisplay() const override;
+private
+slots:
+ void on_upgradeButton_clicked();
+
+private:
+ Ui::LegacyUpgradePage *ui;
+ LegacyInstance *m_inst;
+};
diff --git a/application/pages/LegacyUpgradePage.ui b/application/pages/LegacyUpgradePage.ui
new file mode 100644
index 00000000..124a0ce9
--- /dev/null
+++ b/application/pages/LegacyUpgradePage.ui
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LegacyUpgradePage</class>
+ <widget class="QWidget" name="LegacyUpgradePage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>546</width>
+ <height>405</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTextBrowser" name="textBrowser">
+ <property name="html">
+ <string>&lt;html&gt;&lt;body&gt;&lt;h1&gt;Upgrade is required&lt;/h1&gt;&lt;p&gt;MultiMC now supports old Minecraft versions and all the required features in the new (OneSix) instance format. As a consequence, the old (Legacy) format has been entirely disabled and old instances need to be upgraded.&lt;/p&gt;&lt;p&gt;The upgrade will create a new instance with the same contents as the current one, in the new format. The original instance will remain untouched, in case anything goes wrong in the process.&lt;/p&gt;&lt;p&gt;Please report any issues on our &lt;a href=&quot;https://github.com/MultiMC/MultiMC5/issues&quot;&gt;github issues page&lt;/a&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCommandLinkButton" name="upgradeButton">
+ <property name="text">
+ <string>Upgrade the instance</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>