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/RawLibrary.cpp b/logic/minecraft/Library.cpp similarity index 81% rename from logic/minecraft/RawLibrary.cpp rename to logic/minecraft/Library.cpp index 735f5b0a..9a1d2cc7 100644 --- a/logic/minecraft/RawLibrary.cpp +++ b/logic/minecraft/Library.cpp @@ -1,7 +1,7 @@ -#include "RawLibrary.h" +#include "Library.h" #include -QStringList RawLibrary::files() const +QStringList Library::files() const { QStringList retval; QString storage = storageSuffix(); @@ -19,7 +19,7 @@ QStringList RawLibrary::files() const return retval; } -bool RawLibrary::filesExist(const QDir &base) const +bool Library::filesExist(const QDir &base) const { auto libFiles = files(); for(auto file: libFiles) @@ -32,7 +32,7 @@ bool RawLibrary::filesExist(const QDir &base) const return true; } -QString RawLibrary::url() const +QString Library::url() const { if (!m_absolute_url.isEmpty()) { @@ -54,7 +54,7 @@ QString RawLibrary::url() const } } -bool RawLibrary::isActive() const +bool Library::isActive() const { bool result = true; if (m_rules.empty()) @@ -79,17 +79,17 @@ bool RawLibrary::isActive() const return result; } -void RawLibrary::setStoragePrefix(QString prefix) +void Library::setStoragePrefix(QString prefix) { m_storagePrefix = prefix; } -QString RawLibrary::defaultStoragePrefix() +QString Library::defaultStoragePrefix() { return "libraries/"; } -QString RawLibrary::storagePrefix() const +QString Library::storagePrefix() const { if(m_storagePrefix.isEmpty()) { @@ -98,7 +98,7 @@ QString RawLibrary::storagePrefix() const return m_storagePrefix; } -QString RawLibrary::storageSuffix() const +QString Library::storageSuffix() const { // non-native? use only the gradle specifier if (!isNative()) @@ -119,12 +119,12 @@ QString RawLibrary::storageSuffix() const return nativeSpec.toPath(); } -QString RawLibrary::storagePath() const +QString Library::storagePath() const { return FS::PathCombine(storagePrefix(), storageSuffix()); } -bool RawLibrary::storagePathIsDefault() const +bool Library::storagePathIsDefault() const { return m_storagePrefix.isEmpty(); } diff --git a/logic/minecraft/RawLibrary.h b/logic/minecraft/Library.h similarity index 90% rename from logic/minecraft/RawLibrary.h rename to logic/minecraft/Library.h index a8d3ef0d..7ae126a9 100644 --- a/logic/minecraft/RawLibrary.h +++ b/logic/minecraft/Library.h @@ -8,30 +8,31 @@ #include #include -#include "OneSixRule.h" +#include "Rule.h" #include "minecraft/OpSys.h" #include "GradleSpecifier.h" +#include "MojangDownloadInfo.h" #include "net/URLConstants.h" -class RawLibrary; -typedef std::shared_ptr RawLibraryPtr; +class Library; +typedef std::shared_ptr LibraryPtr; -class RawLibrary +class Library { friend class OneSixVersionFormat; friend class MojangVersionFormat; public: - RawLibrary() + Library() { } - RawLibrary(const QString &name) + Library(const QString &name) { m_name = name; } /// limited copy without some data. TODO: why? - static RawLibraryPtr limitedCopy(RawLibraryPtr base) + static LibraryPtr limitedCopy(LibraryPtr base) { - auto newlib = std::make_shared(); + 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; @@ -158,7 +159,6 @@ protected: /* data */ /// 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 */ @@ -166,7 +166,7 @@ public: /* data */ /** * storage - by default the local libraries folder in multimc, but could be elsewhere - * MultiMC specific, because of FTB. + * MultiMC specific, because of FTB. */ QString m_storagePrefix; @@ -184,4 +184,7 @@ public: /* data */ /// 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/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/OneSixRule.cpp b/logic/minecraft/Rule.cpp similarity index 99% rename from logic/minecraft/OneSixRule.cpp rename to logic/minecraft/Rule.cpp index 3f4a6bb9..c8ba297b 100644 --- a/logic/minecraft/OneSixRule.cpp +++ b/logic/minecraft/Rule.cpp @@ -16,7 +16,7 @@ #include #include -#include "OneSixRule.h" +#include "Rule.h" RuleAction RuleAction_fromString(QString name) { diff --git a/logic/minecraft/OneSixRule.h b/logic/minecraft/Rule.h similarity index 90% rename from logic/minecraft/OneSixRule.h rename to logic/minecraft/Rule.h index f564c3fe..c8bf6eaa 100644 --- a/logic/minecraft/OneSixRule.h +++ b/logic/minecraft/Rule.h @@ -21,7 +21,7 @@ #include #include "OpSys.h" -class RawLibrary; +class Library; class Rule; enum RuleAction @@ -37,7 +37,7 @@ class Rule { protected: RuleAction m_result; - virtual bool applies(const RawLibrary *parent) = 0; + virtual bool applies(const Library *parent) = 0; public: Rule(RuleAction result) : m_result(result) @@ -45,7 +45,7 @@ public: } virtual ~Rule() {}; virtual QJsonObject toJson() = 0; - RuleAction apply(const RawLibrary *parent) + RuleAction apply(const Library *parent) { if (applies(parent)) return m_result; @@ -63,7 +63,7 @@ private: QString m_version_regexp; protected: - virtual bool applies(const RawLibrary *) + virtual bool applies(const Library *) { return (m_system == currentSystem); } @@ -84,7 +84,7 @@ public: class ImplicitRule : public Rule { protected: - virtual bool applies(const RawLibrary *) + virtual bool applies(const Library *) { return true; } 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); diff --git a/tests/tst_MojangVersionFormat.cpp b/tests/tst_MojangVersionFormat.cpp index 4c48fcdc..a9a3f977 100644 --- a/tests/tst_MojangVersionFormat.cpp +++ b/tests/tst_MojangVersionFormat.cpp @@ -34,21 +34,19 @@ slots: QJsonDocument doc = readJson("tests/data/1.9-simple.json"); auto vfile = MojangVersionFormat::versionFileFromJson(doc, "1.9-simple.json"); auto doc2 = MojangVersionFormat::profilePatchToJson(vfile); - writeJson("beast.json", doc2); + writeJson("1.9-simple-passthorugh.json", doc2); QCOMPARE(doc, doc2); } - // not yet - /* + void test_Through() { QJsonDocument doc = readJson("tests/data/1.9.json"); auto vfile = MojangVersionFormat::versionFileFromJson(doc, "1.9.json"); auto doc2 = MojangVersionFormat::profilePatchToJson(vfile); + writeJson("1.9-passthorugh.json", doc2); QCOMPARE(doc, doc2); } - */ - }; QTEST_GUILESS_MAIN(MojangVersionFormatTest)