NOISSUE Add back Legacy for migration purposes
This commit is contained in:
parent
b2b0487600
commit
9a6c2b0e2c
@ -228,6 +228,10 @@ set(MINECRAFT_SOURCES
|
|||||||
minecraft/launch/LauncherPartLaunch.h
|
minecraft/launch/LauncherPartLaunch.h
|
||||||
minecraft/launch/PrintInstanceInfo.cpp
|
minecraft/launch/PrintInstanceInfo.cpp
|
||||||
minecraft/launch/PrintInstanceInfo.h
|
minecraft/launch/PrintInstanceInfo.h
|
||||||
|
minecraft/legacy/LegacyModList.h
|
||||||
|
minecraft/legacy/LegacyModList.cpp
|
||||||
|
minecraft/legacy/LegacyInstance.h
|
||||||
|
minecraft/legacy/LegacyInstance.cpp
|
||||||
minecraft/GradleSpecifier.h
|
minecraft/GradleSpecifier.h
|
||||||
minecraft/MinecraftInstance.cpp
|
minecraft/MinecraftInstance.cpp
|
||||||
minecraft/MinecraftInstance.h
|
minecraft/MinecraftInstance.h
|
||||||
|
@ -19,8 +19,6 @@ struct Env::Private
|
|||||||
shared_qobject_ptr<HttpMetaCache> m_metacache;
|
shared_qobject_ptr<HttpMetaCache> m_metacache;
|
||||||
std::shared_ptr<IIconList> m_iconlist;
|
std::shared_ptr<IIconList> m_iconlist;
|
||||||
shared_qobject_ptr<Meta::Index> m_metadataIndex;
|
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;
|
QString m_jarsPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ class QNetworkAccessManager;
|
|||||||
class HttpMetaCache;
|
class HttpMetaCache;
|
||||||
class BaseVersionList;
|
class BaseVersionList;
|
||||||
class BaseVersion;
|
class BaseVersion;
|
||||||
class LWJGLVersionList;
|
|
||||||
|
|
||||||
namespace Meta
|
namespace Meta
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "settings/INISettingsObject.h"
|
#include "settings/INISettingsObject.h"
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "minecraft/MinecraftInstance.h"
|
#include "minecraft/MinecraftInstance.h"
|
||||||
|
#include "minecraft/legacy/LegacyInstance.h"
|
||||||
#include "NullInstance.h"
|
#include "NullInstance.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@ -90,6 +91,10 @@ InstancePtr FolderInstanceProvider::loadInstance(const InstanceId& id)
|
|||||||
{
|
{
|
||||||
inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
|
inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot));
|
||||||
}
|
}
|
||||||
|
else if (inst_type == "Legacy")
|
||||||
|
{
|
||||||
|
inst.reset(new LegacyInstance(m_globalSettings, instanceSettings, instanceRoot));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot));
|
inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot));
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "multimc_logic_export.h"
|
#include "multimc_logic_export.h"
|
||||||
|
|
||||||
|
class LegacyInstance;
|
||||||
class BaseInstance;
|
class BaseInstance;
|
||||||
class QFileSystemWatcher;
|
class QFileSystemWatcher;
|
||||||
|
|
||||||
|
313
api/logic/minecraft/legacy/LegacyInstance.cpp
Normal file
313
api/logic/minecraft/legacy/LegacyInstance.cpp
Normal file
@ -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;
|
||||||
|
}
|
128
api/logic/minecraft/legacy/LegacyInstance.h
Normal file
128
api/logic/minecraft/legacy/LegacyInstance.h
Normal file
@ -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;
|
||||||
|
};
|
171
api/logic/minecraft/legacy/LegacyModList.cpp
Normal file
171
api/logic/minecraft/legacy/LegacyModList.cpp
Normal file
@ -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;
|
||||||
|
}
|
56
api/logic/minecraft/legacy/LegacyModList.h
Normal file
56
api/logic/minecraft/legacy/LegacyModList.h
Normal file
@ -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;
|
||||||
|
};
|
@ -131,6 +131,8 @@ SET(MULTIMC_SOURCES
|
|||||||
pages/ScreenshotsPage.h
|
pages/ScreenshotsPage.h
|
||||||
pages/OtherLogsPage.cpp
|
pages/OtherLogsPage.cpp
|
||||||
pages/OtherLogsPage.h
|
pages/OtherLogsPage.h
|
||||||
|
pages/LegacyUpgradePage.cpp
|
||||||
|
pages/LegacyUpgradePage.h
|
||||||
pages/WorldListPage.cpp
|
pages/WorldListPage.cpp
|
||||||
pages/WorldListPage.h
|
pages/WorldListPage.h
|
||||||
|
|
||||||
@ -229,7 +231,7 @@ SET(MULTIMC_SOURCES
|
|||||||
|
|
||||||
######## UIs ########
|
######## UIs ########
|
||||||
SET(MULTIMC_UIS
|
SET(MULTIMC_UIS
|
||||||
# Option pages
|
# Instance pages
|
||||||
pages/VersionPage.ui
|
pages/VersionPage.ui
|
||||||
pages/ModFolderPage.ui
|
pages/ModFolderPage.ui
|
||||||
pages/LogPage.ui
|
pages/LogPage.ui
|
||||||
@ -237,6 +239,7 @@ SET(MULTIMC_UIS
|
|||||||
pages/NotesPage.ui
|
pages/NotesPage.ui
|
||||||
pages/ScreenshotsPage.ui
|
pages/ScreenshotsPage.ui
|
||||||
pages/OtherLogsPage.ui
|
pages/OtherLogsPage.ui
|
||||||
|
pages/LegacyUpgradePage.ui
|
||||||
pages/WorldListPage.ui
|
pages/WorldListPage.ui
|
||||||
|
|
||||||
# Global settings pages
|
# Global settings pages
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "minecraft/MinecraftInstance.h"
|
#include "minecraft/MinecraftInstance.h"
|
||||||
|
#include "minecraft/legacy/LegacyInstance.h"
|
||||||
#include <FileSystem.h>
|
#include <FileSystem.h>
|
||||||
#include "pages/BasePage.h"
|
#include "pages/BasePage.h"
|
||||||
#include "pages/LogPage.h"
|
#include "pages/LogPage.h"
|
||||||
@ -12,6 +13,7 @@
|
|||||||
#include "pages/InstanceSettingsPage.h"
|
#include "pages/InstanceSettingsPage.h"
|
||||||
#include "pages/OtherLogsPage.h"
|
#include "pages/OtherLogsPage.h"
|
||||||
#include "pages/BasePageProvider.h"
|
#include "pages/BasePageProvider.h"
|
||||||
|
#include "pages/LegacyUpgradePage.h"
|
||||||
#include "pages/WorldListPage.h"
|
#include "pages/WorldListPage.h"
|
||||||
|
|
||||||
|
|
||||||
@ -44,6 +46,11 @@ public:
|
|||||||
values.append(new ScreenshotsPage(FS::PathCombine(onesix->minecraftRoot(), "screenshots")));
|
values.append(new ScreenshotsPage(FS::PathCombine(onesix->minecraftRoot(), "screenshots")));
|
||||||
values.append(new InstanceSettingsPage(onesix.get()));
|
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();
|
auto logMatcher = inst->getLogFileMatcher();
|
||||||
if(logMatcher)
|
if(logMatcher)
|
||||||
{
|
{
|
||||||
|
25
application/pages/LegacyUpgradePage.cpp
Normal file
25
application/pages/LegacyUpgradePage.cpp
Normal file
@ -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();
|
||||||
|
}
|
60
application/pages/LegacyUpgradePage.h
Normal file
60
application/pages/LegacyUpgradePage.h
Normal file
@ -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;
|
||||||
|
};
|
47
application/pages/LegacyUpgradePage.ui
Normal file
47
application/pages/LegacyUpgradePage.ui
Normal file
@ -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><html><body><h1>Upgrade is required</h1><p>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.</p><p>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>Please report any issues on our <a href="https://github.com/MultiMC/MultiMC5/issues">github issues page</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…
x
Reference in New Issue
Block a user