From c39d26f4453166603749826eee1a732c815047d0 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Wed, 22 Jan 2014 22:15:50 +0100 Subject: Got liteloader working. Patching more or less works --- logic/DerpRule.cpp | 2 +- logic/DerpRule.h | 2 +- logic/DerpVersionBuilder.cpp | 246 +++++++++++++++++++++++++++++++++--------- logic/DerpVersionBuilder.h | 8 ++ logic/LiteLoaderInstaller.cpp | 4 +- 5 files changed, 208 insertions(+), 54 deletions(-) (limited to 'logic') diff --git a/logic/DerpRule.cpp b/logic/DerpRule.cpp index d4cf1ba3..5ed200e3 100644 --- a/logic/DerpRule.cpp +++ b/logic/DerpRule.cpp @@ -18,7 +18,7 @@ #include "DerpRule.h" -QList> rulesFromJsonV4(QJsonObject &objectWithRules) +QList> rulesFromJsonV4(const QJsonObject &objectWithRules) { QList> rules; auto rulesVal = objectWithRules.value("rules"); diff --git a/logic/DerpRule.h b/logic/DerpRule.h index 7895ea98..0254028c 100644 --- a/logic/DerpRule.h +++ b/logic/DerpRule.h @@ -27,7 +27,7 @@ enum RuleAction }; RuleAction RuleAction_fromString(QString); -QList> rulesFromJsonV4(QJsonObject &objectWithRules); +QList> rulesFromJsonV4(const QJsonObject &objectWithRules); class Rule { diff --git a/logic/DerpVersionBuilder.cpp b/logic/DerpVersionBuilder.cpp index b0da8205..eb215cca 100644 --- a/logic/DerpVersionBuilder.cpp +++ b/logic/DerpVersionBuilder.cpp @@ -113,12 +113,23 @@ bool DerpVersionBuilder::build() return true; } -void applyString(const QJsonObject &obj, const QString &key, QString &out) +void applyString(const QJsonObject &obj, const QString &key, QString &out, const bool onlyOverride = true) { if (obj.contains(key) && obj.value(key).isString()) { out = obj.value(key).toString(); } + else if (!onlyOverride) + { + if (obj.contains("+" + key) && obj.value("+" + key).isString()) + { + out += obj.value("+" + key).toString(); + } + else if (obj.contains("-" + key) && obj.value("-" + key).isString()) + { + out.remove(obj.value("-" + key).toString()); + } + } } void applyString(const QJsonObject &obj, const QString &key, std::shared_ptr lib, void(DerpLibrary::*func)(const QString &val)) { @@ -131,7 +142,7 @@ bool DerpVersionBuilder::apply(const QJsonObject &object) { applyString(object, "id", m_version->id); applyString(object, "mainClass", m_version->mainClass); - applyString(object, "processArguments", m_version->processArguments); + applyString(object, "processArguments", m_version->processArguments, false); { const QString toCompare = m_version->processArguments.toLower(); if (toCompare == "legacy") @@ -147,7 +158,7 @@ bool DerpVersionBuilder::apply(const QJsonObject &object) m_version->minecraftArguments = "--username ${auth_player_name} --session ${auth_session} --version ${profile_name}"; } } - applyString(object, "minecraftArguments", m_version->minecraftArguments); + applyString(object, "minecraftArguments", m_version->minecraftArguments, false); applyString(object, "type", m_version->type); applyString(object, "releaseTime", m_version->releaseTime); applyString(object, "time", m_version->time); @@ -170,80 +181,215 @@ bool DerpVersionBuilder::apply(const QJsonObject &object) // libraries if (object.contains("libraries")) { + m_version->libraries.clear(); auto librariesValue = object.value("libraries"); if (!librariesValue.isArray()) { QMessageBox::critical(m_widgetParent, QObject::tr("Error"), QObject::tr("One json files contains a libraries field, but it's not an array")); return false; } + auto array = librariesValue.toArray(); + for (auto libVal : array) + { + if (libVal.isObject()) + { + if (!applyLibrary(libVal.toObject(), Override)) + { + return false; + } + } + + } + } + + // +libraries + if (object.contains("+libraries")) + { + auto librariesValue = object.value("+libraries"); + if (!librariesValue.isArray()) + { + QMessageBox::critical(m_widgetParent, QObject::tr("Error"), QObject::tr("One json files contains a libraries field, but it's not an array")); + return false; + } for (auto libVal : librariesValue.toArray()) { - if (!libVal.isObject()) + if (libVal.isObject()) { - continue; + applyLibrary(libVal.toObject(), Add); } - QJsonObject libObj = libVal.toObject(); + } + } - // Library name - auto nameVal = libObj.value("name"); - if (!nameVal.isString()) + // -libraries + if (object.contains("-libraries")) + { + auto librariesValue = object.value("-libraries"); + if (!librariesValue.isArray()) + { + QMessageBox::critical(m_widgetParent, QObject::tr("Error"), QObject::tr("One json files contains a libraries field, but it's not an array")); + return false; + } + for (auto libVal : librariesValue.toArray()) + { + if (libVal.isObject()) { - continue; + applyLibrary(libVal.toObject(), Remove); } - std::shared_ptr library(new DerpLibrary(nameVal.toString())); - applyString(libObj, "url", library, &DerpLibrary::setBaseUrl); - applyString(libObj, "MMC-hint", library, &DerpLibrary::setHint); - applyString(libObj, "MMC-absulute_url", library, &DerpLibrary::setAbsoluteUrl); - applyString(libObj, "MMC-absoluteUrl", library, &DerpLibrary::setAbsoluteUrl); + } + } + + return true; +} + +int findLibrary(QList > haystack, const QString &needle) +{ + for (int i = 0; i < haystack.size(); ++i) + { + if (QRegExp(needle, Qt::CaseSensitive, QRegExp::WildcardUnix).indexIn(haystack.at(i)->rawName()) != -1) + { + return i; + } + } + return -1; +} + +bool DerpVersionBuilder::applyLibrary(const QJsonObject &lib, const DerpVersionBuilder::Type type) +{ + // Library name + auto nameVal = lib.value("name"); + if (!nameVal.isString()) + { + return false; + } + auto name = nameVal.toString(); - auto extractVal = libObj.value("extract"); - if (extractVal.isObject()) + if (type == Remove) + { + int index = findLibrary(m_version->libraries, name); + if (index >= 0) + { + m_version->libraries.removeAt(index); + } + return true; + } + + if (type == Add && !lib.contains("insert")) + { + return false; + } + + std::shared_ptr library; + + if (lib.value("insert").toString() == "apply" && type == Add) + { + library = m_version->libraries[findLibrary(m_version->libraries, name)]; + } + else + { + library.reset(new DerpLibrary(nameVal.toString())); + } + + applyString(lib, "url", library, &DerpLibrary::setBaseUrl); + applyString(lib, "MMC-hint", library, &DerpLibrary::setHint); + applyString(lib, "MMC-absulute_url", library, &DerpLibrary::setAbsoluteUrl); + applyString(lib, "MMC-absoluteUrl", library, &DerpLibrary::setAbsoluteUrl); + + auto extractVal = lib.value("extract"); + if (extractVal.isObject()) + { + QStringList excludes; + auto extractObj = extractVal.toObject(); + auto excludesVal = extractObj.value("exclude"); + if (excludesVal.isArray()) + { + auto excludesList = excludesVal.toArray(); + for (auto excludeVal : excludesList) { - QStringList excludes; - auto extractObj = extractVal.toObject(); - auto excludesVal = extractObj.value("exclude"); - if (excludesVal.isArray()) + if (excludeVal.isString()) { - auto excludesList = excludesVal.toArray(); - for (auto excludeVal : excludesList) - { - if (excludeVal.isString()) - { - excludes.append(excludeVal.toString()); - } - } - library->extract_excludes = excludes; + excludes.append(excludeVal.toString()); } } + library->extract_excludes = excludes; + } + } - auto nativesVal = libObj.value("natives"); - if (nativesVal.isObject()) + auto nativesVal = lib.value("natives"); + if (nativesVal.isObject()) + { + library->setIsNative(); + auto nativesObj = nativesVal.toObject(); + for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it) + { + auto osType = OpSys_fromString(it.key()); + if (osType == Os_Other) { - library->setIsNative(); - auto nativesObj = nativesVal.toObject(); - for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it) - { - auto osType = OpSys_fromString(it.key()); - if (osType == Os_Other) - { - continue; - } - if (!it.value().isString()) - { - continue; - } - library->addNative(osType, it.value().toString()); - } + continue; + } + if (!it.value().isString()) + { + continue; } + library->addNative(osType, it.value().toString()); + } + } - library->setRules(rulesFromJsonV4(libObj)); - library->finalize(); + if (lib.contains("rules")) + { + library->setRules(rulesFromJsonV4(lib)); + } + library->finalize(); + if (type == Override) + { + qDebug() << "appending" << library->rawName(); + m_version->libraries.append(library); + } + else if (lib.value("insert").toString() != "apply") + { + if (lib.value("insert").toString() == "append") + { m_version->libraries.append(library); } + else if (lib.value("insert").toString() == "prepend") + { + m_version->libraries.prepend(library); + } + else if (lib.value("insert").isObject()) + { + QJsonObject insertObj = lib.value("insert").toObject(); + if (insertObj.isEmpty()) + { + QMessageBox::critical(m_widgetParent, QObject::tr("Error"), QObject::tr("'insert' object empty")); + return false; + } + const QString key = insertObj.keys().first(); + const QString value = insertObj.value(key).toString(); + const int index = findLibrary(m_version->libraries, value); + if (index >= 0) + { + if (key == "before") + { + m_version->libraries.insert(index, library); + } + else if (key == "after") + { + m_version->libraries.insert(index + 1, library); + } + else + { + QMessageBox::critical(m_widgetParent, QObject::tr("Error"), QObject::tr("Invalid value for 'insert': %1").arg(lib.value("insert").toString())); + return false; + } + } + } + else + { + QMessageBox::critical(m_widgetParent, QObject::tr("Error"), QObject::tr("Invalid value for 'insert': %1").arg(lib.value("insert").toString())); + return false; + } } - return true; } diff --git a/logic/DerpVersionBuilder.h b/logic/DerpVersionBuilder.h index 739065db..5354cb0e 100644 --- a/logic/DerpVersionBuilder.h +++ b/logic/DerpVersionBuilder.h @@ -34,10 +34,18 @@ private: DerpInstance *m_instance; QWidget *m_widgetParent; + enum Type + { + Override, + Add, + Remove + }; + bool build(); void clear(); bool apply(const QJsonObject &object); + bool applyLibrary(const QJsonObject &lib, const Type type); bool read(const QFileInfo &fileInfo, QJsonObject *out); }; diff --git a/logic/LiteLoaderInstaller.cpp b/logic/LiteLoaderInstaller.cpp index 8aed47e7..d582f03a 100644 --- a/logic/LiteLoaderInstaller.cpp +++ b/logic/LiteLoaderInstaller.cpp @@ -75,7 +75,7 @@ bool LiteLoaderInstaller::add(DerpInstance *to) DerpLibrary launchwrapperLib("net.minecraft:launchwrapper:" + m_launcherWrapperVersionMapping[to->intendedVersionId()]); launchwrapperLib.finalize(); QJsonObject lwLibObj = launchwrapperLib.toJson(); - lwLibObj.insert("insert", QString("beginning")); + lwLibObj.insert("insert", QString("prepend")); libraries.append(lwLibObj); } @@ -85,7 +85,7 @@ bool LiteLoaderInstaller::add(DerpInstance *to) liteloaderLib.setBaseUrl("http://dl.liteloader.com/versions/"); liteloaderLib.finalize(); QJsonObject llLibObj = liteloaderLib.toJson(); - llLibObj.insert("insert", QString("beginning")); + llLibObj.insert("insert", QString("prepend")); libraries.append(llLibObj); } -- cgit v1.2.3