summaryrefslogtreecommitdiffstats
path: root/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'api/logic/minecraft/onesix/OneSixProfileStrategy.cpp')
-rw-r--r--api/logic/minecraft/onesix/OneSixProfileStrategy.cpp226
1 files changed, 104 insertions, 122 deletions
diff --git a/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp b/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp
index 07c9f075..d3e137c7 100644
--- a/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp
+++ b/api/logic/minecraft/onesix/OneSixProfileStrategy.cpp
@@ -3,7 +3,6 @@
#include "OneSixVersionFormat.h"
#include "minecraft/VersionBuildError.h"
-#include "minecraft/MinecraftVersionList.h"
#include "Env.h"
#include <FileSystem.h>
@@ -11,6 +10,12 @@
#include <QUuid>
#include <QJsonDocument>
#include <QJsonArray>
+#include <QSaveFile>
+#include <QResource>
+#include <meta/Index.h>
+#include <meta/Version.h>
+
+#include <tuple>
OneSixProfileStrategy::OneSixProfileStrategy(OneSixInstance* instance)
{
@@ -53,7 +58,7 @@ void OneSixProfileStrategy::upgradeDeprecatedFiles()
}
auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false);
ProfileUtils::removeLwjglFromPatch(file);
- file->fileId = "net.minecraft";
+ file->uid = "net.minecraft";
file->version = file->minecraftVersion;
file->name = "Minecraft";
auto data = OneSixVersionFormat::versionFileToJson(file, false).toJson();
@@ -80,156 +85,128 @@ void OneSixProfileStrategy::upgradeDeprecatedFiles()
void OneSixProfileStrategy::loadDefaultBuiltinPatches()
{
+ auto addBuiltinPatch = [&](const QString &uid, const QString intendedVersion, int order)
{
- auto mcJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
+ auto jsonFilePath = FS::PathCombine(m_instance->instanceRoot(), "patches" , uid + ".json");
// load up the base minecraft patch
- ProfilePatchPtr minecraftPatch;
- if(QFile::exists(mcJson))
+ ProfilePatchPtr profilePatch;
+ if(QFile::exists(jsonFilePath))
{
- auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false);
+ auto file = ProfileUtils::parseJsonFile(QFileInfo(jsonFilePath), false);
if(file->version.isEmpty())
{
- file->version = m_instance->intendedVersionId();
+ file->version = intendedVersion;
}
- file->setVanilla(false);
- file->setRevertible(true);
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
+ profilePatch = std::make_shared<ProfilePatch>(file, jsonFilePath);
+ profilePatch->setVanilla(false);
+ profilePatch->setRevertible(true);
}
else
{
- auto mcversion = ENV.getVersion("net.minecraft", m_instance->intendedVersionId());
- minecraftPatch = std::dynamic_pointer_cast<ProfilePatch>(mcversion);
+ auto metaVersion = ENV.metadataIndex()->get(uid, intendedVersion);
+ profilePatch = std::make_shared<ProfilePatch>(metaVersion);
+ profilePatch->setVanilla(true);
}
- if (!minecraftPatch)
+ if (!profilePatch)
{
- throw VersionIncomplete("net.minecraft");
+ throw VersionIncomplete(uid);
}
- minecraftPatch->setOrder(-2);
- profile->appendPatch(minecraftPatch);
- }
+ profilePatch->setOrder(order);
+ profile->appendPatch(profilePatch);
+ };
+ addBuiltinPatch("net.minecraft", m_instance->getComponentVersion("net.minecraft"), -2);
+ addBuiltinPatch("org.lwjgl", m_instance->getComponentVersion("org.lwjgl"), -1);
+}
+void OneSixProfileStrategy::loadUserPatches()
+{
+ // first, collect all patches (that are not builtins of OneSix) and load them
+ QMap<QString, ProfilePatchPtr> loadedPatches;
+ QDir patchesDir(FS::PathCombine(m_instance->instanceRoot(),"patches"));
+ for (auto info : patchesDir.entryInfoList(QStringList() << "*.json", QDir::Files))
{
- auto lwjglJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "org.lwjgl.json");
- ProfilePatchPtr lwjglPatch;
- if(QFile::exists(lwjglJson))
- {
- auto file = ProfileUtils::parseJsonFile(QFileInfo(lwjglJson), false);
- file->setVanilla(false);
- file->setRevertible(true);
- lwjglPatch = std::dynamic_pointer_cast<ProfilePatch>(file);
- }
- else
+ // parse the file
+ qDebug() << "Reading" << info.fileName();
+ auto file = ProfileUtils::parseJsonFile(info, true);
+ // ignore builtins
+ if (file->uid == "net.minecraft")
+ continue;
+ if (file->uid == "org.lwjgl")
+ continue;
+ auto patch = std::make_shared<ProfilePatch>(file, info.filePath());
+ patch->setRemovable(true);
+ patch->setMovable(true);
+ if(ENV.metadataIndex()->hasUid(file->uid))
{
- // NOTE: this is obviously fake, is fixed in unstable.
- QResource LWJGL(":/versions/LWJGL/2.9.1.json");
- auto lwjgl = ProfileUtils::parseJsonFile(LWJGL.absoluteFilePath(), false);
- lwjgl->setVanilla(true);
- lwjgl->setCustomizable(true);
- lwjglPatch = std::dynamic_pointer_cast<ProfilePatch>(lwjgl);
+ // FIXME: requesting a uid/list creates it in the index... this allows reverting to possibly invalid versions...
+ patch->setRevertible(true);
}
- if (!lwjglPatch)
+ loadedPatches[file->uid] = patch;
+ }
+ // these are 'special'... if not already loaded from instance files, grab them from the metadata repo.
+ auto loadSpecial = [&](const QString & uid, int order)
+ {
+ auto patchVersion = m_instance->getComponentVersion(uid);
+ if(!patchVersion.isEmpty() && !loadedPatches.contains(uid))
{
- throw VersionIncomplete("org.lwjgl");
+ auto patch = std::make_shared<ProfilePatch>(ENV.metadataIndex()->get(uid, patchVersion));
+ patch->setOrder(order);
+ patch->setVanilla(true);
+ patch->setRemovable(true);
+ patch->setMovable(true);
+ loadedPatches[uid] = patch;
}
- lwjglPatch->setOrder(-1);
- profile->appendPatch(lwjglPatch);
- }
-}
+ };
+ loadSpecial("net.minecraftforge", 5);
+ loadSpecial("com.mumfrey.liteloader", 10);
-void OneSixProfileStrategy::loadUserPatches()
-{
- // load all patches, put into map for ordering, apply in the right order
+ // now add all the patches by user sort order
ProfileUtils::PatchOrder userOrder;
ProfileUtils::readOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), userOrder);
- QDir patches(FS::PathCombine(m_instance->instanceRoot(),"patches"));
- QSet<QString> seen_extra;
-
- // first, load things by sort order.
- for (auto id : userOrder)
+ bool orderIsDirty = false;
+ for (auto uid : userOrder)
{
// ignore builtins
- if (id == "net.minecraft")
+ if (uid == "net.minecraft")
continue;
- if (id == "org.lwjgl")
+ if (uid == "org.lwjgl")
continue;
- // parse the file
- QString filename = patches.absoluteFilePath(id + ".json");
- QFileInfo finfo(filename);
- if(!finfo.exists())
+ // ordering has a patch that is gone?
+ if(!loadedPatches.contains(uid))
{
- qDebug() << "Patch file " << filename << " was deleted by external means...";
+ orderIsDirty = true;
continue;
}
- qDebug() << "Reading" << filename << "by user order";
- VersionFilePtr file = ProfileUtils::parseJsonFile(finfo, false);
- // sanity check. prevent tampering with files.
- if (file->fileId != id)
- {
- file->addProblem(PROBLEM_WARNING, QObject::tr("load id %1 does not match internal id %2").arg(id, file->fileId));
- seen_extra.insert(file->fileId);
- }
- file->setRemovable(true);
- file->setMovable(true);
- // HACK: ignore assets from other version files than Minecraft
- // workaround for stupid assets issue caused by amazon:
- // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
- file->assets = QString();
- file->mojangAssetIndex.reset();
- // HACK
- profile->appendPatch(file);
+ profile->appendPatch(loadedPatches.take(uid));
}
- // now load the rest by internal preference.
- QMultiMap<int, VersionFilePtr> files;
- for (auto info : patches.entryInfoList(QStringList() << "*.json", QDir::Files))
+
+ // is there anything left to sort?
+ if(loadedPatches.isEmpty())
{
- // parse the file
- qDebug() << "Reading" << info.fileName();
- auto file = ProfileUtils::parseJsonFile(info, true);
- // ignore builtins
- if (file->fileId == "net.minecraft")
- continue;
- if (file->fileId == "org.lwjgl")
- continue;
- // do not load versions with broken IDs twice
- if(seen_extra.contains(file->fileId))
- continue;
- // do not load what we already loaded in the first pass
- if (userOrder.contains(file->fileId))
- continue;
- file->setRemovable(true);
- file->setMovable(true);
- // HACK: ignore assets from other version files than Minecraft
- // workaround for stupid assets issue caused by amazon:
- // https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
- file->assets = QString();
- file->mojangAssetIndex.reset();
- // HACK
- files.insert(file->order, file);
+ // TODO: save the order here?
+ return;
+ }
+
+ // inserting into multimap by order number as key sorts the patches and detects duplicates
+ QMultiMap<int, ProfilePatchPtr> files;
+ auto iter = loadedPatches.begin();
+ while(iter != loadedPatches.end())
+ {
+ files.insert((*iter)->getOrder(), *iter);
+ iter++;
}
- QSet<int> seen;
+
+ // then just extract the patches and put them in the list
for (auto order : files.keys())
{
- if(seen.contains(order))
- continue;
- seen.insert(order);
const auto &values = files.values(order);
- if(values.size() == 1)
- {
- profile->appendPatch(values[0]);
- continue;
- }
- for(auto &file: values)
+ for(auto &value: values)
{
- QStringList list;
- for(auto &file2: values)
- {
- if(file != file2)
- list.append(file2->name);
- }
- file->addProblem(PROBLEM_WARNING, QObject::tr("%1 has the same order as the following components:\n%2").arg(file->name, list.join(", ")));
- profile->appendPatch(file);
+ // TODO: put back the insertion of problem messages here, so the user knows about the id duplication
+ profile->appendPatch(value);
}
}
+ // TODO: save the order here?
}
@@ -266,7 +243,10 @@ bool OneSixProfileStrategy::removePatch(ProfilePatchPtr patch)
return false;
}
}
-
+ if(!m_instance->getComponentVersion(patch->getID()).isEmpty())
+ {
+ m_instance->setComponentVersion(patch->getID(), QString());
+ }
auto preRemoveJarMod = [&](JarmodPtr jarMod) -> bool
{
@@ -285,7 +265,8 @@ bool OneSixProfileStrategy::removePatch(ProfilePatchPtr patch)
return true;
};
- for(auto &jarmod: patch->getJarMods())
+ auto &jarMods = patch->getVersionFile()->jarMods;
+ for(auto &jarmod: jarMods)
{
ok &= preRemoveJarMod(jarmod);
}
@@ -405,12 +386,9 @@ bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
jarMod->originalName = sourceInfo.completeBaseName();
f->jarMods.append(jarMod);
f->name = target_name;
- f->fileId = target_id;
+ f->uid = target_id;
f->order = profile->getFreeOrderNumber();
QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
- f->filename = patchFileName;
- f->setMovable(true);
- f->setRemovable(true);
QFile file(patchFileName);
if (!file.open(QFile::WriteOnly))
@@ -421,7 +399,11 @@ bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
}
file.write(OneSixVersionFormat::versionFileToJson(f, true).toJson());
file.close();
- profile->appendPatch(f);
+
+ auto patch = std::make_shared<ProfilePatch>(f, patchFileName);
+ patch->setMovable(true);
+ patch->setRemovable(true);
+ profile->appendPatch(patch);
}
profile->saveCurrentOrder();
profile->reapplyPatches();