refactor: drop LegacyInstance
This commit is contained in:
parent
3059f13011
commit
a70d1f1a91
@ -286,13 +286,6 @@ set(MINECRAFT_SOURCES
|
||||
minecraft/launch/VerifyJavaInstall.cpp
|
||||
minecraft/launch/VerifyJavaInstall.h
|
||||
|
||||
minecraft/legacy/LegacyModList.h
|
||||
minecraft/legacy/LegacyModList.cpp
|
||||
minecraft/legacy/LegacyInstance.h
|
||||
minecraft/legacy/LegacyInstance.cpp
|
||||
minecraft/legacy/LegacyUpgradeTask.h
|
||||
minecraft/legacy/LegacyUpgradeTask.cpp
|
||||
|
||||
minecraft/GradleSpecifier.h
|
||||
minecraft/MinecraftInstance.cpp
|
||||
minecraft/MinecraftInstance.h
|
||||
@ -701,8 +694,6 @@ SET(LAUNCHER_SOURCES
|
||||
ui/pages/instance/OtherLogsPage.h
|
||||
ui/pages/instance/ServersPage.cpp
|
||||
ui/pages/instance/ServersPage.h
|
||||
ui/pages/instance/LegacyUpgradePage.cpp
|
||||
ui/pages/instance/LegacyUpgradePage.h
|
||||
ui/pages/instance/WorldListPage.cpp
|
||||
ui/pages/instance/WorldListPage.h
|
||||
|
||||
@ -884,7 +875,6 @@ qt5_wrap_ui(LAUNCHER_UI
|
||||
ui/pages/instance/InstanceSettingsPage.ui
|
||||
ui/pages/instance/VersionPage.ui
|
||||
ui/pages/instance/WorldListPage.ui
|
||||
ui/pages/instance/LegacyUpgradePage.ui
|
||||
ui/pages/instance/ScreenshotsPage.ui
|
||||
ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui
|
||||
ui/pages/modplatform/atlauncher/AtlPage.ui
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "BaseInstance.h"
|
||||
#include "InstanceTask.h"
|
||||
#include "settings/INISettingsObject.h"
|
||||
#include "minecraft/legacy/LegacyInstance.h"
|
||||
#include "NullInstance.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "FileSystem.h"
|
||||
@ -553,10 +552,6 @@ InstancePtr InstanceList::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));
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/legacy/LegacyInstance.h"
|
||||
#include <FileSystem.h>
|
||||
#include "ui/pages/BasePage.h"
|
||||
#include "ui/pages/BasePageProvider.h"
|
||||
@ -14,7 +13,6 @@
|
||||
#include "ui/pages/instance/ScreenshotsPage.h"
|
||||
#include "ui/pages/instance/InstanceSettingsPage.h"
|
||||
#include "ui/pages/instance/OtherLogsPage.h"
|
||||
#include "ui/pages/instance/LegacyUpgradePage.h"
|
||||
#include "ui/pages/instance/WorldListPage.h"
|
||||
#include "ui/pages/instance/ServersPage.h"
|
||||
#include "ui/pages/instance/GameOptionsPage.h"
|
||||
@ -34,8 +32,6 @@ public:
|
||||
QList<BasePage *> values;
|
||||
values.append(new LogPage(inst));
|
||||
std::shared_ptr<MinecraftInstance> onesix = std::dynamic_pointer_cast<MinecraftInstance>(inst);
|
||||
if(onesix)
|
||||
{
|
||||
values.append(new VersionPage(onesix.get()));
|
||||
auto modsPage = new ModFolderPage(onesix.get(), onesix->loaderModList(), "mods", "loadermods", tr("Mods"), "Loader-mods");
|
||||
modsPage->setFilter("%1 (*.zip *.jar *.litemod)");
|
||||
@ -50,15 +46,6 @@ public:
|
||||
// values.append(new GameOptionsPage(onesix.get()));
|
||||
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "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));
|
||||
values.append(new NotesPage(legacy.get()));
|
||||
values.append(new WorldListPage(legacy.get(), legacy->worldList()));
|
||||
values.append(new ScreenshotsPage(FS::PathCombine(legacy->gameRoot(), "screenshots")));
|
||||
}
|
||||
auto logMatcher = inst->getLogFileMatcher();
|
||||
if(logMatcher)
|
||||
{
|
||||
|
@ -1,256 +0,0 @@
|
||||
/* Copyright 2013-2021 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/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", QString());
|
||||
settings->registerSetting("IntendedJarVersion", QString());
|
||||
/*
|
||||
* 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::mainJarToPreserve() const
|
||||
{
|
||||
bool customJar = m_settings->get("UseCustomBaseJar").toBool();
|
||||
if(customJar)
|
||||
{
|
||||
auto base = baseJar();
|
||||
if(QFile::exists(base))
|
||||
{
|
||||
return base;
|
||||
}
|
||||
}
|
||||
auto runnable = runnableJar();
|
||||
if(QFile::exists(runnable))
|
||||
{
|
||||
return runnable;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
Task::Ptr LegacyInstance::createUpdateTask(Net::Mode)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
QString LegacyInstance::gameRoot() const
|
||||
{
|
||||
QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
|
||||
QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
|
||||
|
||||
if (mcDir.exists() && !dotMCDir.exists())
|
||||
return mcDir.filePath();
|
||||
else
|
||||
return dotMCDir.filePath();
|
||||
}
|
||||
|
||||
QString LegacyInstance::binRoot() const
|
||||
{
|
||||
return FS::PathCombine(gameRoot(), "bin");
|
||||
}
|
||||
|
||||
QString LegacyInstance::modsRoot() const {
|
||||
return FS::PathCombine(gameRoot(), "mods");
|
||||
}
|
||||
|
||||
|
||||
QString LegacyInstance::jarModsDir() const
|
||||
{
|
||||
return FS::PathCombine(instanceRoot(), "instMods");
|
||||
}
|
||||
|
||||
QString LegacyInstance::libDir() const
|
||||
{
|
||||
return FS::PathCombine(gameRoot(), "lib");
|
||||
}
|
||||
|
||||
QString LegacyInstance::savesDir() const
|
||||
{
|
||||
return FS::PathCombine(gameRoot(), "saves");
|
||||
}
|
||||
|
||||
QString LegacyInstance::coreModsDir() const
|
||||
{
|
||||
return FS::PathCombine(gameRoot(), "coremods");
|
||||
}
|
||||
|
||||
QString LegacyInstance::resourceDir() const
|
||||
{
|
||||
return FS::PathCombine(gameRoot(), "resources");
|
||||
}
|
||||
QString LegacyInstance::texturePacksDir() const
|
||||
{
|
||||
return FS::PathCombine(gameRoot(), "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(gameRoot(), "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");
|
||||
}
|
||||
|
||||
std::shared_ptr<WorldList> LegacyInstance::worldList() const
|
||||
{
|
||||
if (!m_world_list)
|
||||
{
|
||||
m_world_list.reset(new WorldList(savesDir()));
|
||||
}
|
||||
return m_world_list;
|
||||
}
|
||||
|
||||
QString LegacyInstance::typeName() const
|
||||
{
|
||||
return tr("Legacy");
|
||||
}
|
||||
|
||||
QString LegacyInstance::getStatusbarDescription()
|
||||
{
|
||||
return tr("Instance from previous versions.");
|
||||
}
|
||||
|
||||
QStringList LegacyInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin)
|
||||
{
|
||||
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;
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
/* Copyright 2013-2021 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 "launch/LaunchTask.h"
|
||||
|
||||
class ModFolderModel;
|
||||
class LegacyModList;
|
||||
class WorldList;
|
||||
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 LegacyInstance : public BaseInstance
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
|
||||
|
||||
virtual void saveNow() 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 coreModsDir() const;
|
||||
QString resourceDir() const;
|
||||
|
||||
QString instanceConfigFolder() const override;
|
||||
|
||||
QString gameRoot() const override; // Path to the instance's minecraft directory.
|
||||
QString modsRoot() const override; // 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;
|
||||
|
||||
// the main jar that we actually want to keep when migrating the instance
|
||||
QString mainJarToPreserve() 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;
|
||||
std::shared_ptr<WorldList> worldList() 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() const override
|
||||
{
|
||||
return {"legacy-instance", "texturepacks"};
|
||||
};
|
||||
|
||||
virtual bool shouldUpdate() const;
|
||||
virtual Task::Ptr createUpdateTask(Net::Mode mode) override;
|
||||
|
||||
virtual QString typeName() const override;
|
||||
|
||||
bool canLaunch() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool canEdit() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool canExport() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
shared_qobject_ptr<LaunchTask> createLaunchTask(
|
||||
AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
IPathMatcher::Ptr getLogFileMatcher() override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
QString getLogFileRoot() override
|
||||
{
|
||||
return gameRoot();
|
||||
}
|
||||
|
||||
QString getStatusbarDescription() override;
|
||||
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
|
||||
|
||||
QProcessEnvironment createEnvironment() override
|
||||
{
|
||||
return QProcessEnvironment();
|
||||
}
|
||||
QMap<QString, QString> getVariables() const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
protected:
|
||||
mutable std::shared_ptr<LegacyModList> jar_mod_list;
|
||||
mutable std::shared_ptr<WorldList> m_world_list;
|
||||
};
|
@ -1,136 +0,0 @@
|
||||
/* Copyright 2013-2021 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);
|
||||
m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
|
||||
}
|
||||
|
||||
struct OrderItem
|
||||
{
|
||||
QString id;
|
||||
bool enabled = false;
|
||||
};
|
||||
typedef QList<OrderItem> OrderList;
|
||||
|
||||
static void internalSort(QList<LegacyModList::Mod> &what)
|
||||
{
|
||||
auto predicate = [](const LegacyModList::Mod &left, const LegacyModList::Mod &right)
|
||||
{
|
||||
return left.fileName().localeAwareCompare(right.fileName()) < 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();
|
||||
|
||||
// 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(info);
|
||||
}
|
||||
}
|
||||
// if there are any untracked files... append them sorted at the end
|
||||
if (folderContents.size())
|
||||
{
|
||||
for (auto entry : folderContents)
|
||||
{
|
||||
newMods.append(entry);
|
||||
}
|
||||
internalSort(newMods);
|
||||
orderedMods.append(newMods);
|
||||
}
|
||||
mods.swap(orderedMods);
|
||||
return true;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/* Copyright 2013-2021 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>
|
||||
|
||||
class LegacyModList
|
||||
{
|
||||
public:
|
||||
|
||||
using Mod = QFileInfo;
|
||||
|
||||
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;
|
||||
};
|
@ -1,138 +0,0 @@
|
||||
#include "LegacyUpgradeTask.h"
|
||||
#include "settings/INISettingsObject.h"
|
||||
#include "FileSystem.h"
|
||||
#include "NullInstance.h"
|
||||
#include "pathmatcher/RegexpMatcher.h"
|
||||
#include <QtConcurrentRun>
|
||||
#include "LegacyInstance.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/PackProfile.h"
|
||||
#include "LegacyModList.h"
|
||||
#include "classparser.h"
|
||||
|
||||
LegacyUpgradeTask::LegacyUpgradeTask(InstancePtr origInstance)
|
||||
{
|
||||
m_origInstance = origInstance;
|
||||
}
|
||||
|
||||
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<bool>::finished, this, &LegacyUpgradeTask::copyFinished);
|
||||
connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::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;
|
||||
}
|
||||
}
|
||||
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<LegacyInstance>(m_origInstance);
|
||||
|
||||
auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(m_stagingPath, "instance.cfg"));
|
||||
instanceSettings->registerSetting("InstanceType", "Legacy");
|
||||
instanceSettings->set("InstanceType", "OneSix");
|
||||
// NOTE: this scope ensures the instance is fully saved before we emitSucceeded
|
||||
{
|
||||
MinecraftInstance inst(m_globalSettings, instanceSettings, m_stagingPath);
|
||||
inst.setName(m_instName);
|
||||
|
||||
QString preferredVersionNumber = decideVersion(legacyInst->currentVersionId(), legacyInst->intendedVersionId());
|
||||
if(preferredVersionNumber.isNull())
|
||||
{
|
||||
// try to decide version based on the jar(s?)
|
||||
preferredVersionNumber = classparser::GetMinecraftJarVersion(legacyInst->baseJar());
|
||||
if(preferredVersionNumber.isNull())
|
||||
{
|
||||
preferredVersionNumber = classparser::GetMinecraftJarVersion(legacyInst->runnableJar());
|
||||
if(preferredVersionNumber.isNull())
|
||||
{
|
||||
emitFailed(tr("Could not decide Minecraft version."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto components = inst.getPackProfile();
|
||||
components->buildingFromScratch();
|
||||
components->setComponentVersion("net.minecraft", preferredVersionNumber, true);
|
||||
|
||||
QString jarPath = legacyInst->mainJarToPreserve();
|
||||
if(!jarPath.isNull())
|
||||
{
|
||||
qDebug() << "Preserving base jar! : " << 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
|
||||
components->installCustomJar(jarPath);
|
||||
}
|
||||
|
||||
auto jarMods = legacyInst->jarModList()->allMods();
|
||||
for(auto & jarMod: jarMods)
|
||||
{
|
||||
QString modPath = jarMod.absoluteFilePath();
|
||||
qDebug() << "jarMod: " << modPath;
|
||||
components->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.gameRoot(), mcRemovables);
|
||||
}
|
||||
emitSucceeded();
|
||||
}
|
||||
|
||||
void LegacyUpgradeTask::copyAborted()
|
||||
{
|
||||
emitFailed(tr("Instance folder copy has been aborted."));
|
||||
return;
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "InstanceTask.h"
|
||||
#include "net/NetJob.h"
|
||||
#include <QUrl>
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
#include "settings/SettingsObject.h"
|
||||
#include "BaseVersion.h"
|
||||
#include "BaseInstance.h"
|
||||
|
||||
|
||||
class LegacyUpgradeTask : public InstanceTask
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LegacyUpgradeTask(InstancePtr origInstance);
|
||||
|
||||
protected:
|
||||
//! Entry point for tasks.
|
||||
virtual void executeTask() override;
|
||||
void copyFinished();
|
||||
void copyAborted();
|
||||
|
||||
private: /* data */
|
||||
InstancePtr m_origInstance;
|
||||
QFuture<bool> m_copyFuture;
|
||||
QFutureWatcher<bool> m_copyFutureWatcher;
|
||||
};
|
@ -1,51 +0,0 @@
|
||||
#include "LegacyUpgradePage.h"
|
||||
#include "ui_LegacyUpgradePage.h"
|
||||
|
||||
#include "InstanceList.h"
|
||||
#include "minecraft/legacy/LegacyInstance.h"
|
||||
#include "minecraft/legacy/LegacyUpgradeTask.h"
|
||||
#include "Application.h"
|
||||
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
|
||||
LegacyUpgradePage::LegacyUpgradePage(InstancePtr inst, QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
LegacyUpgradePage::~LegacyUpgradePage()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void LegacyUpgradePage::runModalTask(Task *task)
|
||||
{
|
||||
connect(task, &Task::failed, [this](QString reason)
|
||||
{
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Warning)->show();
|
||||
});
|
||||
ProgressDialog loadDialog(this);
|
||||
loadDialog.setSkipButton(true, tr("Abort"));
|
||||
if(loadDialog.execWithTask(task) == QDialog::Accepted)
|
||||
{
|
||||
m_container->requestClose();
|
||||
}
|
||||
}
|
||||
|
||||
void LegacyUpgradePage::on_upgradeButton_clicked()
|
||||
{
|
||||
QString newName = tr("%1 (Migrated)").arg(m_inst->name());
|
||||
auto upgradeTask = new LegacyUpgradeTask(m_inst);
|
||||
upgradeTask->setName(newName);
|
||||
upgradeTask->setGroup(APPLICATION->instances()->getInstanceGroup(m_inst->id()));
|
||||
upgradeTask->setIcon(m_inst->iconKey());
|
||||
unique_qobject_ptr<Task> task(APPLICATION->instances()->wrapInstanceTask(upgradeTask));
|
||||
runModalTask(task.get());
|
||||
}
|
||||
|
||||
bool LegacyUpgradePage::shouldDisplay() const
|
||||
{
|
||||
return !m_inst->isRunning();
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/* Copyright 2013-2021 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 "ui/pages/BasePage.h"
|
||||
#include <Application.h>
|
||||
#include "tasks/Task.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class LegacyUpgradePage;
|
||||
}
|
||||
|
||||
class LegacyUpgradePage : public QWidget, public BasePage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LegacyUpgradePage(InstancePtr inst, QWidget *parent = 0);
|
||||
virtual ~LegacyUpgradePage();
|
||||
virtual QString displayName() const override
|
||||
{
|
||||
return tr("Upgrade");
|
||||
}
|
||||
virtual QIcon icon() const override
|
||||
{
|
||||
return APPLICATION->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:
|
||||
void runModalTask(Task *task);
|
||||
|
||||
private:
|
||||
Ui::LegacyUpgradePage *ui;
|
||||
InstancePtr m_inst;
|
||||
};
|
@ -1,54 +0,0 @@
|
||||
<?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><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Noto Sans'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<h1 style=" margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:xx-large; font-weight:600;">Upgrade is required</span></h1>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PolyMC 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.</p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">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.</p>
|
||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Please report any issues on our <a href="https://github.com/PolyMC/PolyMC/issues"><span style=" text-decoration: underline; color:#3584e4;">github issues page</span></a>.</p></body></html></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>
|
Loading…
Reference in New Issue
Block a user