From d4eacb56b30baaef801f42545398a4f29755fadf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 7 Mar 2016 02:01:28 +0100 Subject: NOISSUE make new Mojang version format pass through MultiMC structures Not yet used effectively, but it is read and written properly --- logic/CMakeLists.txt | 9 +- logic/minecraft/Library.cpp | 130 +++++++++ logic/minecraft/Library.h | 190 +++++++++++++ logic/minecraft/MinecraftProfile.cpp | 8 +- logic/minecraft/MinecraftProfile.h | 10 +- logic/minecraft/MojangDownloadInfo.h | 92 +++++++ logic/minecraft/MojangVersionFormat.cpp | 305 ++++++++++++++++++++- logic/minecraft/MojangVersionFormat.h | 15 + logic/minecraft/OneSixRule.cpp | 93 ------- logic/minecraft/OneSixRule.h | 101 ------- logic/minecraft/ProfileUtils.cpp | 4 +- logic/minecraft/ProfileUtils.h | 2 +- logic/minecraft/RawLibrary.cpp | 130 --------- logic/minecraft/RawLibrary.h | 187 ------------- logic/minecraft/Rule.cpp | 93 +++++++ logic/minecraft/Rule.h | 101 +++++++ logic/minecraft/VersionFile.cpp | 12 +- logic/minecraft/VersionFile.h | 14 +- logic/minecraft/ftb/FTBProfileStrategy.cpp | 2 +- logic/minecraft/liteloader/LiteLoaderInstaller.cpp | 8 +- logic/minecraft/liteloader/LiteLoaderVersionList.h | 4 +- logic/minecraft/onesix/OneSixUpdate.cpp | 4 +- logic/minecraft/onesix/OneSixVersionFormat.cpp | 88 +----- logic/minecraft/onesix/OneSixVersionFormat.h | 6 +- 24 files changed, 974 insertions(+), 634 deletions(-) create mode 100644 logic/minecraft/Library.cpp create mode 100644 logic/minecraft/Library.h create mode 100644 logic/minecraft/MojangDownloadInfo.h delete mode 100644 logic/minecraft/OneSixRule.cpp delete mode 100644 logic/minecraft/OneSixRule.h delete mode 100644 logic/minecraft/RawLibrary.cpp delete mode 100644 logic/minecraft/RawLibrary.h create mode 100644 logic/minecraft/Rule.cpp create mode 100644 logic/minecraft/Rule.h (limited to 'logic') diff --git a/logic/CMakeLists.txt b/logic/CMakeLists.txt index fe827f5f..28c1b8fc 100644 --- a/logic/CMakeLists.txt +++ b/logic/CMakeLists.txt @@ -186,8 +186,8 @@ set(LOGIC_SOURCES minecraft/MinecraftVersionList.cpp minecraft/MinecraftVersionList.h minecraft/NullProfileStrategy.h - minecraft/OneSixRule.cpp - minecraft/OneSixRule.h + minecraft/Rule.cpp + minecraft/Rule.h minecraft/OpSys.cpp minecraft/OpSys.h minecraft/ParseUtils.cpp @@ -195,8 +195,9 @@ set(LOGIC_SOURCES minecraft/ProfileUtils.cpp minecraft/ProfileUtils.h minecraft/ProfileStrategy.h - minecraft/RawLibrary.cpp - minecraft/RawLibrary.h + minecraft/Library.cpp + minecraft/Library.h + minecraft/MojangDownloadInfo.h minecraft/VersionBuildError.h minecraft/VersionFile.cpp minecraft/VersionFile.h diff --git a/logic/minecraft/Library.cpp b/logic/minecraft/Library.cpp new file mode 100644 index 00000000..9a1d2cc7 --- /dev/null +++ b/logic/minecraft/Library.cpp @@ -0,0 +1,130 @@ +#include "Library.h" +#include + +QStringList Library::files() const +{ + QStringList retval; + QString storage = storageSuffix(); + if (storage.contains("${arch}")) + { + QString cooked_storage = storage; + cooked_storage.replace("${arch}", "32"); + retval.append(cooked_storage); + cooked_storage = storage; + cooked_storage.replace("${arch}", "64"); + retval.append(cooked_storage); + } + else + retval.append(storage); + return retval; +} + +bool Library::filesExist(const QDir &base) const +{ + auto libFiles = files(); + for(auto file: libFiles) + { + QFileInfo info(base, file); + qWarning() << info.absoluteFilePath() << "doesn't exist"; + if (!info.exists()) + return false; + } + return true; +} + +QString Library::url() const +{ + if (!m_absolute_url.isEmpty()) + { + return m_absolute_url; + } + + if (m_base_url.isEmpty()) + { + return QString("https://" + URLConstants::LIBRARY_BASE) + storageSuffix(); + } + + if(m_base_url.endsWith('/')) + { + return m_base_url + storageSuffix(); + } + else + { + return m_base_url + QChar('/') + storageSuffix(); + } +} + +bool Library::isActive() const +{ + bool result = true; + if (m_rules.empty()) + { + result = true; + } + else + { + RuleAction ruleResult = Disallow; + for (auto rule : m_rules) + { + RuleAction temp = rule->apply(this); + if (temp != Defer) + ruleResult = temp; + } + result = result && (ruleResult == Allow); + } + if (isNative()) + { + result = result && m_native_classifiers.contains(currentSystem); + } + return result; +} + +void Library::setStoragePrefix(QString prefix) +{ + m_storagePrefix = prefix; +} + +QString Library::defaultStoragePrefix() +{ + return "libraries/"; +} + +QString Library::storagePrefix() const +{ + if(m_storagePrefix.isEmpty()) + { + return defaultStoragePrefix(); + } + return m_storagePrefix; +} + +QString Library::storageSuffix() const +{ + // non-native? use only the gradle specifier + if (!isNative()) + { + return m_name.toPath(); + } + + // otherwise native, override classifiers. Mojang HACK! + GradleSpecifier nativeSpec = m_name; + if (m_native_classifiers.contains(currentSystem)) + { + nativeSpec.setClassifier(m_native_classifiers[currentSystem]); + } + else + { + nativeSpec.setClassifier("INVALID"); + } + return nativeSpec.toPath(); +} + +QString Library::storagePath() const +{ + return FS::PathCombine(storagePrefix(), storageSuffix()); +} + +bool Library::storagePathIsDefault() const +{ + return m_storagePrefix.isEmpty(); +} diff --git a/logic/minecraft/Library.h b/logic/minecraft/Library.h new file mode 100644 index 00000000..7ae126a9 --- /dev/null +++ b/logic/minecraft/Library.h @@ -0,0 +1,190 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Rule.h" +#include "minecraft/OpSys.h" +#include "GradleSpecifier.h" +#include "MojangDownloadInfo.h" +#include "net/URLConstants.h" + +class Library; +typedef std::shared_ptr LibraryPtr; + +class Library +{ + friend class OneSixVersionFormat; + friend class MojangVersionFormat; +public: + Library() + { + } + Library(const QString &name) + { + m_name = name; + } + /// limited copy without some data. TODO: why? + static LibraryPtr limitedCopy(LibraryPtr base) + { + auto newlib = std::make_shared(); + newlib->m_name = base->m_name; + newlib->m_base_url = base->m_base_url; + newlib->m_hint = base->m_hint; + newlib->m_absolute_url = base->m_absolute_url; + newlib->extract_excludes = base->extract_excludes; + newlib->m_native_classifiers = base->m_native_classifiers; + newlib->m_rules = base->m_rules; + newlib->m_storagePrefix = base->m_storagePrefix; + return newlib; + } + +public: /* methods */ + /// Returns the raw name field + const GradleSpecifier & rawName() const + { + return m_name; + } + + void setRawName(const GradleSpecifier & spec) + { + m_name = spec; + } + + void setClassifier(const QString & spec) + { + m_name.setClassifier(spec); + } + + /// returns the full group and artifact prefix + QString artifactPrefix() const + { + return m_name.artifactPrefix(); + } + + /// get the artifact ID + QString artifactId() const + { + return m_name.artifactId(); + } + + /// get the artifact version + QString version() const + { + return m_name.version(); + } + + /// Returns true if the library is native + bool isNative() const + { + return m_native_classifiers.size() != 0; + } + + void setStoragePrefix(QString prefix = QString()); + + /// the default storage prefix used by MultiMC + static QString defaultStoragePrefix(); + + bool storagePathIsDefault() const; + + /// Get the prefix - root of the storage to be used + QString storagePrefix() const; + + /// Get the relative path where the library should be saved + QString storageSuffix() const; + + /// Get the absolute path where the library should be saved + QString storagePath() const; + + /// Set the url base for downloads + void setBaseUrl(const QString &base_url) + { + m_base_url = base_url; + } + + /// List of files this library describes. Required because of platform-specificness of native libs + QStringList files() const; + + /// List Shortcut for checking if all the above files exist + bool filesExist(const QDir &base) const; + + void setAbsoluteUrl(const QString &absolute_url) + { + m_absolute_url = absolute_url; + } + + QString absoluteUrl() const + { + return m_absolute_url; + } + + void setHint(const QString &hint) + { + m_hint = hint; + } + + QString hint() const + { + return m_hint; + } + + /// Set the load rules + void setRules(QList> rules) + { + m_rules = rules; + } + + /// Returns true if the library should be loaded (or extracted, in case of natives) + bool isActive() const; + + /// Get the URL to download the library from + QString url() const; + +protected: /* data */ + /// the basic gradle dependency specifier. + GradleSpecifier m_name; + /// where to store the lib locally + QString m_storage_path; + /// is this lib actually active on the current OS? + bool m_is_active = false; + + /// DEPRECATED URL prefix of the maven repo where the file can be downloaded + QString m_base_url; + + /// DEPRECATED: MultiMC-specific absolute URL. takes precedence over the implicit maven repo URL, if defined + QString m_absolute_url; + + /** + * MultiMC-specific type hint - modifies how the library is treated + */ + QString m_hint; + + /** + * storage - by default the local libraries folder in multimc, but could be elsewhere + * MultiMC specific, because of FTB. + */ + QString m_storagePrefix; + + /// true if the library had an extract/excludes section (even empty) + bool applyExcludes = false; + + /// a list of files that shouldn't be extracted from the library + QStringList extract_excludes; + + /// native suffixes per OS + QMap m_native_classifiers; + + /// true if the library had a rules section (even empty) + bool applyRules = false; + + /// rules associated with the library + QList> m_rules; + + /// MOJANG: container with Mojang style download info + MojangLibraryDownloadInfoPtr m_mojang_downloads; +}; diff --git a/logic/minecraft/MinecraftProfile.cpp b/logic/minecraft/MinecraftProfile.cpp index be847050..0cf8b548 100644 --- a/logic/minecraft/MinecraftProfile.cpp +++ b/logic/minecraft/MinecraftProfile.cpp @@ -230,9 +230,9 @@ bool MinecraftProfile::revertToVanilla() return true; } -QList > MinecraftProfile::getActiveNormalLibs() +QList > MinecraftProfile::getActiveNormalLibs() { - QList > output; + QList > output; for (auto lib : libraries) { if (lib->isActive() && !lib->isNative()) @@ -251,9 +251,9 @@ QList > MinecraftProfile::getActiveNormalLibs() return output; } -QList > MinecraftProfile::getActiveNativeLibs() +QList > MinecraftProfile::getActiveNativeLibs() { - QList > output; + QList > output; for (auto lib : libraries) { if (lib->isActive() && lib->isNative()) diff --git a/logic/minecraft/MinecraftProfile.h b/logic/minecraft/MinecraftProfile.h index 25663c74..84d3ce3b 100644 --- a/logic/minecraft/MinecraftProfile.h +++ b/logic/minecraft/MinecraftProfile.h @@ -21,7 +21,7 @@ #include #include -#include "RawLibrary.h" +#include "Library.h" #include "VersionFile.h" #include "JarMod.h" @@ -93,10 +93,10 @@ public: public: /// get all java libraries that belong to the classpath - QList getActiveNormalLibs(); + QList getActiveNormalLibs(); /// get all native libraries that need to be available to the process - QList getActiveNativeLibs(); + QList getActiveNativeLibs(); /// get file ID of the patch file at # QString versionFileId(const int index) const; @@ -161,10 +161,10 @@ public: /* data */ QString appletClass; /// the list of libs - both active and inactive, native and java - QList libraries; + QList libraries; /// same, but only vanilla. - QList vanillaLibraries; + QList vanillaLibraries; /// traits, collected from all the version files (version files can only add) QSet traits; diff --git a/logic/minecraft/MojangDownloadInfo.h b/logic/minecraft/MojangDownloadInfo.h new file mode 100644 index 00000000..780318b8 --- /dev/null +++ b/logic/minecraft/MojangDownloadInfo.h @@ -0,0 +1,92 @@ +#pragma once +#include +#include + +class MojangDownloadInfo +{ + friend class MojangVersionFormat; +public: + QString getUrl() + { + return m_url; + } + + QString getSha1() + { + return m_sha1; + } + + int getSize() + { + return m_size; + } + +protected: + /// Local filesystem path. WARNING: not used, only here so we can pass through mojang files unmolested! + QString m_path; + /// absolute URL of this file + QString m_url; + /// sha-1 checksum of the file + QString m_sha1; + /// size of the file in bytes + int m_size; +}; + +typedef std::shared_ptr MojangDownloadInfoPtr; + +class MojangLibraryDownloadInfo +{ + friend class MojangVersionFormat; +public: + MojangDownloadInfo *getDownloadInfo(QString classifier) + { + if (classifier.isNull()) + { + return artifact.get(); + } + + return classifiers[classifier].get(); + } +private: + MojangDownloadInfoPtr artifact; + QMap classifiers; +}; + +typedef std::shared_ptr MojangLibraryDownloadInfoPtr; + +class MojangAssetIndexInfo : public MojangDownloadInfo +{ + friend class MojangVersionFormat; +public: + MojangAssetIndexInfo() + { + } + + MojangAssetIndexInfo(QString id) + { + m_id = id; + m_url = "https://s3.amazonaws.com/Minecraft.Download/indexes/" + id + ".json"; + m_known = false; + } + + int getTotalSize() + { + return m_totalSize; + } + + QString getId() + { + return m_id; + } + + bool sizeAndHashKnown() + { + return m_known; + } + +protected: + int m_totalSize; + QString m_id; + bool m_known = true; +}; +typedef std::shared_ptr MojangAssetIndexInfoPtr; diff --git a/logic/minecraft/MojangVersionFormat.cpp b/logic/minecraft/MojangVersionFormat.cpp index 4d6f205b..1b95a0ba 100644 --- a/logic/minecraft/MojangVersionFormat.cpp +++ b/logic/minecraft/MojangVersionFormat.cpp @@ -18,6 +18,37 @@ static void readString(const QJsonObject &root, const QString &key, QString &var } } +MojangAssetIndexInfoPtr MojangVersionFormat::assetIndexFromJson(const QJsonObject &obj) +{ + auto out = std::make_shared(); + // optional, not used + readString(obj, "path", out->m_path); + // required! + out->m_sha1 = requireString(obj, "sha1"); + out->m_url = requireString(obj, "url"); + out->m_size = requireInteger(obj, "size"); + out->m_totalSize = requireInteger(obj, "totalSize"); + out->m_id = requireString(obj, "id"); + // out->m_known = true; + return out; +} + +QJsonObject MojangVersionFormat::assetIndexToJson(MojangAssetIndexInfoPtr info) +{ + QJsonObject out; + if(!info->m_path.isNull()) + { + out.insert("path", info->m_path); + } + out.insert("sha1", info->m_sha1); + out.insert("size", info->m_size); + out.insert("url", info->m_url); + out.insert("totalSize", info->m_totalSize); + out.insert("id", info->m_id); + return out; +} + + VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc, const QString &filename) { VersionFilePtr out(new VersionFile()); @@ -43,6 +74,10 @@ VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc readString(root, "minecraftArguments", out->overwriteMinecraftArguments); readString(root, "type", out->type); + if(root.contains("assetIndex")) + { + out->mojangAssetIndex = assetIndexFromJson(requireObject(root, "assetIndex")); + } readString(root, "assets", out->assets); out->m_releaseTime = timeFromS3Time(root.value("releaseTime").toString("")); @@ -67,14 +102,24 @@ VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc { auto libObj = requireObject(libVal); - auto lib = OneSixVersionFormat::libraryFromJson(libObj, filename); + auto lib = MojangVersionFormat::libraryFromJson(libObj, filename); out->addLibs.append(lib); } } + if(root.contains("downloads")) + { + auto downloadsObj = requireObject(root, "downloads"); + for(auto iter = downloadsObj.begin(); iter != downloadsObj.end(); iter++) + { + auto classifier = iter.key(); + auto classifierObj = requireObject(iter.value()); + out->mojangDownloads[classifier] = downloadInfoFromJson(classifierObj); + } + } return out; } -static QJsonDocument versionFileToJson(VersionFilePtr patch) +QJsonDocument MojangVersionFormat::versionFileToJson(VersionFilePtr patch) { QJsonObject root; writeString(root, "id", patch->id); @@ -95,10 +140,23 @@ static QJsonDocument versionFileToJson(VersionFilePtr patch) QJsonArray array; for (auto value: patch->addLibs) { - array.append(OneSixVersionFormat::libraryToJson(value.get())); + array.append(MojangVersionFormat::libraryToJson(value.get())); } root.insert("libraries", array); } + if(patch->mojangAssetIndex && patch->mojangAssetIndex->sizeAndHashKnown()) + { + root.insert("assetIndex", MojangVersionFormat::assetIndexToJson(patch->mojangAssetIndex)); + } + if(patch->mojangDownloads.size()) + { + QJsonObject downloadsOut; + for(auto iter = patch->mojangDownloads.begin(); iter != patch->mojangDownloads.end(); iter++) + { + downloadsOut.insert(iter.key(), downloadInfoToJson(iter.value())); + } + root.insert("downloads", downloadsOut); + } // write the contents to a json document. { QJsonDocument out; @@ -133,3 +191,244 @@ QJsonDocument MojangVersionFormat::profilePatchToJson(const ProfilePatchPtr &pat } throw VersionIncomplete(QObject::tr("Unhandled object type while processing %1").arg(patch->getPatchName())); } + +/* +class MojangDownloadInfo +{ + friend class MojangVersionFormat; +public: + QString getUrl() + { + return m_url; + } + + QString getSha1() + { + return m_sha1; + } + + int getSize() + { + return m_size; + } + +protected: + QString m_url; + QString m_sha1; + int m_size; +}; +*/ + +MojangDownloadInfoPtr MojangVersionFormat::downloadInfoFromJson(const QJsonObject &obj) +{ + auto out = std::make_shared(); + // optional, not used + readString(obj, "path", out->m_path); + // required! + out->m_sha1 = requireString(obj, "sha1"); + out->m_url = requireString(obj, "url"); + out->m_size = requireInteger(obj, "size"); + return out; +} + +/* +class MojangLibraryDownloadInfo +{ + friend class MojangVersionFormat; +public: + MojangDownloadInfo getDownloadInfo(QString classifier) + { + if (classifier.isNull()) + { + return artifact; + } + + return classifiers[classifier]; + } +private: + MojangDownloadInfo artifact; + QMap classifiers; +}; +*/ + +/* + "downloads": { + "artifact": { + "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar", + "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33", + "size": 22, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar" + }, + "classifiers": { + "natives-linux": { + "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", + "sha1": "931074f46c795d2f7b30ed6395df5715cfd7675b", + "size": 578680, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar" + }, + "natives-osx": { + "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar", + "sha1": "bcab850f8f487c3f4c4dbabde778bb82bd1a40ed", + "size": 426822, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar" + }, + "natives-windows": { + "path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar", + "sha1": "b84d5102b9dbfabfeb5e43c7e2828d98a7fc80e0", + "size": 613748, + "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar" + } + } + }, +*/ + + +MojangLibraryDownloadInfoPtr MojangVersionFormat::libDownloadInfoFromJson(const QJsonObject &libObj) +{ + auto out = std::make_shared(); + auto dlObj = requireObject(libObj.value("downloads")); + if(dlObj.contains("artifact")) + { + out->artifact = downloadInfoFromJson(requireObject(dlObj, "artifact")); + } + if(dlObj.contains("classifiers")) + { + auto classifiersObj = requireObject(dlObj, "classifiers"); + for(auto iter = classifiersObj.begin(); iter != classifiersObj.end(); iter++) + { + auto classifier = iter.key(); + auto classifierObj = requireObject(iter.value()); + out->classifiers[classifier] = downloadInfoFromJson(classifierObj); + } + } + return out; +} + +LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename) +{ + LibraryPtr out(new Library()); + 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); + 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); + } + if (libObj.contains("downloads")) + { + out->m_mojang_downloads = libDownloadInfoFromJson(libObj); + } + return out; +} + +QJsonObject MojangVersionFormat::downloadInfoToJson(MojangDownloadInfoPtr info) +{ + QJsonObject out; + if(!info->m_path.isNull()) + { + out.insert("path", info->m_path); + } + out.insert("sha1", info->m_sha1); + out.insert("size", info->m_size); + out.insert("url", info->m_url); + return out; +} + +QJsonObject MojangVersionFormat::libDownloadInfoToJson(MojangLibraryDownloadInfoPtr libinfo) +{ + QJsonObject out; + if(libinfo->artifact) + { + out.insert("artifact", downloadInfoToJson(libinfo->artifact)); + } + if(libinfo->classifiers.size()) + { + QJsonObject classifiersOut; + for(auto iter = libinfo->classifiers.begin(); iter != libinfo->classifiers.end(); iter++) + { + classifiersOut.insert(iter.key(), downloadInfoToJson(iter.value())); + } + out.insert("classifiers", classifiersOut); + } + return out; +} + +QJsonObject MojangVersionFormat::libraryToJson(Library *library) +{ + QJsonObject libRoot; + libRoot.insert("name", (QString)library->m_name); + 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); + } + if(library->m_mojang_downloads) + { + auto downloadsObj = libDownloadInfoToJson(library->m_mojang_downloads); + libRoot.insert("downloads", downloadsObj); + } + return libRoot; +} diff --git a/logic/minecraft/MojangVersionFormat.h b/logic/minecraft/MojangVersionFormat.h index cd87d68e..67066647 100644 --- a/logic/minecraft/MojangVersionFormat.h +++ b/logic/minecraft/MojangVersionFormat.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "multimc_logic_export.h" @@ -11,4 +12,18 @@ public: // version files / profile patches static VersionFilePtr versionFileFromJson(const QJsonDocument &doc, const QString &filename); static QJsonDocument profilePatchToJson(const ProfilePatchPtr &patch); + + // libraries + static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename); + static QJsonObject libraryToJson(Library *library); + +private: + static QJsonDocument versionFileToJson(VersionFilePtr patch); + + static MojangAssetIndexInfoPtr assetIndexFromJson (const QJsonObject &obj); + static MojangDownloadInfoPtr downloadInfoFromJson (const QJsonObject &obj); + static MojangLibraryDownloadInfoPtr libDownloadInfoFromJson (const QJsonObject &libObj); + static QJsonObject assetIndexToJson (MojangAssetIndexInfoPtr assetidxinfo); + static QJsonObject libDownloadInfoToJson (MojangLibraryDownloadInfoPtr libinfo); + static QJsonObject downloadInfoToJson (MojangDownloadInfoPtr info); }; diff --git a/logic/minecraft/OneSixRule.cpp b/logic/minecraft/OneSixRule.cpp deleted file mode 100644 index 3f4a6bb9..00000000 --- a/logic/minecraft/OneSixRule.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include "OneSixRule.h" - -RuleAction RuleAction_fromString(QString name) -{ - if (name == "allow") - return Allow; - if (name == "disallow") - return Disallow; - return Defer; -} - -QList> rulesFromJsonV4(const QJsonObject &objectWithRules) -{ - QList> rules; - auto rulesVal = objectWithRules.value("rules"); - if (!rulesVal.isArray()) - return rules; - - QJsonArray ruleList = rulesVal.toArray(); - for (auto ruleVal : ruleList) - { - std::shared_ptr rule; - if (!ruleVal.isObject()) - continue; - auto ruleObj = ruleVal.toObject(); - auto actionVal = ruleObj.value("action"); - if (!actionVal.isString()) - continue; - auto action = RuleAction_fromString(actionVal.toString()); - if (action == Defer) - continue; - - auto osVal = ruleObj.value("os"); - if (!osVal.isObject()) - { - // add a new implicit action rule - rules.append(ImplicitRule::create(action)); - continue; - } - - auto osObj = osVal.toObject(); - auto osNameVal = osObj.value("name"); - if (!osNameVal.isString()) - continue; - OpSys requiredOs = OpSys_fromString(osNameVal.toString()); - QString versionRegex = osObj.value("version").toString(); - // add a new OS rule - rules.append(OsRule::create(action, requiredOs, versionRegex)); - } - return rules; -} - -QJsonObject ImplicitRule::toJson() -{ - QJsonObject ruleObj; - ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow")); - return ruleObj; -} - -QJsonObject OsRule::toJson() -{ - QJsonObject ruleObj; - ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow")); - QJsonObject osObj; - { - osObj.insert("name", OpSys_toString(m_system)); - if(!m_version_regexp.isEmpty()) - { - osObj.insert("version", m_version_regexp); - } - } - ruleObj.insert("os", osObj); - return ruleObj; -} - diff --git a/logic/minecraft/OneSixRule.h b/logic/minecraft/OneSixRule.h deleted file mode 100644 index f564c3fe..00000000 --- a/logic/minecraft/OneSixRule.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include -#include -#include "OpSys.h" - -class RawLibrary; -class Rule; - -enum RuleAction -{ - Allow, - Disallow, - Defer -}; - -QList> rulesFromJsonV4(const QJsonObject &objectWithRules); - -class Rule -{ -protected: - RuleAction m_result; - virtual bool applies(const RawLibrary *parent) = 0; - -public: - Rule(RuleAction result) : m_result(result) - { - } - virtual ~Rule() {}; - virtual QJsonObject toJson() = 0; - RuleAction apply(const RawLibrary *parent) - { - if (applies(parent)) - return m_result; - else - return Defer; - } -}; - -class OsRule : public Rule -{ -private: - // the OS - OpSys m_system; - // the OS version regexp - QString m_version_regexp; - -protected: - virtual bool applies(const RawLibrary *) - { - return (m_system == currentSystem); - } - OsRule(RuleAction result, OpSys system, QString version_regexp) - : Rule(result), m_system(system), m_version_regexp(version_regexp) - { - } - -public: - virtual QJsonObject toJson(); - static std::shared_ptr create(RuleAction result, OpSys system, - QString version_regexp) - { - return std::shared_ptr(new OsRule(result, system, version_regexp)); - } -}; - -class ImplicitRule : public Rule -{ -protected: - virtual bool applies(const RawLibrary *) - { - return true; - } - ImplicitRule(RuleAction result) : Rule(result) - { - } - -public: - virtual QJsonObject toJson(); - static std::shared_ptr create(RuleAction result) - { - return std::shared_ptr(new ImplicitRule(result)); - } -}; diff --git a/logic/minecraft/ProfileUtils.cpp b/logic/minecraft/ProfileUtils.cpp index 096f43bf..30e83a1f 100644 --- a/logic/minecraft/ProfileUtils.cpp +++ b/logic/minecraft/ProfileUtils.cpp @@ -153,9 +153,9 @@ VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo) void removeLwjglFromPatch(VersionFilePtr patch) { - auto filter = [](QList& libs) + auto filter = [](QList& libs) { - QList filteredLibs; + QList filteredLibs; for (auto lib : libs) { if (!g_VersionFilterData.lwjglWhitelist.contains(lib->artifactPrefix())) diff --git a/logic/minecraft/ProfileUtils.h b/logic/minecraft/ProfileUtils.h index 1e6d6a8f..267fd42b 100644 --- a/logic/minecraft/ProfileUtils.h +++ b/logic/minecraft/ProfileUtils.h @@ -1,5 +1,5 @@ #pragma once -#include "RawLibrary.h" +#include "Library.h" #include "VersionFile.h" namespace ProfileUtils diff --git a/logic/minecraft/RawLibrary.cpp b/logic/minecraft/RawLibrary.cpp deleted file mode 100644 index 735f5b0a..00000000 --- a/logic/minecraft/RawLibrary.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include "RawLibrary.h" -#include - -QStringList RawLibrary::files() const -{ - QStringList retval; - QString storage = storageSuffix(); - if (storage.contains("${arch}")) - { - QString cooked_storage = storage; - cooked_storage.replace("${arch}", "32"); - retval.append(cooked_storage); - cooked_storage = storage; - cooked_storage.replace("${arch}", "64"); - retval.append(cooked_storage); - } - else - retval.append(storage); - return retval; -} - -bool RawLibrary::filesExist(const QDir &base) const -{ - auto libFiles = files(); - for(auto file: libFiles) - { - QFileInfo info(base, file); - qWarning() << info.absoluteFilePath() << "doesn't exist"; - if (!info.exists()) - return false; - } - return true; -} - -QString RawLibrary::url() const -{ - if (!m_absolute_url.isEmpty()) - { - return m_absolute_url; - } - - if (m_base_url.isEmpty()) - { - return QString("https://" + URLConstants::LIBRARY_BASE) + storageSuffix(); - } - - if(m_base_url.endsWith('/')) - { - return m_base_url + storageSuffix(); - } - else - { - return m_base_url + QChar('/') + storageSuffix(); - } -} - -bool RawLibrary::isActive() const -{ - bool result = true; - if (m_rules.empty()) - { - result = true; - } - else - { - RuleAction ruleResult = Disallow; - for (auto rule : m_rules) - { - RuleAction temp = rule->apply(this); - if (temp != Defer) - ruleResult = temp; - } - result = result && (ruleResult == Allow); - } - if (isNative()) - { - result = result && m_native_classifiers.contains(currentSystem); - } - return result; -} - -void RawLibrary::setStoragePrefix(QString prefix) -{ - m_storagePrefix = prefix; -} - -QString RawLibrary::defaultStoragePrefix() -{ - return "libraries/"; -} - -QString RawLibrary::storagePrefix() const -{ - if(m_storagePrefix.isEmpty()) - { - return defaultStoragePrefix(); - } - return m_storagePrefix; -} - -QString RawLibrary::storageSuffix() const -{ - // non-native? use only the gradle specifier - if (!isNative()) - { - return m_name.toPath(); - } - - // otherwise native, override classifiers. Mojang HACK! - GradleSpecifier nativeSpec = m_name; - if (m_native_classifiers.contains(currentSystem)) - { - nativeSpec.setClassifier(m_native_classifiers[currentSystem]); - } - else - { - nativeSpec.setClassifier("INVALID"); - } - return nativeSpec.toPath(); -} - -QString RawLibrary::storagePath() const -{ - return FS::PathCombine(storagePrefix(), storageSuffix()); -} - -bool RawLibrary::storagePathIsDefault() const -{ - return m_storagePrefix.isEmpty(); -} diff --git a/logic/minecraft/RawLibrary.h b/logic/minecraft/RawLibrary.h deleted file mode 100644 index a8d3ef0d..00000000 --- a/logic/minecraft/RawLibrary.h +++ /dev/null @@ -1,187 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include - -#include "OneSixRule.h" -#include "minecraft/OpSys.h" -#include "GradleSpecifier.h" -#include "net/URLConstants.h" - -class RawLibrary; -typedef std::shared_ptr RawLibraryPtr; - -class RawLibrary -{ - friend class OneSixVersionFormat; - friend class MojangVersionFormat; -public: - RawLibrary() - { - } - RawLibrary(const QString &name) - { - m_name = name; - } - /// limited copy without some data. TODO: why? - static RawLibraryPtr limitedCopy(RawLibraryPtr base) - { - auto newlib = std::make_shared(); - newlib->m_name = base->m_name; - newlib->m_base_url = base->m_base_url; - newlib->m_hint = base->m_hint; - newlib->m_absolute_url = base->m_absolute_url; - newlib->extract_excludes = base->extract_excludes; - newlib->m_native_classifiers = base->m_native_classifiers; - newlib->m_rules = base->m_rules; - newlib->m_storagePrefix = base->m_storagePrefix; - return newlib; - } - -public: /* methods */ - /// Returns the raw name field - const GradleSpecifier & rawName() const - { - return m_name; - } - - void setRawName(const GradleSpecifier & spec) - { - m_name = spec; - } - - void setClassifier(const QString & spec) - { - m_name.setClassifier(spec); - } - - /// returns the full group and artifact prefix - QString artifactPrefix() const - { - return m_name.artifactPrefix(); - } - - /// get the artifact ID - QString artifactId() const - { - return m_name.artifactId(); - } - - /// get the artifact version - QString version() const - { - return m_name.version(); - } - - /// Returns true if the library is native - bool isNative() const - { - return m_native_classifiers.size() != 0; - } - - void setStoragePrefix(QString prefix = QString()); - - /// the default storage prefix used by MultiMC - static QString defaultStoragePrefix(); - - bool storagePathIsDefault() const; - - /// Get the prefix - root of the storage to be used - QString storagePrefix() const; - - /// Get the relative path where the library should be saved - QString storageSuffix() const; - - /// Get the absolute path where the library should be saved - QString storagePath() const; - - /// Set the url base for downloads - void setBaseUrl(const QString &base_url) - { - m_base_url = base_url; - } - - /// List of files this library describes. Required because of platform-specificness of native libs - QStringList files() const; - - /// List Shortcut for checking if all the above files exist - bool filesExist(const QDir &base) const; - - void setAbsoluteUrl(const QString &absolute_url) - { - m_absolute_url = absolute_url; - } - - QString absoluteUrl() const - { - return m_absolute_url; - } - - void setHint(const QString &hint) - { - m_hint = hint; - } - - QString hint() const - { - return m_hint; - } - - /// Set the load rules - void setRules(QList> rules) - { - m_rules = rules; - } - - /// Returns true if the library should be loaded (or extracted, in case of natives) - bool isActive() const; - - /// Get the URL to download the library from - QString url() const; - -protected: /* data */ - /// the basic gradle dependency specifier. - GradleSpecifier m_name; - /// where to store the lib locally - QString m_storage_path; - /// is this lib actually active on the current OS? - bool m_is_active = false; - - /// DEPRECATED URL prefix of the maven repo where the file can be downloaded - QString m_base_url; - - /// DEPRECATED: MultiMC-specific absolute URL. takes precedence over the implicit maven repo URL, if defined - QString m_absolute_url; - -public: /* data */ - /** - * MultiMC-specific type hint - modifies how the library is treated - */ - QString m_hint; - - /** - * storage - by default the local libraries folder in multimc, but could be elsewhere - * MultiMC specific, because of FTB. - */ - QString m_storagePrefix; - - /// true if the library had an extract/excludes section (even empty) - bool applyExcludes = false; - - /// a list of files that shouldn't be extracted from the library - QStringList extract_excludes; - - /// native suffixes per OS - QMap m_native_classifiers; - - /// true if the library had a rules section (even empty) - bool applyRules = false; - - /// rules associated with the library - QList> m_rules; -}; diff --git a/logic/minecraft/Rule.cpp b/logic/minecraft/Rule.cpp new file mode 100644 index 00000000..c8ba297b --- /dev/null +++ b/logic/minecraft/Rule.cpp @@ -0,0 +1,93 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "Rule.h" + +RuleAction RuleAction_fromString(QString name) +{ + if (name == "allow") + return Allow; + if (name == "disallow") + return Disallow; + return Defer; +} + +QList> rulesFromJsonV4(const QJsonObject &objectWithRules) +{ + QList> rules; + auto rulesVal = objectWithRules.value("rules"); + if (!rulesVal.isArray()) + return rules; + + QJsonArray ruleList = rulesVal.toArray(); + for (auto ruleVal : ruleList) + { + std::shared_ptr rule; + if (!ruleVal.isObject()) + continue; + auto ruleObj = ruleVal.toObject(); + auto actionVal = ruleObj.value("action"); + if (!actionVal.isString()) + continue; + auto action = RuleAction_fromString(actionVal.toString()); + if (action == Defer) + continue; + + auto osVal = ruleObj.value("os"); + if (!osVal.isObject()) + { + // add a new implicit action rule + rules.append(ImplicitRule::create(action)); + continue; + } + + auto osObj = osVal.toObject(); + auto osNameVal = osObj.value("name"); + if (!osNameVal.isString()) + continue; + OpSys requiredOs = OpSys_fromString(osNameVal.toString()); + QString versionRegex = osObj.value("version").toString(); + // add a new OS rule + rules.append(OsRule::create(action, requiredOs, versionRegex)); + } + return rules; +} + +QJsonObject ImplicitRule::toJson() +{ + QJsonObject ruleObj; + ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow")); + return ruleObj; +} + +QJsonObject OsRule::toJson() +{ + QJsonObject ruleObj; + ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow")); + QJsonObject osObj; + { + osObj.insert("name", OpSys_toString(m_system)); + if(!m_version_regexp.isEmpty()) + { + osObj.insert("version", m_version_regexp); + } + } + ruleObj.insert("os", osObj); + return ruleObj; +} + diff --git a/logic/minecraft/Rule.h b/logic/minecraft/Rule.h new file mode 100644 index 00000000..c8bf6eaa --- /dev/null +++ b/logic/minecraft/Rule.h @@ -0,0 +1,101 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include "OpSys.h" + +class Library; +class Rule; + +enum RuleAction +{ + Allow, + Disallow, + Defer +}; + +QList> rulesFromJsonV4(const QJsonObject &objectWithRules); + +class Rule +{ +protected: + RuleAction m_result; + virtual bool applies(const Library *parent) = 0; + +public: + Rule(RuleAction result) : m_result(result) + { + } + virtual ~Rule() {}; + virtual QJsonObject toJson() = 0; + RuleAction apply(const Library *parent) + { + if (applies(parent)) + return m_result; + else + return Defer; + } +}; + +class OsRule : public Rule +{ +private: + // the OS + OpSys m_system; + // the OS version regexp + QString m_version_regexp; + +protected: + virtual bool applies(const Library *) + { + return (m_system == currentSystem); + } + OsRule(RuleAction result, OpSys system, QString version_regexp) + : Rule(result), m_system(system), m_version_regexp(version_regexp) + { + } + +public: + virtual QJsonObject toJson(); + static std::shared_ptr create(RuleAction result, OpSys system, + QString version_regexp) + { + return std::shared_ptr(new OsRule(result, system, version_regexp)); + } +}; + +class ImplicitRule : public Rule +{ +protected: + virtual bool applies(const Library *) + { + return true; + } + ImplicitRule(RuleAction result) : Rule(result) + { + } + +public: + virtual QJsonObject toJson(); + static std::shared_ptr create(RuleAction result) + { + return std::shared_ptr(new ImplicitRule(result)); + } +}; diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp index 08f53a37..410f6659 100644 --- a/logic/minecraft/VersionFile.cpp +++ b/logic/minecraft/VersionFile.cpp @@ -4,7 +4,7 @@ #include #include "minecraft/VersionFile.h" -#include "minecraft/RawLibrary.h" +#include "minecraft/Library.h" #include "minecraft/MinecraftProfile.h" #include "minecraft/JarMod.h" #include "ParseUtils.h" @@ -12,7 +12,7 @@ #include "VersionBuildError.h" #include -int findLibraryByName(QList haystack, const GradleSpecifier &needle) +int findLibraryByName(QList haystack, const GradleSpecifier &needle) { int retval = -1; for (int i = 0; i < haystack.size(); ++i) @@ -112,10 +112,10 @@ void VersionFile::applyTo(MinecraftProfile *version) version->traits.unite(traits); if (shouldOverwriteLibs) { - QList libs; + QList libs; for (auto lib : overwriteLibs) { - libs.append(RawLibrary::limitedCopy(lib)); + libs.append(Library::limitedCopy(lib)); } if (isMinecraftVersion()) { @@ -130,14 +130,14 @@ void VersionFile::applyTo(MinecraftProfile *version) // library not found? just add it. if (index < 0) { - version->libraries.append(RawLibrary::limitedCopy(addedLibrary)); + version->libraries.append(Library::limitedCopy(addedLibrary)); continue; } auto existingLibrary = version->libraries.at(index); // if we are higher it means we should update if (Version(addedLibrary->version()) > Version(existingLibrary->version())) { - auto library = RawLibrary::limitedCopy(addedLibrary); + auto library = Library::limitedCopy(addedLibrary); version->libraries.replace(index, library); } } diff --git a/logic/minecraft/VersionFile.h b/logic/minecraft/VersionFile.h index 64bec731..5e722dbf 100644 --- a/logic/minecraft/VersionFile.h +++ b/logic/minecraft/VersionFile.h @@ -7,9 +7,9 @@ #include #include "minecraft/OpSys.h" -#include "minecraft/OneSixRule.h" +#include "minecraft/Rule.h" #include "ProfilePatch.h" -#include "RawLibrary.h" +#include "Library.h" #include "JarMod.h" class MinecraftProfile; @@ -169,16 +169,22 @@ public: /* data */ /// MultiMC: override list of libraries (replaces the previously assembled lists) bool shouldOverwriteLibs = false; - QList overwriteLibs; + QList overwriteLibs; /// Mojang: list of libraries to add to the version - QList addLibs; + QList addLibs; /// MultiMC: list of attached traits of this version file - used to enable features QSet traits; /// MultiMC: list of jar mods added to this version QList jarMods; + + // Mojang: list of 'downloads' - client jar, server jar, windows server exe, maybe more. + QMap mojangDownloads; + + // Mojang: extended asset index download information + MojangAssetIndexInfoPtr mojangAssetIndex; }; diff --git a/logic/minecraft/ftb/FTBProfileStrategy.cpp b/logic/minecraft/ftb/FTBProfileStrategy.cpp index c4bfa27b..a86cdee3 100644 --- a/logic/minecraft/ftb/FTBProfileStrategy.cpp +++ b/logic/minecraft/ftb/FTBProfileStrategy.cpp @@ -60,7 +60,7 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches() file->id.clear(); for(auto addLib: file->addLibs) { - addLib->m_hint = "local"; + addLib->setHint("local"); addLib->setStoragePrefix(nativeInstance->librariesPath().absolutePath()); } file->fileId = "org.multimc.ftb.pack"; diff --git a/logic/minecraft/liteloader/LiteLoaderInstaller.cpp b/logic/minecraft/liteloader/LiteLoaderInstaller.cpp index 81e51cd7..25297fa4 100644 --- a/logic/minecraft/liteloader/LiteLoaderInstaller.cpp +++ b/logic/minecraft/liteloader/LiteLoaderInstaller.cpp @@ -21,7 +21,7 @@ #include #include "minecraft/MinecraftProfile.h" -#include "minecraft/RawLibrary.h" +#include "minecraft/Library.h" #include "minecraft/onesix/OneSixInstance.h" #include #include "minecraft/liteloader/LiteLoaderVersionList.h" @@ -50,14 +50,14 @@ bool LiteLoaderInstaller::add(OneSixInstance *to) QJsonArray libraries; - for (auto rawLibrary : m_version->libraries) + for (auto Library : m_version->libraries) { - libraries.append(OneSixVersionFormat::libraryToJson(rawLibrary.get())); + libraries.append(OneSixVersionFormat::libraryToJson(Library.get())); } // liteloader { - RawLibrary liteloaderLib("com.mumfrey:liteloader:" + m_version->version); + Library 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 = OneSixVersionFormat::libraryToJson(&liteloaderLib); libraries.append(llLibObj); diff --git a/logic/minecraft/liteloader/LiteLoaderVersionList.h b/logic/minecraft/liteloader/LiteLoaderVersionList.h index 43bb270d..1dba4b6a 100644 --- a/logic/minecraft/liteloader/LiteLoaderVersionList.h +++ b/logic/minecraft/liteloader/LiteLoaderVersionList.h @@ -23,7 +23,7 @@ #include "BaseVersionList.h" #include "tasks/Task.h" #include "net/NetJob.h" -#include +#include #include "multimc_logic_export.h" @@ -58,7 +58,7 @@ public: int timestamp; bool isLatest; QString tweakClass; - QList libraries; + QList libraries; // meta QString defaultUrl; diff --git a/logic/minecraft/onesix/OneSixUpdate.cpp b/logic/minecraft/onesix/OneSixUpdate.cpp index 3fd66920..da3bd504 100644 --- a/logic/minecraft/onesix/OneSixUpdate.cpp +++ b/logic/minecraft/onesix/OneSixUpdate.cpp @@ -28,7 +28,7 @@ #include "BaseInstance.h" #include "minecraft/MinecraftVersionList.h" #include "minecraft/MinecraftProfile.h" -#include "minecraft/RawLibrary.h" +#include "minecraft/Library.h" #include "minecraft/forge/ForgeMirrors.h" #include "net/URLConstants.h" #include "minecraft/AssetsUtils.h" @@ -213,7 +213,7 @@ void OneSixUpdate::jarlibStart() auto metacache = ENV.metacache(); QList ForgeLibs; - QList brokenLocalLibs; + QList brokenLocalLibs; for (auto lib : libs) { diff --git a/logic/minecraft/onesix/OneSixVersionFormat.cpp b/logic/minecraft/onesix/OneSixVersionFormat.cpp index 45eef278..4ccf6e78 100644 --- a/logic/minecraft/onesix/OneSixVersionFormat.cpp +++ b/logic/minecraft/onesix/OneSixVersionFormat.cpp @@ -4,6 +4,7 @@ #include "minecraft/ParseUtils.h" #include #include +#include using namespace Json; @@ -24,99 +25,22 @@ static QString readStringRet(const QJsonObject &root, const QString &key) return QString(); } -RawLibraryPtr OneSixVersionFormat::libraryFromJson(const QJsonObject &libObj, const QString &filename) +LibraryPtr 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); + LibraryPtr out = MojangVersionFormat::libraryFromJson(libObj, filename); 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 OneSixVersionFormat::libraryToJson(Library *library) { - QJsonObject libRoot; - libRoot.insert("name", (QString)library->m_name); + QJsonObject libRoot = MojangVersionFormat::libraryToJson(library); 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; } @@ -253,7 +177,7 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc template struct libraryConversion { - static QJsonObject convert(std::shared_ptr &value) + static QJsonObject convert(std::shared_ptr &value) { return OneSixVersionFormat::libraryToJson(value.get()); } diff --git a/logic/minecraft/onesix/OneSixVersionFormat.h b/logic/minecraft/onesix/OneSixVersionFormat.h index 9d16cced..45a961e4 100644 --- a/logic/minecraft/onesix/OneSixVersionFormat.h +++ b/logic/minecraft/onesix/OneSixVersionFormat.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include class OneSixVersionFormat @@ -16,8 +16,8 @@ public: static QJsonDocument profilePatchToJson(const ProfilePatchPtr &patch, bool saveOrder); // libraries - static RawLibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename); - static QJsonObject libraryToJson(RawLibrary *library); + static LibraryPtr libraryFromJson(const QJsonObject &libObj, const QString &filename); + static QJsonObject libraryToJson(Library *library); // jar mods static JarmodPtr jarModFromJson(const QJsonObject &libObj, const QString &filename, const QString &originalName); -- cgit v1.2.3