From 9497b7e96cfac6e60a53fe05c0ca945ecc839533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 28 Feb 2016 19:01:54 +0100 Subject: NOISSUE even more version file refactors There is no end to them in sight --- logic/CMakeLists.txt | 1 - logic/Json.h | 27 --- logic/minecraft/JarMod.cpp | 27 --- logic/minecraft/JarMod.h | 4 - logic/minecraft/MinecraftVersionList.cpp | 4 +- logic/minecraft/MojangVersionFormat.cpp | 64 ++++++- logic/minecraft/MojangVersionFormat.h | 12 +- logic/minecraft/ProfileUtils.cpp | 4 +- logic/minecraft/RawLibrary.cpp | 117 ------------- logic/minecraft/RawLibrary.h | 8 +- logic/minecraft/forge/ForgeInstaller.cpp | 6 +- logic/minecraft/liteloader/LiteLoaderInstaller.cpp | 5 +- .../minecraft/liteloader/LiteLoaderVersionList.cpp | 3 +- logic/minecraft/onesix/OneSixProfileStrategy.cpp | 6 +- logic/minecraft/onesix/OneSixVersionFormat.cpp | 194 +++++++++++++++++++-- logic/minecraft/onesix/OneSixVersionFormat.h | 24 ++- 16 files changed, 290 insertions(+), 216 deletions(-) delete mode 100644 logic/minecraft/JarMod.cpp diff --git a/logic/CMakeLists.txt b/logic/CMakeLists.txt index 89c25729..fe827f5f 100644 --- a/logic/CMakeLists.txt +++ b/logic/CMakeLists.txt @@ -178,7 +178,6 @@ set(LOGIC_SOURCES minecraft/MinecraftProfile.h minecraft/MojangVersionFormat.cpp minecraft/MojangVersionFormat.h - minecraft/JarMod.cpp minecraft/JarMod.h minecraft/MinecraftInstance.cpp minecraft/MinecraftInstance.h diff --git a/logic/Json.h b/logic/Json.h index d13230b8..cb266c6e 100644 --- a/logic/Json.h +++ b/logic/Json.h @@ -48,33 +48,6 @@ MULTIMC_LOGIC_EXPORT QJsonArray requireArray(const QJsonDocument &doc, const QSt void writeString(QJsonObject & to, const QString &key, const QString &value); void writeStringList(QJsonObject & to, const QString &key, const QStringList &values); -template -void writeObjectList(QJsonObject & to, QString key, QList> values) -{ - if (!values.isEmpty()) - { - QJsonArray array; - for (auto value: values) - { - array.append(value->toJson()); - } - to.insert(key, array); - } -} -template -void writeObjectList(QJsonObject & to, QString key, QList values) -{ - if (!values.isEmpty()) - { - QJsonArray array; - for (auto value: values) - { - array.append(value.toJson()); - } - to.insert(key, array); - } -} - template QJsonValue toJson(const T &t) { diff --git a/logic/minecraft/JarMod.cpp b/logic/minecraft/JarMod.cpp deleted file mode 100644 index bf985707..00000000 --- a/logic/minecraft/JarMod.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "JarMod.h" -#include "Json.h" -using namespace Json; - -JarmodPtr Jarmod::fromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName) -{ - JarmodPtr out(new Jarmod()); - if (!libObj.contains("name")) - { - throw JSONValidationError(filename + - "contains a jarmod that doesn't have a 'name' field"); - } - out->name = libObj.value("name").toString(); - out->originalName = libObj.value("originalName").toString(); - return out; -} - -QJsonObject Jarmod::toJson() -{ - QJsonObject out; - writeString(out, "name", name); - if(!originalName.isEmpty()) - { - writeString(out, "originalName", originalName); - } - return out; -} diff --git a/logic/minecraft/JarMod.h b/logic/minecraft/JarMod.h index 461308f0..42d05da9 100644 --- a/logic/minecraft/JarMod.h +++ b/logic/minecraft/JarMod.h @@ -6,10 +6,6 @@ class Jarmod; typedef std::shared_ptr JarmodPtr; class Jarmod { -public: /* methods */ - static JarmodPtr fromJson(const QJsonObject &libObj, const QString &filename, - const QString &originalName); - QJsonObject toJson(); public: /* data */ QString name; QString originalName; diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp index 3e970bf7..578432cb 100644 --- a/logic/minecraft/MinecraftVersionList.cpp +++ b/logic/minecraft/MinecraftVersionList.cpp @@ -512,7 +512,7 @@ void MCVListVersionUpdateTask::json_downloaded() VersionFilePtr file; try { - file = MojangVersionFormat::fromJson(jsonDoc, "net.minecraft.json"); + file = MojangVersionFormat::versionFileFromJson(jsonDoc, "net.minecraft.json"); } catch (Exception &e) { @@ -528,7 +528,7 @@ void MCVListVersionUpdateTask::json_downloaded() file->fileId = "net.minecraft"; // now dump the file to disk - auto doc = OneSixVersionFormat::toJson(file, false); + auto doc = OneSixVersionFormat::profilePatchToJson(file, false); auto newdata = doc.toBinaryData(); auto id = updatedVersion->descriptor(); QString targetPath = "versions/" + id + "/" + id + ".dat"; diff --git a/logic/minecraft/MojangVersionFormat.cpp b/logic/minecraft/MojangVersionFormat.cpp index 7427156b..70a005c7 100644 --- a/logic/minecraft/MojangVersionFormat.cpp +++ b/logic/minecraft/MojangVersionFormat.cpp @@ -1,4 +1,7 @@ #include "MojangVersionFormat.h" +#include "onesix/OneSixVersionFormat.h" +#include "MinecraftVersion.h" +#include "VersionBuildError.h" #include "Json.h" using namespace Json; @@ -14,7 +17,7 @@ static void readString(const QJsonObject &root, const QString &key, QString &var } } -VersionFilePtr MojangVersionFormat::fromJson(const QJsonDocument &doc, const QString &filename) +VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename) { VersionFilePtr out(new VersionFile()); if (doc.isEmpty() || doc.isNull()) @@ -63,9 +66,66 @@ VersionFilePtr MojangVersionFormat::fromJson(const QJsonDocument &doc, const QSt { auto libObj = requireObject(libVal); - auto lib = RawLibrary::fromJson(libObj, filename); + auto lib = OneSixVersionFormat::libraryFromJson(libObj, filename); out->overwriteLibs.append(lib); } } return out; } +/* +static QJsonDocument versionFileToJson(VersionFilePtr patch) +{ + QJsonObject root; + writeString(root, "id", patch->id); + writeString(root, "mainClass", patch->mainClass); + writeString(root, "processArguments", patch->processArguments); + writeString(root, "minecraftArguments", patch->overwriteMinecraftArguments); + writeString(root, "type", patch->type); + writeString(root, "assets", patch->assets); + writeString(root, "releaseTime", patch->m_releaseTimeString); + writeString(root, "time", patch->m_updateTimeString); + + if (!patch->addLibs.isEmpty()) + { + QJsonArray array; + for (auto value: patch->addLibs) + { + array.append(OneSixVersionFormat::libraryToJson(value.get())); + } + root.insert("libraries", array); + } + // write the contents to a json document. + { + QJsonDocument out; + out.setObject(root); + return out; + } +} + +static QJsonDocument minecraftVersionToJson(MinecraftVersionPtr patch) +{ + if(patch->m_versionSource == Local && patch->getVersionFile()) + { + return MojangVersionFormat::profilePatchToJson(patch->getVersionFile()); + } + else + { + throw VersionIncomplete(QObject::tr("Can't write incomplete/builtin Minecraft version %1").arg(patch->name())); + } +} + +QJsonDocument MojangVersionFormat::profilePatchToJson(const ProfilePatchPtr &patch) +{ + auto vfile = std::dynamic_pointer_cast(patch); + if(vfile) + { + return versionFileToJson(vfile); + } + auto mversion = std::dynamic_pointer_cast(patch); + if(mversion) + { + return minecraftVersionToJson(mversion); + } + throw VersionIncomplete(QObject::tr("Unhandled object type while processing %1").arg(patch->getPatchName())); +} +*/ diff --git a/logic/minecraft/MojangVersionFormat.h b/logic/minecraft/MojangVersionFormat.h index 78bc1c42..da38bd62 100644 --- a/logic/minecraft/MojangVersionFormat.h +++ b/logic/minecraft/MojangVersionFormat.h @@ -3,6 +3,12 @@ #include #include -namespace MojangVersionFormat { - VersionFilePtr fromJson(const QJsonDocument &doc, const QString &filename); -} +class MojangVersionFormat +{ +public: + // version files / profile patches + static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename); + /* + static QJsonDocument profilePatchToJson(const ProfilePatchPtr &patch); + */ +}; diff --git a/logic/minecraft/ProfileUtils.cpp b/logic/minecraft/ProfileUtils.cpp index 995c2052..096f43bf 100644 --- a/logic/minecraft/ProfileUtils.cpp +++ b/logic/minecraft/ProfileUtils.cpp @@ -129,7 +129,7 @@ VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder) .arg(fileInfo.fileName(), error.errorString()) .arg(line).arg(column)); } - return OneSixVersionFormat::fromJson(doc, file.fileName(), requireOrder); + return OneSixVersionFormat::versionFileFromJson(doc, file.fileName(), requireOrder); } VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo) @@ -148,7 +148,7 @@ VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo) throw JSONValidationError( QObject::tr("Unable to process the version file %1.").arg(fileInfo.fileName())); } - return OneSixVersionFormat::fromJson(doc, file.fileName(), false); + return OneSixVersionFormat::versionFileFromJson(doc, file.fileName(), false); } void removeLwjglFromPatch(VersionFilePtr patch) diff --git a/logic/minecraft/RawLibrary.cpp b/logic/minecraft/RawLibrary.cpp index a10536ea..735f5b0a 100644 --- a/logic/minecraft/RawLibrary.cpp +++ b/logic/minecraft/RawLibrary.cpp @@ -1,123 +1,6 @@ -#include "Json.h" -using namespace Json; - #include "RawLibrary.h" #include -RawLibraryPtr RawLibrary::fromJson(const QJsonObject &libObj, const QString &filename) -{ - RawLibraryPtr out(new RawLibrary()); - if (!libObj.contains("name")) - { - throw JSONValidationError(filename + - "contains a library that doesn't have a 'name' field"); - } - out->m_name = libObj.value("name").toString(); - - auto readString = [libObj, filename](const QString & key, QString & variable) -> bool - { - if (!libObj.contains(key)) - return false; - QJsonValue val = libObj.value(key); - - if (!val.isString()) - { - qWarning() << key << "is not a string in" << filename << "(skipping)"; - return false; - } - - variable = val.toString(); - return true; - }; - - QString urlStr; - readString("url", urlStr); - out->m_base_url = urlStr; - readString("MMC-hint", out->m_hint); - readString("MMC-absulute_url", out->m_absolute_url); - readString("MMC-absoluteUrl", out->m_absolute_url); - if (libObj.contains("extract")) - { - out->applyExcludes = true; - auto extractObj = requireObject(libObj.value("extract")); - for (auto excludeVal : requireArray(extractObj.value("exclude"))) - { - out->extract_excludes.append(requireString(excludeVal)); - } - } - if (libObj.contains("natives")) - { - QJsonObject nativesObj = requireObject(libObj.value("natives")); - for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it) - { - if (!it.value().isString()) - { - qWarning() << filename << "contains an invalid native (skipping)"; - } - OpSys opSys = OpSys_fromString(it.key()); - if (opSys != Os_Other) - { - out->m_native_classifiers[opSys] = it.value().toString(); - } - } - } - if (libObj.contains("rules")) - { - out->applyRules = true; - out->m_rules = rulesFromJsonV4(libObj); - } - return out; -} - -QJsonObject RawLibrary::toJson() const -{ - QJsonObject libRoot; - libRoot.insert("name", (QString)m_name); - if (m_absolute_url.size()) - libRoot.insert("MMC-absoluteUrl", m_absolute_url); - if (m_hint.size()) - libRoot.insert("MMC-hint", m_hint); - if (m_base_url != "http://" + URLConstants::AWS_DOWNLOAD_LIBRARIES && - m_base_url != "https://" + URLConstants::AWS_DOWNLOAD_LIBRARIES && - m_base_url != "https://" + URLConstants::LIBRARY_BASE && !m_base_url.isEmpty()) - { - libRoot.insert("url", m_base_url); - } - if (isNative()) - { - QJsonObject nativeList; - auto iter = m_native_classifiers.begin(); - while (iter != m_native_classifiers.end()) - { - nativeList.insert(OpSys_toString(iter.key()), iter.value()); - iter++; - } - libRoot.insert("natives", nativeList); - if (extract_excludes.size()) - { - QJsonArray excludes; - QJsonObject extract; - for (auto exclude : extract_excludes) - { - excludes.append(exclude); - } - extract.insert("exclude", excludes); - libRoot.insert("extract", extract); - } - } - if (m_rules.size()) - { - QJsonArray allRules; - for (auto &rule : m_rules) - { - QJsonObject ruleObj = rule->toJson(); - allRules.append(ruleObj); - } - libRoot.insert("rules", allRules); - } - return libRoot; -} - QStringList RawLibrary::files() const { QStringList retval; diff --git a/logic/minecraft/RawLibrary.h b/logic/minecraft/RawLibrary.h index 62791239..a8d3ef0d 100644 --- a/logic/minecraft/RawLibrary.h +++ b/logic/minecraft/RawLibrary.h @@ -18,6 +18,8 @@ typedef std::shared_ptr RawLibraryPtr; class RawLibrary { + friend class OneSixVersionFormat; + friend class MojangVersionFormat; public: RawLibrary() { @@ -41,12 +43,6 @@ public: return newlib; } - /// read and create a basic library - static RawLibraryPtr fromJson(const QJsonObject &libObj, const QString &filename); - - /// Convert the library back to an JSON object - QJsonObject toJson() const; - public: /* methods */ /// Returns the raw name field const GradleSpecifier & rawName() const diff --git a/logic/minecraft/forge/ForgeInstaller.cpp b/logic/minecraft/forge/ForgeInstaller.cpp index 468414f8..bc0a967e 100644 --- a/logic/minecraft/forge/ForgeInstaller.cpp +++ b/logic/minecraft/forge/ForgeInstaller.cpp @@ -77,7 +77,7 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr // read the forge version info { - newVersion = OneSixVersionFormat::readProfileFromSingleFile(versionInfoVal.toObject()); + newVersion = OneSixVersionFormat::profileFromSingleJson(versionInfoVal.toObject()); if (!newVersion) return; } @@ -192,7 +192,7 @@ bool ForgeInstaller::add(OneSixInstance *to) } } - QJsonObject libObj = lib->toJson(); + QJsonObject libObj = OneSixVersionFormat::libraryToJson(lib.get()); bool found = false; bool equals = false; @@ -202,7 +202,7 @@ bool ForgeInstaller::add(OneSixInstance *to) if (tolib->artifactId() != libName) continue; found = true; - if (tolib->toJson() == libObj) + if (OneSixVersionFormat::libraryToJson(tolib.get()) == libObj) { equals = true; } diff --git a/logic/minecraft/liteloader/LiteLoaderInstaller.cpp b/logic/minecraft/liteloader/LiteLoaderInstaller.cpp index 3fefe273..81e51cd7 100644 --- a/logic/minecraft/liteloader/LiteLoaderInstaller.cpp +++ b/logic/minecraft/liteloader/LiteLoaderInstaller.cpp @@ -23,6 +23,7 @@ #include "minecraft/MinecraftProfile.h" #include "minecraft/RawLibrary.h" #include "minecraft/onesix/OneSixInstance.h" +#include #include "minecraft/liteloader/LiteLoaderVersionList.h" #include "Exception.h" @@ -51,14 +52,14 @@ bool LiteLoaderInstaller::add(OneSixInstance *to) for (auto rawLibrary : m_version->libraries) { - libraries.append(rawLibrary->toJson()); + libraries.append(OneSixVersionFormat::libraryToJson(rawLibrary.get())); } // liteloader { RawLibrary liteloaderLib("com.mumfrey:liteloader:" + m_version->version); liteloaderLib.setAbsoluteUrl(QString("http://dl.liteloader.com/versions/com/mumfrey/liteloader/%1/%2").arg(m_version->mcVersion, m_version->file)); - QJsonObject llLibObj = liteloaderLib.toJson(); + QJsonObject llLibObj = OneSixVersionFormat::libraryToJson(&liteloaderLib); libraries.append(llLibObj); } diff --git a/logic/minecraft/liteloader/LiteLoaderVersionList.cpp b/logic/minecraft/liteloader/LiteLoaderVersionList.cpp index 1d200e48..42698ccc 100644 --- a/logic/minecraft/liteloader/LiteLoaderVersionList.cpp +++ b/logic/minecraft/liteloader/LiteLoaderVersionList.cpp @@ -14,6 +14,7 @@ */ #include "LiteLoaderVersionList.h" +#include #include "Env.h" #include "net/URLConstants.h" #include "Exception.h" @@ -246,7 +247,7 @@ void LLListLoadTask::listDownloaded() auto libobject = (*lIt).toObject(); try { - auto lib = RawLibrary::fromJson(libobject, "versions.json"); + auto lib = OneSixVersionFormat::libraryFromJson(libobject, "versions.json"); // hack to make liteloader 1.7.10_00 work if(lib->rawName() == GradleSpecifier("org.ow2.asm:asm-all:5.0.3")) { diff --git a/logic/minecraft/onesix/OneSixProfileStrategy.cpp b/logic/minecraft/onesix/OneSixProfileStrategy.cpp index 7dca3619..fe4e0d26 100644 --- a/logic/minecraft/onesix/OneSixProfileStrategy.cpp +++ b/logic/minecraft/onesix/OneSixProfileStrategy.cpp @@ -56,7 +56,7 @@ void OneSixProfileStrategy::upgradeDeprecatedFiles() file->fileId = "net.minecraft"; file->version = file->id; file->name = "Minecraft"; - auto data = OneSixVersionFormat::toJson(file, false).toJson(); + auto data = OneSixVersionFormat::profilePatchToJson(file, false).toJson(); QSaveFile newPatchFile(mcJson); if(!newPatchFile.open(QIODevice::WriteOnly)) { @@ -301,7 +301,7 @@ bool OneSixProfileStrategy::customizePatch(ProfilePatchPtr patch) { return false; } - auto document = OneSixVersionFormat::toJson(patch, true); + auto document = OneSixVersionFormat::profilePatchToJson(patch, true); jsonFile.write(document.toJson()); if(!jsonFile.commit()) { @@ -404,7 +404,7 @@ bool OneSixProfileStrategy::installJarMods(QStringList filepaths) << "for reading:" << file.errorString(); return false; } - file.write(OneSixVersionFormat::toJson(f, true).toJson()); + file.write(OneSixVersionFormat::profilePatchToJson(f, true).toJson()); file.close(); profile->appendPatch(f); } diff --git a/logic/minecraft/onesix/OneSixVersionFormat.cpp b/logic/minecraft/onesix/OneSixVersionFormat.cpp index defbd69a..dc9cf9c4 100644 --- a/logic/minecraft/onesix/OneSixVersionFormat.cpp +++ b/logic/minecraft/onesix/OneSixVersionFormat.cpp @@ -2,6 +2,8 @@ #include #include #include "minecraft/ParseUtils.h" +#include +#include using namespace Json; @@ -22,7 +24,103 @@ static QString readStringRet(const QJsonObject &root, const QString &key) return QString(); } -VersionFilePtr OneSixVersionFormat::fromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder) +RawLibraryPtr OneSixVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename) +{ + RawLibraryPtr out(new RawLibrary()); + if (!libObj.contains("name")) + { + throw JSONValidationError(filename + + "contains a library that doesn't have a 'name' field"); + } + out->m_name = libObj.value("name").toString(); + + readString(libObj, "url", out->m_base_url); + readString(libObj, "MMC-hint", out->m_hint); + readString(libObj, "MMC-absulute_url", out->m_absolute_url); + readString(libObj, "MMC-absoluteUrl", out->m_absolute_url); + if (libObj.contains("extract")) + { + out->applyExcludes = true; + auto extractObj = requireObject(libObj.value("extract")); + for (auto excludeVal : requireArray(extractObj.value("exclude"))) + { + out->extract_excludes.append(requireString(excludeVal)); + } + } + if (libObj.contains("natives")) + { + QJsonObject nativesObj = requireObject(libObj.value("natives")); + for (auto it = nativesObj.begin(); it != nativesObj.end(); ++it) + { + if (!it.value().isString()) + { + qWarning() << filename << "contains an invalid native (skipping)"; + } + OpSys opSys = OpSys_fromString(it.key()); + if (opSys != Os_Other) + { + out->m_native_classifiers[opSys] = it.value().toString(); + } + } + } + if (libObj.contains("rules")) + { + out->applyRules = true; + out->m_rules = rulesFromJsonV4(libObj); + } + return out; +} + +QJsonObject OneSixVersionFormat::libraryToJson(RawLibrary *library) +{ + QJsonObject libRoot; + libRoot.insert("name", (QString)library->m_name); + if (library->m_absolute_url.size()) + libRoot.insert("MMC-absoluteUrl", library->m_absolute_url); + if (library->m_hint.size()) + libRoot.insert("MMC-hint", library->m_hint); + if (library->m_base_url != "http://" + URLConstants::AWS_DOWNLOAD_LIBRARIES && + library->m_base_url != "https://" + URLConstants::AWS_DOWNLOAD_LIBRARIES && + library->m_base_url != "https://" + URLConstants::LIBRARY_BASE && !library->m_base_url.isEmpty()) + { + libRoot.insert("url", library->m_base_url); + } + if (library->isNative()) + { + QJsonObject nativeList; + auto iter = library->m_native_classifiers.begin(); + while (iter != library->m_native_classifiers.end()) + { + nativeList.insert(OpSys_toString(iter.key()), iter.value()); + iter++; + } + libRoot.insert("natives", nativeList); + if (library->extract_excludes.size()) + { + QJsonArray excludes; + QJsonObject extract; + for (auto exclude : library->extract_excludes) + { + excludes.append(exclude); + } + extract.insert("exclude", excludes); + libRoot.insert("extract", extract); + } + } + if (library->m_rules.size()) + { + QJsonArray allRules; + for (auto &rule : library->m_rules) + { + QJsonObject ruleObj = rule->toJson(); + allRules.append(ruleObj); + } + libRoot.insert("rules", allRules); + } + return libRoot; +} + +VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder) { VersionFilePtr out(new VersionFile()); if (doc.isEmpty() || doc.isNull()) @@ -102,7 +200,7 @@ VersionFilePtr OneSixVersionFormat::fromJson(const QJsonDocument &doc, const QSt { auto libObj = requireObject(libVal); - auto lib = RawLibrary::fromJson(libObj, filename); + auto lib = libraryFromJson(libObj, filename); out->overwriteLibs.append(lib); } } @@ -113,7 +211,7 @@ VersionFilePtr OneSixVersionFormat::fromJson(const QJsonDocument &doc, const QSt { QJsonObject libObj = requireObject(libVal); // parse the jarmod - auto lib = Jarmod::fromJson(libObj, filename, out->name); + auto lib = OneSixVersionFormat::jarModFromJson(libObj, filename, out->name); if(lib->originalName.isEmpty()) { auto fixed = out->name; @@ -131,7 +229,7 @@ VersionFilePtr OneSixVersionFormat::fromJson(const QJsonDocument &doc, const QSt { QJsonObject libObj = requireObject(libVal); // parse the library - auto lib = RawLibrary::fromJson(libObj, filename); + auto lib = libraryFromJson(libObj, filename); out->addLibs.append(lib); } } @@ -152,6 +250,15 @@ VersionFilePtr OneSixVersionFormat::fromJson(const QJsonDocument &doc, const QSt return out; } +template +struct libraryConversion +{ + static QJsonObject convert(std::shared_ptr &value) + { + return OneSixVersionFormat::libraryToJson(value.get()); + } +}; + static QJsonDocument versionFileToJson(VersionFilePtr patch, bool saveOrder) { QJsonObject root; @@ -179,9 +286,33 @@ static QJsonDocument versionFileToJson(VersionFilePtr patch, bool saveOrder) writeStringList(root, "tweakers", patch->overwriteTweakers); writeStringList(root, "+tweakers", patch->addTweakers); writeStringList(root, "+traits", patch->traits.toList()); - writeObjectList(root, "libraries", patch->overwriteLibs); - writeObjectList(root, "+libraries", patch->addLibs); - writeObjectList(root, "+jarMods", patch->jarMods); + if (!patch->overwriteLibs.isEmpty()) + { + QJsonArray array; + for (auto value: patch->overwriteLibs) + { + array.append(OneSixVersionFormat::libraryToJson(value.get())); + } + root.insert("libraries", array); + } + if (!patch->addLibs.isEmpty()) + { + QJsonArray array; + for (auto value: patch->addLibs) + { + array.append(OneSixVersionFormat::libraryToJson(value.get())); + } + root.insert("+libraries", array); + } + if (!patch->jarMods.isEmpty()) + { + QJsonArray array; + for (auto value: patch->jarMods) + { + array.append(OneSixVersionFormat::jarModtoJson(value.get())); + } + root.insert("+jarMods", array); + } // write the contents to a json document. { QJsonDocument out; @@ -190,23 +321,40 @@ static QJsonDocument versionFileToJson(VersionFilePtr patch, bool saveOrder) } } -QJsonDocument OneSixVersionFormat::toJson(const ProfilePatchPtr &patch, bool saveOrder) +static QJsonDocument minecraftVersionToJson(MinecraftVersionPtr patch, bool saveOrder) +{ + if(patch->m_versionSource == Local && patch->getVersionFile()) + { + return OneSixVersionFormat::profilePatchToJson(patch->getVersionFile(), saveOrder); + } + else + { + throw VersionIncomplete(QObject::tr("Can't write incomplete/builtin Minecraft version %1").arg(patch->name())); + } +} + +QJsonDocument OneSixVersionFormat::profilePatchToJson(const ProfilePatchPtr &patch, bool saveOrder) { auto vfile = std::dynamic_pointer_cast(patch); if(vfile) { return versionFileToJson(vfile, saveOrder); } - return QJsonDocument(); + auto mversion = std::dynamic_pointer_cast(patch); + if(mversion) + { + return minecraftVersionToJson(mversion, saveOrder); + } + throw VersionIncomplete(QObject::tr("Unhandled object type while processing %1").arg(patch->getPatchName())); } -std::shared_ptr OneSixVersionFormat::readProfileFromSingleFile(const QJsonObject &obj) +std::shared_ptr OneSixVersionFormat::profileFromSingleJson(const QJsonObject &obj) { std::shared_ptr version(new MinecraftProfile(new NullProfileStrategy())); try { version->clear(); - auto file = fromJson(QJsonDocument(obj), QString(), false); + auto file = versionFileFromJson(QJsonDocument(obj), QString(), false); file->applyTo(version.get()); version->appendPatch(file); } @@ -216,3 +364,27 @@ std::shared_ptr OneSixVersionFormat::readProfileFromSingleFile } return version; } + +JarmodPtr OneSixVersionFormat::jarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName) +{ + JarmodPtr out(new Jarmod()); + if (!libObj.contains("name")) + { + throw JSONValidationError(filename + + "contains a jarmod that doesn't have a 'name' field"); + } + out->name = libObj.value("name").toString(); + out->originalName = libObj.value("originalName").toString(); + return out; +} + +QJsonObject OneSixVersionFormat::jarModtoJson(Jarmod *jarmod) +{ + QJsonObject out; + writeString(out, "name", jarmod->name); + if(!jarmod->originalName.isEmpty()) + { + writeString(out, "originalName", jarmod->originalName); + } + return out; +} diff --git a/logic/minecraft/onesix/OneSixVersionFormat.h b/logic/minecraft/onesix/OneSixVersionFormat.h index ab21a6a0..9d16cced 100644 --- a/logic/minecraft/onesix/OneSixVersionFormat.h +++ b/logic/minecraft/onesix/OneSixVersionFormat.h @@ -2,10 +2,24 @@ #include #include +#include #include -namespace OneSixVersionFormat { - std::shared_ptr readProfileFromSingleFile(const QJsonObject &obj); - VersionFilePtr fromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder); - QJsonDocument toJson(const ProfilePatchPtr &patch, bool saveOrder); -} +class OneSixVersionFormat +{ +public: + // whole profiles from single file + static std::shared_ptr profileFromSingleJson(const QJsonObject &obj); + + // version files / profile patches + static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder); + static QJsonDocument profilePatchToJson(const ProfilePatchPtr &patch, bool saveOrder); + + // libraries + static RawLibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename); + static QJsonObject libraryToJson(RawLibrary *library); + + // jar mods + static JarmodPtr jarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName); + static QJsonObject jarModtoJson(Jarmod * jarmod); +}; -- cgit v1.2.3