diff options
-rw-r--r-- | logic/CMakeLists.txt | 4 | ||||
-rw-r--r-- | logic/minecraft/MinecraftProfile.cpp | 18 | ||||
-rw-r--r-- | logic/minecraft/MinecraftProfile.h | 8 | ||||
-rw-r--r-- | logic/minecraft/MinecraftVersion.cpp | 3 | ||||
-rw-r--r-- | logic/minecraft/MinecraftVersion.h | 2 | ||||
-rw-r--r-- | logic/minecraft/MinecraftVersionList.cpp | 6 | ||||
-rw-r--r-- | logic/minecraft/MojangVersionFormat.cpp | 71 | ||||
-rw-r--r-- | logic/minecraft/MojangVersionFormat.h | 8 | ||||
-rw-r--r-- | logic/minecraft/ProfilePatch.h | 1 | ||||
-rw-r--r-- | logic/minecraft/ProfileUtils.cpp | 5 | ||||
-rw-r--r-- | logic/minecraft/VersionFile.cpp | 265 | ||||
-rw-r--r-- | logic/minecraft/VersionFile.h | 6 | ||||
-rw-r--r-- | logic/minecraft/forge/ForgeInstaller.cpp | 3 | ||||
-rw-r--r-- | logic/minecraft/onesix/OneSixProfileStrategy.cpp | 7 | ||||
-rw-r--r-- | logic/minecraft/onesix/OneSixVersionFormat.cpp | 218 | ||||
-rw-r--r-- | logic/minecraft/onesix/OneSixVersionFormat.h | 11 |
16 files changed, 328 insertions, 308 deletions
diff --git a/logic/CMakeLists.txt b/logic/CMakeLists.txt index 40311baf..89c25729 100644 --- a/logic/CMakeLists.txt +++ b/logic/CMakeLists.txt @@ -163,6 +163,8 @@ set(LOGIC_SOURCES minecraft/onesix/OneSixInstance.cpp minecraft/onesix/OneSixProfileStrategy.cpp minecraft/onesix/OneSixProfileStrategy.h + minecraft/onesix/OneSixVersionFormat.cpp + minecraft/onesix/OneSixVersionFormat.h minecraft/legacy/LegacyUpdate.h minecraft/legacy/LegacyUpdate.cpp minecraft/legacy/LegacyInstance.h @@ -174,6 +176,8 @@ set(LOGIC_SOURCES minecraft/GradleSpecifier.h minecraft/MinecraftProfile.cpp minecraft/MinecraftProfile.h + minecraft/MojangVersionFormat.cpp + minecraft/MojangVersionFormat.h minecraft/JarMod.cpp minecraft/JarMod.h minecraft/MinecraftInstance.cpp diff --git a/logic/minecraft/MinecraftProfile.cpp b/logic/minecraft/MinecraftProfile.cpp index 379705a7..7a84996c 100644 --- a/logic/minecraft/MinecraftProfile.cpp +++ b/logic/minecraft/MinecraftProfile.cpp @@ -68,7 +68,6 @@ void MinecraftProfile::clear() assets.clear(); processArguments.clear(); minecraftArguments.clear(); - minimumLauncherVersion = 0xDEADBEAF; mainClass.clear(); appletClass.clear(); libraries.clear(); @@ -267,23 +266,6 @@ QList<std::shared_ptr<RawLibrary> > MinecraftProfile::getActiveNativeLibs() return output; } -std::shared_ptr<MinecraftProfile> MinecraftProfile::fromJson(const QJsonObject &obj) -{ - std::shared_ptr<MinecraftProfile> version(new MinecraftProfile(new NullProfileStrategy())); - try - { - version->clear(); - auto file = VersionFile::fromJson(QJsonDocument(obj), QString(), false); - file->applyTo(version.get()); - version->appendPatch(file); - } - catch(Exception &err) - { - return 0; - } - return version; -} - QVariant MinecraftProfile::data(const QModelIndex &index, int role) const { if (!index.isValid()) diff --git a/logic/minecraft/MinecraftProfile.h b/logic/minecraft/MinecraftProfile.h index a9b3c299..2a97f037 100644 --- a/logic/minecraft/MinecraftProfile.h +++ b/logic/minecraft/MinecraftProfile.h @@ -39,9 +39,6 @@ class MULTIMC_LOGIC_EXPORT MinecraftProfile : public QAbstractListModel public: explicit MinecraftProfile(ProfileStrategy *strategy); - /// construct a MinecraftProfile from a single file - static std::shared_ptr<MinecraftProfile> fromJson(const QJsonObject &obj); - void setStrategy(ProfileStrategy * strategy); ProfileStrategy *strategy(); @@ -153,11 +150,6 @@ public: /* data */ /// Same as above, but only for vanilla QString vanillaMinecraftArguments; /** - * the minimum launcher version required by this version ... current is 4 (at point of - * writing) - */ - int minimumLauncherVersion = 0xDEADBEEF; - /** * A list of all tweaker classes */ QStringList tweakers; diff --git a/logic/minecraft/MinecraftVersion.cpp b/logic/minecraft/MinecraftVersion.cpp index e6895bf7..4225fa50 100644 --- a/logic/minecraft/MinecraftVersion.cpp +++ b/logic/minecraft/MinecraftVersion.cpp @@ -64,7 +64,7 @@ void MinecraftVersion::applyFileTo(MinecraftProfile *version) throw VersionIncomplete(QObject::tr("Can't apply incomplete/builtin Minecraft version %1").arg(m_name)); } } - +/* QJsonDocument MinecraftVersion::toJson(bool saveOrder) { if(m_versionSource == Local && getVersionFile()) @@ -76,6 +76,7 @@ QJsonDocument MinecraftVersion::toJson(bool saveOrder) throw VersionIncomplete(QObject::tr("Can't write incomplete/builtin Minecraft version %1").arg(m_name)); } } +*/ QString MinecraftVersion::getUrl() const { diff --git a/logic/minecraft/MinecraftVersion.h b/logic/minecraft/MinecraftVersion.h index afeac3b7..63583968 100644 --- a/logic/minecraft/MinecraftVersion.h +++ b/logic/minecraft/MinecraftVersion.h @@ -74,7 +74,7 @@ public: /* methods */ VersionFilePtr getVersionFile(); - virtual QJsonDocument toJson(bool saveOrder) override; + // virtual QJsonDocument toJson(bool saveOrder) override; QString getUrl() const; diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp index 9a1c18b7..3e970bf7 100644 --- a/logic/minecraft/MinecraftVersionList.cpp +++ b/logic/minecraft/MinecraftVersionList.cpp @@ -27,6 +27,8 @@ #include "ParseUtils.h" #include "ProfileUtils.h" #include "VersionFilterData.h" +#include "onesix/OneSixVersionFormat.h" +#include "MojangVersionFormat.h" #include <FileSystem.h> static const char * localVersionCache = "versions/versions.dat"; @@ -510,7 +512,7 @@ void MCVListVersionUpdateTask::json_downloaded() VersionFilePtr file; try { - file = VersionFile::fromMojangJson(jsonDoc, "net.minecraft.json"); + file = MojangVersionFormat::fromJson(jsonDoc, "net.minecraft.json"); } catch (Exception &e) { @@ -526,7 +528,7 @@ void MCVListVersionUpdateTask::json_downloaded() file->fileId = "net.minecraft"; // now dump the file to disk - auto doc = file->toJson(false); + auto doc = OneSixVersionFormat::toJson(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 new file mode 100644 index 00000000..7427156b --- /dev/null +++ b/logic/minecraft/MojangVersionFormat.cpp @@ -0,0 +1,71 @@ +#include "MojangVersionFormat.h" + +#include "Json.h" +using namespace Json; + +static const int CURRENT_MINIMUM_LAUNCHER_VERSION = 14; + +// FIXME: duplicated in OneSixVersionFormat! +static void readString(const QJsonObject &root, const QString &key, QString &variable) +{ + if (root.contains(key)) + { + variable = requireString(root.value(key)); + } +} + +VersionFilePtr MojangVersionFormat::fromJson(const QJsonDocument &doc, const QString &filename) +{ + VersionFilePtr out(new VersionFile()); + if (doc.isEmpty() || doc.isNull()) + { + throw JSONValidationError(filename + " is empty or null"); + } + if (!doc.isObject()) + { + throw JSONValidationError(filename + " is not an object"); + } + + QJsonObject root = doc.object(); + + out->name = root.value("name").toString(); + out->fileId = root.value("fileId").toString(); + out->version = root.value("version").toString(); + out->mcVersion = root.value("mcVersion").toString(); + out->filename = filename; + + readString(root, "id", out->id); + + readString(root, "mainClass", out->mainClass); + readString(root, "appletClass", out->appletClass); + readString(root, "minecraftArguments", out->overwriteMinecraftArguments); + readString(root, "type", out->type); + + readString(root, "assets", out->assets); + + if (root.contains("minimumLauncherVersion")) + { + auto minimumLauncherVersion = requireInteger(root.value("minimumLauncherVersion")); + if (minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION) + { + out->addProblem( + PROBLEM_WARNING, + QObject::tr("The 'minimumLauncherVersion' value of this version (%1) is higher than supported by MultiMC (%2). It might not work properly!") + .arg(minimumLauncherVersion) + .arg(CURRENT_MINIMUM_LAUNCHER_VERSION)); + } + } + + if (root.contains("libraries")) + { + out->shouldOverwriteLibs = true; + for (auto libVal : requireArray(root.value("libraries"))) + { + auto libObj = requireObject(libVal); + + auto lib = RawLibrary::fromJson(libObj, filename); + out->overwriteLibs.append(lib); + } + } + return out; +} diff --git a/logic/minecraft/MojangVersionFormat.h b/logic/minecraft/MojangVersionFormat.h new file mode 100644 index 00000000..78bc1c42 --- /dev/null +++ b/logic/minecraft/MojangVersionFormat.h @@ -0,0 +1,8 @@ +#pragma once + +#include <minecraft/VersionFile.h> +#include <QJsonDocument> + +namespace MojangVersionFormat { + VersionFilePtr fromJson(const QJsonDocument &doc, const QString &filename); +} diff --git a/logic/minecraft/ProfilePatch.h b/logic/minecraft/ProfilePatch.h index e4bb1c02..cf7a1904 100644 --- a/logic/minecraft/ProfilePatch.h +++ b/logic/minecraft/ProfilePatch.h @@ -40,7 +40,6 @@ class ProfilePatch public: virtual ~ProfilePatch(){}; virtual void applyTo(MinecraftProfile *version) = 0; - virtual QJsonDocument toJson(bool saveOrder) = 0; virtual bool isMinecraftVersion() = 0; virtual bool hasJarMods() = 0; diff --git a/logic/minecraft/ProfileUtils.cpp b/logic/minecraft/ProfileUtils.cpp index 5816f207..995c2052 100644 --- a/logic/minecraft/ProfileUtils.cpp +++ b/logic/minecraft/ProfileUtils.cpp @@ -1,5 +1,6 @@ #include "ProfileUtils.h" #include "minecraft/VersionFilterData.h" +#include "minecraft/onesix/OneSixVersionFormat.h" #include "Json.h" #include <QDebug> @@ -128,7 +129,7 @@ VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder) .arg(fileInfo.fileName(), error.errorString()) .arg(line).arg(column)); } - return VersionFile::fromJson(doc, file.fileName(), requireOrder); + return OneSixVersionFormat::fromJson(doc, file.fileName(), requireOrder); } VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo) @@ -147,7 +148,7 @@ VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo) throw JSONValidationError( QObject::tr("Unable to process the version file %1.").arg(fileInfo.fileName())); } - return VersionFile::fromJson(doc, file.fileName(), false); + return OneSixVersionFormat::fromJson(doc, file.fileName(), false); } void removeLwjglFromPatch(VersionFilePtr patch) diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp index e0b4aa85..6e2af603 100644 --- a/logic/minecraft/VersionFile.cpp +++ b/logic/minecraft/VersionFile.cpp @@ -9,29 +9,9 @@ #include "minecraft/JarMod.h" #include "ParseUtils.h" -#include "Json.h" -using namespace Json; - #include "VersionBuildError.h" #include <Version.h> -static void readString(const QJsonObject &root, const QString &key, QString &variable) -{ - if (root.contains(key)) - { - variable = requireString(root.value(key)); - } -} - -static QString readStringRet(const QJsonObject &root, const QString &key) -{ - if (root.contains(key)) - { - return requireString(root.value(key)); - } - return QString(); -} - int findLibraryByName(QList<RawLibraryPtr> haystack, const GradleSpecifier &needle) { int retval = -1; @@ -48,246 +28,6 @@ int findLibraryByName(QList<RawLibraryPtr> haystack, const GradleSpecifier &need return retval; } -void checkMinimumLauncherVersion(VersionFilePtr out) -{ - const int CURRENT_MINIMUM_LAUNCHER_VERSION = 14; - if (out->minimumLauncherVersion > CURRENT_MINIMUM_LAUNCHER_VERSION) - { - out->addProblem( - PROBLEM_WARNING, - QObject::tr("The 'minimumLauncherVersion' value of this version (%1) is higher than supported by MultiMC (%2). It might not work properly!") - .arg(out->minimumLauncherVersion) - .arg(CURRENT_MINIMUM_LAUNCHER_VERSION)); - } -} - -VersionFilePtr VersionFile::fromMojangJson(const QJsonDocument &doc, const QString &filename) -{ - VersionFilePtr out(new VersionFile()); - if (doc.isEmpty() || doc.isNull()) - { - throw JSONValidationError(filename + " is empty or null"); - } - if (!doc.isObject()) - { - throw JSONValidationError(filename + " is not an object"); - } - - QJsonObject root = doc.object(); - - out->name = root.value("name").toString(); - out->fileId = root.value("fileId").toString(); - out->version = root.value("version").toString(); - out->mcVersion = root.value("mcVersion").toString(); - out->filename = filename; - - readString(root, "id", out->id); - - readString(root, "mainClass", out->mainClass); - readString(root, "appletClass", out->appletClass); - readString(root, "minecraftArguments", out->overwriteMinecraftArguments); - readString(root, "type", out->type); - - readString(root, "assets", out->assets); - - if (root.contains("minimumLauncherVersion")) - { - out->minimumLauncherVersion = requireInteger(root.value("minimumLauncherVersion")); - checkMinimumLauncherVersion(out); - } - - if (root.contains("libraries")) - { - out->shouldOverwriteLibs = true; - for (auto libVal : requireArray(root.value("libraries"))) - { - auto libObj = requireObject(libVal); - - auto lib = RawLibrary::fromJson(libObj, filename); - out->overwriteLibs.append(lib); - } - } - return out; -} - -VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder) -{ - VersionFilePtr out(new VersionFile()); - if (doc.isEmpty() || doc.isNull()) - { - throw JSONValidationError(filename + " is empty or null"); - } - if (!doc.isObject()) - { - throw JSONValidationError(filename + " is not an object"); - } - - QJsonObject root = doc.object(); - - if (requireOrder) - { - if (root.contains("order")) - { - out->order = requireInteger(root.value("order")); - } - else - { - // FIXME: evaluate if we don't want to throw exceptions here instead - qCritical() << filename << "doesn't contain an order field"; - } - } - - out->name = root.value("name").toString(); - out->fileId = root.value("fileId").toString(); - out->version = root.value("version").toString(); - out->mcVersion = root.value("mcVersion").toString(); - out->filename = filename; - - readString(root, "id", out->id); - - readString(root, "mainClass", out->mainClass); - readString(root, "appletClass", out->appletClass); - readString(root, "processArguments", out->processArguments); - readString(root, "minecraftArguments", out->overwriteMinecraftArguments); - readString(root, "+minecraftArguments", out->addMinecraftArguments); - readString(root, "type", out->type); - - parse_timestamp(readStringRet(root, "releaseTime"), out->m_releaseTimeString, out->m_releaseTime); - parse_timestamp(readStringRet(root, "time"), out->m_updateTimeString, out->m_updateTime); - - readString(root, "assets", out->assets); - - if (root.contains("minimumLauncherVersion")) - { - out->minimumLauncherVersion = requireInteger(root.value("minimumLauncherVersion")); - checkMinimumLauncherVersion(out); - } - - if (root.contains("tweakers")) - { - out->shouldOverwriteTweakers = true; - for (auto tweakerVal : requireArray(root.value("tweakers"))) - { - out->overwriteTweakers.append(requireString(tweakerVal)); - } - } - - if (root.contains("+tweakers")) - { - for (auto tweakerVal : requireArray(root.value("+tweakers"))) - { - out->addTweakers.append(requireString(tweakerVal)); - } - } - - - if (root.contains("+traits")) - { - for (auto tweakerVal : requireArray(root.value("+traits"))) - { - out->traits.insert(requireString(tweakerVal)); - } - } - - if (root.contains("libraries")) - { - out->shouldOverwriteLibs = true; - for (auto libVal : requireArray(root.value("libraries"))) - { - auto libObj = requireObject(libVal); - - auto lib = RawLibrary::fromJson(libObj, filename); - out->overwriteLibs.append(lib); - } - } - - if (root.contains("+jarMods")) - { - for (auto libVal : requireArray(root.value("+jarMods"))) - { - QJsonObject libObj = requireObject(libVal); - // parse the jarmod - auto lib = Jarmod::fromJson(libObj, filename, out->name); - if(lib->originalName.isEmpty()) - { - auto fixed = out->name; - fixed.remove(" (jar mod)"); - lib->originalName = out->name; - } - // and add to jar mods - out->jarMods.append(lib); - } - } - - if (root.contains("+libraries")) - { - for (auto libVal : requireArray(root.value("+libraries"))) - { - QJsonObject libObj = requireObject(libVal); - // parse the library - auto lib = RawLibrary::fromJson(libObj, filename); - out->addLibs.append(lib); - } - } - - /* removed features that shouldn't be used */ - if (root.contains("-libraries")) - { - out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-libraries'")); - } - if (root.contains("-tweakers")) - { - out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-tweakers'")); - } - if (root.contains("-minecraftArguments")) - { - out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-minecraftArguments'")); - } - return out; -} - -QJsonDocument VersionFile::toJson(bool saveOrder) -{ - QJsonObject root; - if (saveOrder) - { - root.insert("order", order); - } - writeString(root, "name", name); - writeString(root, "fileId", fileId); - writeString(root, "version", version); - writeString(root, "mcVersion", mcVersion); - writeString(root, "id", id); - writeString(root, "mainClass", mainClass); - writeString(root, "appletClass", appletClass); - writeString(root, "processArguments", processArguments); - writeString(root, "minecraftArguments", overwriteMinecraftArguments); - writeString(root, "+minecraftArguments", addMinecraftArguments); - writeString(root, "type", type); - writeString(root, "assets", assets); - if (isMinecraftVersion()) - { - writeString(root, "releaseTime", m_releaseTimeString); - writeString(root, "time", m_updateTimeString); - } - if (minimumLauncherVersion != -1) - { - root.insert("minimumLauncherVersion", minimumLauncherVersion); - } - writeStringList(root, "tweakers", overwriteTweakers); - writeStringList(root, "+tweakers", addTweakers); - writeStringList(root, "+traits", traits.toList()); - writeObjectList(root, "libraries", overwriteLibs); - writeObjectList(root, "+libraries", addLibs); - writeObjectList(root, "+jarMods", jarMods); - // write the contents to a json document. - { - QJsonDocument out; - out.setObject(root); - return out; - } -} - bool VersionFile::isMinecraftVersion() { return fileId == "net.minecraft"; @@ -350,11 +90,6 @@ void VersionFile::applyTo(MinecraftProfile *version) { version->assets = assets; } - if (minimumLauncherVersion >= 0) - { - if (version->minimumLauncherVersion < minimumLauncherVersion) - version->minimumLauncherVersion = minimumLauncherVersion; - } if (!overwriteMinecraftArguments.isNull()) { if (isMinecraftVersion()) diff --git a/logic/minecraft/VersionFile.h b/logic/minecraft/VersionFile.h index 56877936..3486f656 100644 --- a/logic/minecraft/VersionFile.h +++ b/logic/minecraft/VersionFile.h @@ -19,11 +19,6 @@ typedef std::shared_ptr<VersionFile> VersionFilePtr; class VersionFile : public ProfilePatch { public: /* methods */ - static VersionFilePtr fromMojangJson(const QJsonDocument &doc, const QString &filename); - static VersionFilePtr fromJson(const QJsonDocument &doc, const QString &filename, - const bool requireOrder); - virtual QJsonDocument toJson(bool saveOrder) override; - virtual void applyTo(MinecraftProfile *version) override; virtual bool isMinecraftVersion() override; virtual bool hasJarMods() override; @@ -139,7 +134,6 @@ public: /* data */ /// asset group used by this ... thing. QString assets; - int minimumLauncherVersion = -1; bool shouldOverwriteTweakers = false; QStringList overwriteTweakers; diff --git a/logic/minecraft/forge/ForgeInstaller.cpp b/logic/minecraft/forge/ForgeInstaller.cpp index a9283e5d..468414f8 100644 --- a/logic/minecraft/forge/ForgeInstaller.cpp +++ b/logic/minecraft/forge/ForgeInstaller.cpp @@ -21,6 +21,7 @@ #include "net/HttpMetaCache.h" #include "tasks/Task.h" #include "minecraft/onesix/OneSixInstance.h" +#include <minecraft/onesix/OneSixVersionFormat.h> #include "minecraft/VersionFilterData.h" #include "Env.h" #include "Exception.h" @@ -76,7 +77,7 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr // read the forge version info { - newVersion = MinecraftProfile::fromJson(versionInfoVal.toObject()); + newVersion = OneSixVersionFormat::readProfileFromSingleFile(versionInfoVal.toObject()); if (!newVersion) return; } diff --git a/logic/minecraft/onesix/OneSixProfileStrategy.cpp b/logic/minecraft/onesix/OneSixProfileStrategy.cpp index 35ca769f..7dca3619 100644 --- a/logic/minecraft/onesix/OneSixProfileStrategy.cpp +++ b/logic/minecraft/onesix/OneSixProfileStrategy.cpp @@ -1,5 +1,6 @@ #include "OneSixProfileStrategy.h" #include "OneSixInstance.h" +#include "OneSixVersionFormat.h" #include "minecraft/VersionBuildError.h" #include "minecraft/MinecraftVersionList.h" @@ -55,7 +56,7 @@ void OneSixProfileStrategy::upgradeDeprecatedFiles() file->fileId = "net.minecraft"; file->version = file->id; file->name = "Minecraft"; - auto data = file->toJson(false).toJson(); + auto data = OneSixVersionFormat::toJson(file, false).toJson(); QSaveFile newPatchFile(mcJson); if(!newPatchFile.open(QIODevice::WriteOnly)) { @@ -300,7 +301,7 @@ bool OneSixProfileStrategy::customizePatch(ProfilePatchPtr patch) { return false; } - auto document = patch->toJson(true); + auto document = OneSixVersionFormat::toJson(patch, true); jsonFile.write(document.toJson()); if(!jsonFile.commit()) { @@ -403,7 +404,7 @@ bool OneSixProfileStrategy::installJarMods(QStringList filepaths) << "for reading:" << file.errorString(); return false; } - file.write(f->toJson(true).toJson()); + file.write(OneSixVersionFormat::toJson(f, true).toJson()); file.close(); profile->appendPatch(f); } diff --git a/logic/minecraft/onesix/OneSixVersionFormat.cpp b/logic/minecraft/onesix/OneSixVersionFormat.cpp new file mode 100644 index 00000000..defbd69a --- /dev/null +++ b/logic/minecraft/onesix/OneSixVersionFormat.cpp @@ -0,0 +1,218 @@ +#include "OneSixVersionFormat.h" +#include <minecraft/NullProfileStrategy.h> +#include <Json.h> +#include "minecraft/ParseUtils.h" + +using namespace Json; + +static void readString(const QJsonObject &root, const QString &key, QString &variable) +{ + if (root.contains(key)) + { + variable = requireString(root.value(key)); + } +} + +static QString readStringRet(const QJsonObject &root, const QString &key) +{ + if (root.contains(key)) + { + return requireString(root.value(key)); + } + return QString(); +} + +VersionFilePtr OneSixVersionFormat::fromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder) +{ + VersionFilePtr out(new VersionFile()); + if (doc.isEmpty() || doc.isNull()) + { + throw JSONValidationError(filename + " is empty or null"); + } + if (!doc.isObject()) + { + throw JSONValidationError(filename + " is not an object"); + } + + QJsonObject root = doc.object(); + + if (requireOrder) + { + if (root.contains("order")) + { + out->order = requireInteger(root.value("order")); + } + else + { + // FIXME: evaluate if we don't want to throw exceptions here instead + qCritical() << filename << "doesn't contain an order field"; + } + } + + out->name = root.value("name").toString(); + out->fileId = root.value("fileId").toString(); + out->version = root.value("version").toString(); + out->mcVersion = root.value("mcVersion").toString(); + out->filename = filename; + + readString(root, "id", out->id); + + readString(root, "mainClass", out->mainClass); + readString(root, "appletClass", out->appletClass); + readString(root, "processArguments", out->processArguments); + readString(root, "minecraftArguments", out->overwriteMinecraftArguments); + readString(root, "+minecraftArguments", out->addMinecraftArguments); + readString(root, "type", out->type); + + parse_timestamp(readStringRet(root, "releaseTime"), out->m_releaseTimeString, out->m_releaseTime); + parse_timestamp(readStringRet(root, "time"), out->m_updateTimeString, out->m_updateTime); + + readString(root, "assets", out->assets); + + if (root.contains("tweakers")) + { + out->shouldOverwriteTweakers = true; + for (auto tweakerVal : requireArray(root.value("tweakers"))) + { + out->overwriteTweakers.append(requireString(tweakerVal)); + } + } + + if (root.contains("+tweakers")) + { + for (auto tweakerVal : requireArray(root.value("+tweakers"))) + { + out->addTweakers.append(requireString(tweakerVal)); + } + } + + + if (root.contains("+traits")) + { + for (auto tweakerVal : requireArray(root.value("+traits"))) + { + out->traits.insert(requireString(tweakerVal)); + } + } + + if (root.contains("libraries")) + { + out->shouldOverwriteLibs = true; + for (auto libVal : requireArray(root.value("libraries"))) + { + auto libObj = requireObject(libVal); + + auto lib = RawLibrary::fromJson(libObj, filename); + out->overwriteLibs.append(lib); + } + } + + if (root.contains("+jarMods")) + { + for (auto libVal : requireArray(root.value("+jarMods"))) + { + QJsonObject libObj = requireObject(libVal); + // parse the jarmod + auto lib = Jarmod::fromJson(libObj, filename, out->name); + if(lib->originalName.isEmpty()) + { + auto fixed = out->name; + fixed.remove(" (jar mod)"); + lib->originalName = out->name; + } + // and add to jar mods + out->jarMods.append(lib); + } + } + + if (root.contains("+libraries")) + { + for (auto libVal : requireArray(root.value("+libraries"))) + { + QJsonObject libObj = requireObject(libVal); + // parse the library + auto lib = RawLibrary::fromJson(libObj, filename); + out->addLibs.append(lib); + } + } + + /* removed features that shouldn't be used */ + if (root.contains("-libraries")) + { + out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-libraries'")); + } + if (root.contains("-tweakers")) + { + out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-tweakers'")); + } + if (root.contains("-minecraftArguments")) + { + out->addProblem(PROBLEM_ERROR, QObject::tr("Version file contains unsupported element '-minecraftArguments'")); + } + return out; +} + +static QJsonDocument versionFileToJson(VersionFilePtr patch, bool saveOrder) +{ + QJsonObject root; + if (saveOrder) + { + root.insert("order", patch->order); + } + writeString(root, "name", patch->name); + writeString(root, "fileId", patch->fileId); + writeString(root, "version", patch->version); + writeString(root, "mcVersion", patch->mcVersion); + writeString(root, "id", patch->id); + writeString(root, "mainClass", patch->mainClass); + writeString(root, "appletClass", patch->appletClass); + writeString(root, "processArguments", patch->processArguments); + writeString(root, "minecraftArguments", patch->overwriteMinecraftArguments); + writeString(root, "+minecraftArguments", patch->addMinecraftArguments); + writeString(root, "type", patch->type); + writeString(root, "assets", patch->assets); + if (patch->isMinecraftVersion()) + { + writeString(root, "releaseTime", patch->m_releaseTimeString); + writeString(root, "time", patch->m_updateTimeString); + } + 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); + // write the contents to a json document. + { + QJsonDocument out; + out.setObject(root); + return out; + } +} + +QJsonDocument OneSixVersionFormat::toJson(const ProfilePatchPtr &patch, bool saveOrder) +{ + auto vfile = std::dynamic_pointer_cast<VersionFile>(patch); + if(vfile) + { + return versionFileToJson(vfile, saveOrder); + } + return QJsonDocument(); +} + +std::shared_ptr<MinecraftProfile> OneSixVersionFormat::readProfileFromSingleFile(const QJsonObject &obj) +{ + std::shared_ptr<MinecraftProfile> version(new MinecraftProfile(new NullProfileStrategy())); + try + { + version->clear(); + auto file = fromJson(QJsonDocument(obj), QString(), false); + file->applyTo(version.get()); + version->appendPatch(file); + } + catch(Exception &err) + { + return nullptr; + } + return version; +} diff --git a/logic/minecraft/onesix/OneSixVersionFormat.h b/logic/minecraft/onesix/OneSixVersionFormat.h new file mode 100644 index 00000000..ab21a6a0 --- /dev/null +++ b/logic/minecraft/onesix/OneSixVersionFormat.h @@ -0,0 +1,11 @@ +#pragma once + +#include <minecraft/VersionFile.h> +#include <minecraft/MinecraftProfile.h> +#include <QJsonDocument> + +namespace OneSixVersionFormat { + std::shared_ptr<MinecraftProfile> readProfileFromSingleFile(const QJsonObject &obj); + VersionFilePtr fromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder); + QJsonDocument toJson(const ProfilePatchPtr &patch, bool saveOrder); +} |