refactor: drop migration for pre-component instances
This commit is contained in:
parent
613b351f13
commit
3059f13011
@ -124,18 +124,7 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
|
|||||||
m_settings->registerSetting("JoinServerOnLaunch", false);
|
m_settings->registerSetting("JoinServerOnLaunch", false);
|
||||||
m_settings->registerSetting("JoinServerOnLaunchAddress", "");
|
m_settings->registerSetting("JoinServerOnLaunchAddress", "");
|
||||||
|
|
||||||
// DEPRECATED: Read what versions the user configuration thinks should be used
|
|
||||||
m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, "");
|
|
||||||
m_settings->registerSetting("LWJGLVersion", "");
|
|
||||||
m_settings->registerSetting("ForgeVersion", "");
|
|
||||||
m_settings->registerSetting("LiteloaderVersion", "");
|
|
||||||
|
|
||||||
m_components.reset(new PackProfile(this));
|
m_components.reset(new PackProfile(this));
|
||||||
m_components->setOldConfigVersion("net.minecraft", m_settings->get("IntendedVersion").toString());
|
|
||||||
auto setting = m_settings->getSetting("LWJGLVersion");
|
|
||||||
m_components->setOldConfigVersion("org.lwjgl", m_settings->get("LWJGLVersion").toString());
|
|
||||||
m_components->setOldConfigVersion("net.minecraftforge", m_settings->get("ForgeVersion").toString());
|
|
||||||
m_components->setOldConfigVersion("com.mumfrey.liteloader", m_settings->get("LiteloaderVersion").toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MinecraftInstance::saveNow()
|
void MinecraftInstance::saveNow()
|
||||||
|
@ -272,18 +272,6 @@ void PackProfile::save_internal()
|
|||||||
bool PackProfile::load()
|
bool PackProfile::load()
|
||||||
{
|
{
|
||||||
auto filename = componentsFilePath();
|
auto filename = componentsFilePath();
|
||||||
QFile componentsFile(filename);
|
|
||||||
|
|
||||||
// migrate old config to new one, if needed
|
|
||||||
if(!componentsFile.exists())
|
|
||||||
{
|
|
||||||
if(!migratePreComponentConfig())
|
|
||||||
{
|
|
||||||
// FIXME: the user should be notified...
|
|
||||||
qCritical() << "Failed to convert old pre-component config for instance" << d->m_instance->name();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the new component list and swap it with the current one...
|
// load the new component list and swap it with the current one...
|
||||||
ComponentContainer newComponents;
|
ComponentContainer newComponents;
|
||||||
@ -369,239 +357,6 @@ void PackProfile::updateFailed(const QString& error)
|
|||||||
invalidateLaunchProfile();
|
invalidateLaunchProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE this is really old stuff, and only needs to be used when loading the old hardcoded component-unaware format (loadPreComponentConfig).
|
|
||||||
static void upgradeDeprecatedFiles(QString root, QString instanceName)
|
|
||||||
{
|
|
||||||
auto versionJsonPath = FS::PathCombine(root, "version.json");
|
|
||||||
auto customJsonPath = FS::PathCombine(root, "custom.json");
|
|
||||||
auto mcJson = FS::PathCombine(root, "patches" , "net.minecraft.json");
|
|
||||||
|
|
||||||
QString sourceFile;
|
|
||||||
QString renameFile;
|
|
||||||
|
|
||||||
// convert old crap.
|
|
||||||
if(QFile::exists(customJsonPath))
|
|
||||||
{
|
|
||||||
sourceFile = customJsonPath;
|
|
||||||
renameFile = versionJsonPath;
|
|
||||||
}
|
|
||||||
else if(QFile::exists(versionJsonPath))
|
|
||||||
{
|
|
||||||
sourceFile = versionJsonPath;
|
|
||||||
}
|
|
||||||
if(!sourceFile.isEmpty() && !QFile::exists(mcJson))
|
|
||||||
{
|
|
||||||
if(!FS::ensureFilePathExists(mcJson))
|
|
||||||
{
|
|
||||||
qWarning() << "Couldn't create patches folder for" << instanceName;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(!renameFile.isEmpty() && QFile::exists(renameFile))
|
|
||||||
{
|
|
||||||
if(!QFile::rename(renameFile, renameFile + ".old"))
|
|
||||||
{
|
|
||||||
qWarning() << "Couldn't rename" << renameFile << "to" << renameFile + ".old" << "in" << instanceName;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false);
|
|
||||||
ProfileUtils::removeLwjglFromPatch(file);
|
|
||||||
file->uid = "net.minecraft";
|
|
||||||
file->version = file->minecraftVersion;
|
|
||||||
file->name = "Minecraft";
|
|
||||||
|
|
||||||
Meta::Require needsLwjgl;
|
|
||||||
needsLwjgl.uid = "org.lwjgl";
|
|
||||||
file->requires.insert(needsLwjgl);
|
|
||||||
|
|
||||||
if(!ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), mcJson))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(!QFile::rename(sourceFile, sourceFile + ".old"))
|
|
||||||
{
|
|
||||||
qWarning() << "Couldn't rename" << sourceFile << "to" << sourceFile + ".old" << "in" << instanceName;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Migrate old layout to the component based one...
|
|
||||||
* - Part of the version information is taken from `instance.cfg` (fed to this class from outside).
|
|
||||||
* - Part is taken from the old order.json file.
|
|
||||||
* - Part is loaded from loose json files in the instance's `patches` directory.
|
|
||||||
*/
|
|
||||||
bool PackProfile::migratePreComponentConfig()
|
|
||||||
{
|
|
||||||
// upgrade the very old files from the beginnings of MultiMC 5
|
|
||||||
upgradeDeprecatedFiles(d->m_instance->instanceRoot(), d->m_instance->name());
|
|
||||||
|
|
||||||
QList<ComponentPtr> components;
|
|
||||||
QSet<QString> loaded;
|
|
||||||
|
|
||||||
auto addBuiltinPatch = [&](const QString &uid, bool asDependency, const QString & emptyVersion, const Meta::Require & req, const Meta::Require & conflict)
|
|
||||||
{
|
|
||||||
auto jsonFilePath = FS::PathCombine(d->m_instance->instanceRoot(), "patches" , uid + ".json");
|
|
||||||
auto intendedVersion = d->getOldConfigVersion(uid);
|
|
||||||
// load up the base minecraft patch
|
|
||||||
ComponentPtr component;
|
|
||||||
if(QFile::exists(jsonFilePath))
|
|
||||||
{
|
|
||||||
if(intendedVersion.isEmpty())
|
|
||||||
{
|
|
||||||
intendedVersion = emptyVersion;
|
|
||||||
}
|
|
||||||
auto file = ProfileUtils::parseJsonFile(QFileInfo(jsonFilePath), false);
|
|
||||||
// fix uid
|
|
||||||
file->uid = uid;
|
|
||||||
// if version is missing, add it from the outside.
|
|
||||||
if(file->version.isEmpty())
|
|
||||||
{
|
|
||||||
file->version = intendedVersion;
|
|
||||||
}
|
|
||||||
// if this is a dependency (LWJGL), mark it also as volatile
|
|
||||||
if(asDependency)
|
|
||||||
{
|
|
||||||
file->m_volatile = true;
|
|
||||||
}
|
|
||||||
// insert requirements if needed
|
|
||||||
if(!req.uid.isEmpty())
|
|
||||||
{
|
|
||||||
file->requires.insert(req);
|
|
||||||
}
|
|
||||||
// insert conflicts if needed
|
|
||||||
if(!conflict.uid.isEmpty())
|
|
||||||
{
|
|
||||||
file->conflicts.insert(conflict);
|
|
||||||
}
|
|
||||||
// FIXME: @QUALITY do not ignore return value
|
|
||||||
ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), jsonFilePath);
|
|
||||||
component = new Component(this, uid, file);
|
|
||||||
component->m_version = intendedVersion;
|
|
||||||
}
|
|
||||||
else if(!intendedVersion.isEmpty())
|
|
||||||
{
|
|
||||||
auto metaVersion = APPLICATION->metadataIndex()->get(uid, intendedVersion);
|
|
||||||
component = new Component(this, metaVersion);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
component->m_dependencyOnly = asDependency;
|
|
||||||
component->m_important = !asDependency;
|
|
||||||
components.append(component);
|
|
||||||
};
|
|
||||||
// TODO: insert depends and conflicts here if these are customized files...
|
|
||||||
Meta::Require reqLwjgl;
|
|
||||||
reqLwjgl.uid = "org.lwjgl";
|
|
||||||
reqLwjgl.suggests = "2.9.1";
|
|
||||||
Meta::Require conflictLwjgl3;
|
|
||||||
conflictLwjgl3.uid = "org.lwjgl3";
|
|
||||||
Meta::Require nullReq;
|
|
||||||
addBuiltinPatch("org.lwjgl", true, "2.9.1", nullReq, conflictLwjgl3);
|
|
||||||
addBuiltinPatch("net.minecraft", false, QString(), reqLwjgl, nullReq);
|
|
||||||
|
|
||||||
// first, collect all other file-based patches and load them
|
|
||||||
QMap<QString, ComponentPtr> loadedComponents;
|
|
||||||
QDir patchesDir(FS::PathCombine(d->m_instance->instanceRoot(),"patches"));
|
|
||||||
for (auto info : patchesDir.entryInfoList(QStringList() << "*.json", QDir::Files))
|
|
||||||
{
|
|
||||||
// parse the file
|
|
||||||
qDebug() << "Reading" << info.fileName();
|
|
||||||
auto file = ProfileUtils::parseJsonFile(info, true);
|
|
||||||
|
|
||||||
// correct missing or wrong uid based on the file name
|
|
||||||
QString uid = info.completeBaseName();
|
|
||||||
|
|
||||||
// ignore builtins, they've been handled already
|
|
||||||
if (uid == "net.minecraft")
|
|
||||||
continue;
|
|
||||||
if (uid == "org.lwjgl")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// handle horrible corner cases
|
|
||||||
if(uid.isEmpty())
|
|
||||||
{
|
|
||||||
// if you have a file named '.json', make it just go away.
|
|
||||||
// FIXME: @QUALITY do not ignore return value
|
|
||||||
QFile::remove(info.absoluteFilePath());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
file->uid = uid;
|
|
||||||
// FIXME: @QUALITY do not ignore return value
|
|
||||||
ProfileUtils::saveJsonFile(OneSixVersionFormat::versionFileToJson(file), info.absoluteFilePath());
|
|
||||||
|
|
||||||
auto component = new Component(this, file->uid, file);
|
|
||||||
auto version = d->getOldConfigVersion(file->uid);
|
|
||||||
if(!version.isEmpty())
|
|
||||||
{
|
|
||||||
component->m_version = version;
|
|
||||||
}
|
|
||||||
loadedComponents[file->uid] = component;
|
|
||||||
}
|
|
||||||
// try to load the other 'hardcoded' patches (forge, liteloader), if they weren't loaded from files
|
|
||||||
auto loadSpecial = [&](const QString & uid, int order)
|
|
||||||
{
|
|
||||||
auto patchVersion = d->getOldConfigVersion(uid);
|
|
||||||
if(!patchVersion.isEmpty() && !loadedComponents.contains(uid))
|
|
||||||
{
|
|
||||||
auto patch = new Component(this, APPLICATION->metadataIndex()->get(uid, patchVersion));
|
|
||||||
patch->setOrder(order);
|
|
||||||
loadedComponents[uid] = patch;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
loadSpecial("net.minecraftforge", 5);
|
|
||||||
loadSpecial("com.mumfrey.liteloader", 10);
|
|
||||||
|
|
||||||
// load the old order.json file, if present
|
|
||||||
ProfileUtils::PatchOrder userOrder;
|
|
||||||
ProfileUtils::readOverrideOrders(FS::PathCombine(d->m_instance->instanceRoot(), "order.json"), userOrder);
|
|
||||||
|
|
||||||
// now add all the patches by user sort order
|
|
||||||
for (auto uid : userOrder)
|
|
||||||
{
|
|
||||||
// ignore builtins
|
|
||||||
if (uid == "net.minecraft")
|
|
||||||
continue;
|
|
||||||
if (uid == "org.lwjgl")
|
|
||||||
continue;
|
|
||||||
// ordering has a patch that is gone?
|
|
||||||
if(!loadedComponents.contains(uid))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
components.append(loadedComponents.take(uid));
|
|
||||||
}
|
|
||||||
|
|
||||||
// is there anything left to sort? - this is used when there are leftover components that aren't part of the order.json
|
|
||||||
if(!loadedComponents.isEmpty())
|
|
||||||
{
|
|
||||||
// inserting into multimap by order number as key sorts the patches and detects duplicates
|
|
||||||
QMultiMap<int, ComponentPtr> files;
|
|
||||||
auto iter = loadedComponents.begin();
|
|
||||||
while(iter != loadedComponents.end())
|
|
||||||
{
|
|
||||||
files.insert((*iter)->getOrder(), *iter);
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// then just extract the patches and put them in the list
|
|
||||||
for (auto order : files.keys())
|
|
||||||
{
|
|
||||||
const auto &values = files.values(order);
|
|
||||||
for(auto &value: values)
|
|
||||||
{
|
|
||||||
// TODO: put back the insertion of problem messages here, so the user knows about the id duplication
|
|
||||||
components.append(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// new we have a complete list of components...
|
|
||||||
return savePackProfile(componentsFilePath(), components);
|
|
||||||
}
|
|
||||||
|
|
||||||
// END: save/load
|
// END: save/load
|
||||||
|
|
||||||
void PackProfile::appendComponent(ComponentPtr component)
|
void PackProfile::appendComponent(ComponentPtr component)
|
||||||
@ -1169,15 +924,6 @@ std::shared_ptr<LaunchProfile> PackProfile::getProfile() const
|
|||||||
return d->m_profile;
|
return d->m_profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackProfile::setOldConfigVersion(const QString& uid, const QString& version)
|
|
||||||
{
|
|
||||||
if(version.isEmpty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
d->m_oldConfigVersions[uid] = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PackProfile::setComponentVersion(const QString& uid, const QString& version, bool important)
|
bool PackProfile::setComponentVersion(const QString& uid, const QString& version, bool important)
|
||||||
{
|
{
|
||||||
auto iter = d->componentIndex.find(uid);
|
auto iter = d->componentIndex.find(uid);
|
||||||
|
@ -143,8 +143,6 @@ private:
|
|||||||
bool installCustomJar_internal(QString filepath);
|
bool installCustomJar_internal(QString filepath);
|
||||||
bool removeComponent_internal(ComponentPtr patch);
|
bool removeComponent_internal(ComponentPtr patch);
|
||||||
|
|
||||||
bool migratePreComponentConfig();
|
|
||||||
|
|
||||||
private: /* data */
|
private: /* data */
|
||||||
|
|
||||||
std::unique_ptr<PackProfileData> d;
|
std::unique_ptr<PackProfileData> d;
|
||||||
|
@ -18,18 +18,6 @@ struct PackProfileData
|
|||||||
// the launch profile (volatile, temporary thing created on demand)
|
// the launch profile (volatile, temporary thing created on demand)
|
||||||
std::shared_ptr<LaunchProfile> m_profile;
|
std::shared_ptr<LaunchProfile> m_profile;
|
||||||
|
|
||||||
// version information migrated from instance.cfg file. Single use on migration!
|
|
||||||
std::map<QString, QString> m_oldConfigVersions;
|
|
||||||
QString getOldConfigVersion(const QString& uid) const
|
|
||||||
{
|
|
||||||
const auto iter = m_oldConfigVersions.find(uid);
|
|
||||||
if(iter != m_oldConfigVersions.cend())
|
|
||||||
{
|
|
||||||
return (*iter).second;
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// persistent list of components and related machinery
|
// persistent list of components and related machinery
|
||||||
ComponentContainer components;
|
ComponentContainer components;
|
||||||
ComponentIndex componentIndex;
|
ComponentIndex componentIndex;
|
||||||
|
Loading…
Reference in New Issue
Block a user