diff options
Diffstat (limited to 'logic/minecraft')
25 files changed, 348 insertions, 508 deletions
diff --git a/logic/minecraft/Library.cpp b/logic/minecraft/Library.cpp index 9a1d2cc7..922db84e 100644 --- a/logic/minecraft/Library.cpp +++ b/logic/minecraft/Library.cpp @@ -1,57 +1,176 @@ #include "Library.h" +#include <net/CacheDownload.h> +#include <minecraft/forge/ForgeXzDownload.h> +#include <Env.h> #include <FileSystem.h> -QStringList Library::files() const +void Library::getApplicableFiles(OpSys system, QStringList& jar, QStringList& native, QStringList& native32, QStringList& native64) const { - QStringList retval; - QString storage = storageSuffix(); - if (storage.contains("${arch}")) + auto actualPath = [&](QString relPath) { - 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); + QFileInfo out(FS::PathCombine(storagePrefix(), relPath)); + return out.absoluteFilePath(); + }; + if(m_mojangDownloads) + { + if(m_mojangDownloads->artifact) + { + auto artifact = m_mojangDownloads->artifact; + jar += actualPath(artifact->path); + } + if(!isNative()) + return; + if(m_nativeClassifiers.contains(system)) + { + auto nativeClassifier = m_nativeClassifiers[system]; + if(nativeClassifier.contains("${arch}")) + { + auto nat32Classifier = nativeClassifier; + nat32Classifier.replace("${arch}", "32"); + auto nat64Classifier = nativeClassifier; + nat64Classifier.replace("${arch}", "64"); + auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier); + if(nat32info) + native32 += actualPath(nat32info->path); + auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier); + if(nat64info) + native64 += actualPath(nat64info->path); + } + else + { + native += actualPath(m_mojangDownloads->getDownloadInfo(nativeClassifier)->path); + } + } } 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; + QString raw_storage = storageSuffix(system); + if(isNative()) + { + if (raw_storage.contains("${arch}")) + { + auto nat32Storage = raw_storage; + nat32Storage.replace("${arch}", "32"); + auto nat64Storage = raw_storage; + nat64Storage.replace("${arch}", "64"); + native32 += actualPath(nat32Storage); + native64 += actualPath(nat64Storage); + } + else + { + native += actualPath(raw_storage); + } + } + else + { + jar += actualPath(raw_storage); + } } - return true; } -QString Library::url() const +QList<NetActionPtr> Library::getDownloads(OpSys system, HttpMetaCache * cache, QStringList &failedFiles) const { - if (!m_absolute_url.isEmpty()) - { - return m_absolute_url; - } + QList<NetActionPtr> out; + bool isLocal = (hint() == "local"); + bool isForge = (hint() == "forge-pack-xz"); - if (m_base_url.isEmpty()) + auto add_download = [&](QString storage, QString dl) { - return QString("https://" + URLConstants::LIBRARY_BASE) + storageSuffix(); - } + auto entry = cache->resolveEntry("libraries", storage); + if (!entry->isStale()) + return true; + if(isLocal) + { + QFileInfo fileinfo(entry->getFullPath()); + if(!fileinfo.exists()) + { + failedFiles.append(entry->getFullPath()); + return false; + } + return true; + } + if (isForge) + { + out.append(ForgeXzDownload::make(storage, entry)); + } + else + { + out.append(CacheDownload::make(dl, entry)); + } + return true; + }; - if(m_base_url.endsWith('/')) + if(m_mojangDownloads) { - return m_base_url + storageSuffix(); + if(m_mojangDownloads->artifact) + { + auto artifact = m_mojangDownloads->artifact; + add_download(artifact->path, artifact->url); + } + if(m_nativeClassifiers.contains(system)) + { + auto nativeClassifier = m_nativeClassifiers[system]; + if(nativeClassifier.contains("${arch}")) + { + auto nat32Classifier = nativeClassifier; + nat32Classifier.replace("${arch}", "32"); + auto nat64Classifier = nativeClassifier; + nat64Classifier.replace("${arch}", "64"); + auto nat32info = m_mojangDownloads->getDownloadInfo(nat32Classifier); + if(nat32info) + add_download(nat32info->path, nat32info->url); + auto nat64info = m_mojangDownloads->getDownloadInfo(nat64Classifier); + if(nat64info) + add_download(nat64info->path, nat64info->url); + } + else + { + auto info = m_mojangDownloads->getDownloadInfo(nativeClassifier); + if(info) + { + add_download(info->path, info->url); + } + } + } } else { - return m_base_url + QChar('/') + storageSuffix(); + QString raw_storage = storageSuffix(system); + auto raw_dl = [&](){ + if (!m_absoluteURL.isEmpty()) + { + return m_absoluteURL; + } + + if (m_repositoryURL.isEmpty()) + { + return QString("https://" + URLConstants::LIBRARY_BASE) + raw_storage; + } + + if(m_repositoryURL.endsWith('/')) + { + return m_repositoryURL + raw_storage; + } + else + { + return m_repositoryURL + QChar('/') + raw_storage; + } + }(); + if (raw_storage.contains("${arch}")) + { + QString cooked_storage = raw_storage; + QString cooked_dl = raw_dl; + add_download(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32")); + cooked_storage = raw_storage; + cooked_dl = raw_dl; + add_download(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64")); + } + else + { + add_download(raw_storage, raw_dl); + } } + return out; } bool Library::isActive() const @@ -74,7 +193,7 @@ bool Library::isActive() const } if (isNative()) { - result = result && m_native_classifiers.contains(currentSystem); + result = result && m_nativeClassifiers.contains(currentSystem); } return result; } @@ -98,7 +217,7 @@ QString Library::storagePrefix() const return m_storagePrefix; } -QString Library::storageSuffix() const +QString Library::storageSuffix(OpSys system) const { // non-native? use only the gradle specifier if (!isNative()) @@ -108,9 +227,9 @@ QString Library::storageSuffix() const // otherwise native, override classifiers. Mojang HACK! GradleSpecifier nativeSpec = m_name; - if (m_native_classifiers.contains(currentSystem)) + if (m_nativeClassifiers.contains(system)) { - nativeSpec.setClassifier(m_native_classifiers[currentSystem]); + nativeSpec.setClassifier(m_nativeClassifiers[system]); } else { @@ -118,13 +237,3 @@ QString Library::storageSuffix() const } 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 index 35b5cb99..fdce93f3 100644 --- a/logic/minecraft/Library.h +++ b/logic/minecraft/Library.h @@ -1,5 +1,6 @@ #pragma once #include <QString> +#include <net/NetAction.h> #include <QPair> #include <QList> #include <QStringList> @@ -12,16 +13,19 @@ #include "minecraft/OpSys.h" #include "GradleSpecifier.h" #include "net/URLConstants.h" +#include "MojangDownloadInfo.h" + +#include "multimc_logic_export.h" -struct MojangLibraryDownloadInfo; class Library; typedef std::shared_ptr<Library> LibraryPtr; -class Library +class MULTIMC_LOGIC_EXPORT Library { friend class OneSixVersionFormat; friend class MojangVersionFormat; + friend class LibraryTest; public: Library() { @@ -35,13 +39,14 @@ public: { auto newlib = std::make_shared<Library>(); newlib->m_name = base->m_name; - newlib->m_base_url = base->m_base_url; + newlib->m_repositoryURL = base->m_repositoryURL; 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_absoluteURL = base->m_absoluteURL; + newlib->m_extractExcludes = base->m_extractExcludes; + newlib->m_nativeClassifiers = base->m_nativeClassifiers; newlib->m_rules = base->m_rules; newlib->m_storagePrefix = base->m_storagePrefix; + newlib->m_mojangDownloads = base->m_mojangDownloads; return newlib; } @@ -83,45 +88,27 @@ public: /* methods */ /// Returns true if the library is native bool isNative() const { - return m_native_classifiers.size() != 0; + return m_nativeClassifiers.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) + void setRepositoryURL(const QString &base_url) { - m_base_url = base_url; + m_repositoryURL = 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 getApplicableFiles(OpSys system, QStringList & jar, QStringList & native, QStringList & native32, QStringList & native64) const; void setAbsoluteUrl(const QString &absolute_url) { - m_absolute_url = absolute_url; + m_absoluteURL = absolute_url; } - QString absoluteUrl() const + void setMojangDownloadInfo(MojangLibraryDownloadInfo::Ptr info) { - return m_absolute_url; + m_mojangDownloads = info; } void setHint(const QString &hint) @@ -129,11 +116,6 @@ public: /* methods */ m_hint = hint; } - QString hint() const - { - return m_hint; - } - /// Set the load rules void setRules(QList<std::shared_ptr<Rule>> rules) { @@ -143,22 +125,33 @@ public: /* methods */ /// 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; + // Get a list of downloads for this library + QList<NetActionPtr> getDownloads(OpSys system, class HttpMetaCache * cache, QStringList &failedFiles) const; + +private: /* methods */ + /// the default storage prefix used by MultiMC + static QString defaultStoragePrefix(); + + /// 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(OpSys system) const; + + QString hint() const + { + return m_hint; + } 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; + QString m_repositoryURL; /// DEPRECATED: MultiMC-specific absolute URL. takes precedence over the implicit maven repo URL, if defined - QString m_absolute_url; + QString m_absoluteURL; /** * MultiMC-specific type hint - modifies how the library is treated @@ -172,13 +165,13 @@ protected: /* data */ QString m_storagePrefix; /// true if the library had an extract/excludes section (even empty) - bool applyExcludes = false; + bool m_hasExcludes = false; /// a list of files that shouldn't be extracted from the library - QStringList extract_excludes; + QStringList m_extractExcludes; /// native suffixes per OS - QMap<OpSys, QString> m_native_classifiers; + QMap<OpSys, QString> m_nativeClassifiers; /// true if the library had a rules section (even empty) bool applyRules = false; @@ -187,5 +180,5 @@ protected: /* data */ QList<std::shared_ptr<Rule>> m_rules; /// MOJANG: container with Mojang style download info - std::shared_ptr<MojangLibraryDownloadInfo> m_mojang_downloads; + MojangLibraryDownloadInfo::Ptr m_mojangDownloads; }; diff --git a/logic/minecraft/MinecraftProfile.cpp b/logic/minecraft/MinecraftProfile.cpp index 71ece012..70d0cee4 100644 --- a/logic/minecraft/MinecraftProfile.cpp +++ b/logic/minecraft/MinecraftProfile.cpp @@ -14,6 +14,7 @@ */ #include <QFile> +#include <QCryptographicHash> #include <Version.h> #include <QDir> #include <QJsonDocument> @@ -68,9 +69,9 @@ void MinecraftProfile::clear() m_mainClass.clear(); m_appletClass.clear(); m_libraries.clear(); - m_nativeLibraries.clear(); m_traits.clear(); m_jarMods.clear(); + mojangDownloads.clear(); m_problemSeverity = ProblemSeverity::PROBLEM_NONE; } @@ -428,6 +429,18 @@ void MinecraftProfile::applyMinecraftAssets(MojangAssetIndexInfo::Ptr assets) } } +void MinecraftProfile::applyMojangDownload(const QString &key, MojangDownloadInfo::Ptr download) +{ + if(download) + { + mojangDownloads[key] = download; + } + else + { + mojangDownloads.remove(key); + } +} + void MinecraftProfile::applyTraits(const QSet<QString>& traits) { this->m_traits.unite(traits); @@ -466,35 +479,24 @@ static int findLibraryByName(QList<LibraryPtr> haystack, const GradleSpecifier & void MinecraftProfile::applyLibrary(LibraryPtr library) { - auto insert = [&](QList<LibraryPtr> & into) - { - // find the library by name. - const int index = findLibraryByName(into, library->rawName()); - // library not found? just add it. - if (index < 0) - { - into.append(Library::limitedCopy(library)); - return; - } - auto existingLibrary = into.at(index); - // if we are higher it means we should update - if (Version(library->version()) > Version(existingLibrary->version())) - { - auto libraryCopy = Library::limitedCopy(library); - into.replace(index, libraryCopy); - } - }; if(!library->isActive()) { return; } - if(library->isNative()) + // find the library by name. + const int index = findLibraryByName(m_libraries, library->rawName()); + // library not found? just add it. + if (index < 0) { - insert(m_nativeLibraries); + m_libraries.append(Library::limitedCopy(library)); + return; } - else + auto existingLibrary = m_libraries.at(index); + // if we are higher it means we should update + if (Version(library->version()) > Version(existingLibrary->version())) { - insert(m_libraries); + auto libraryCopy = Library::limitedCopy(library); + m_libraries.replace(index, libraryCopy); } } @@ -571,12 +573,21 @@ const QList<LibraryPtr> & MinecraftProfile::getLibraries() const return m_libraries; } -const QList<LibraryPtr> & MinecraftProfile::getNativeLibraries() const +QString MinecraftProfile::getMainJarUrl() const { - return m_nativeLibraries; + auto iter = mojangDownloads.find("client"); + if(iter != mojangDownloads.end()) + { + // current + return iter.value()->url; + } + else + { + // legacy fallback + return URLConstants::getLegacyJarUrl(getMinecraftVersion()); + } } - void MinecraftProfile::installJarMods(QStringList selectedFiles) { m_strategy->installJarMods(selectedFiles); diff --git a/logic/minecraft/MinecraftProfile.h b/logic/minecraft/MinecraftProfile.h index ce0ff3cf..ca9288ad 100644 --- a/logic/minecraft/MinecraftProfile.h +++ b/logic/minecraft/MinecraftProfile.h @@ -97,6 +97,7 @@ public: /* application of profile variables from patches */ void applyJarMods(const QList<JarmodPtr> &jarMods); void applyLibrary(LibraryPtr library); void applyProblemSeverity(ProblemSeverity severity); + void applyMojangDownload(const QString & key, MojangDownloadInfo::Ptr download); public: /* getters for profile variables */ QString getMinecraftVersion() const; @@ -109,7 +110,7 @@ public: /* getters for profile variables */ const QStringList & getTweakers() const; const QList<JarmodPtr> & getJarMods() const; const QList<LibraryPtr> & getLibraries() const; - const QList<LibraryPtr> & getNativeLibraries() const; + QString getMainJarUrl() const; bool hasTrait(const QString & trait) const; ProblemSeverity getProblemSeverity() const; @@ -139,6 +140,9 @@ private: /* data */ /// Assets type - "legacy" or a version ID MojangAssetIndexInfo::Ptr m_minecraftAssets; + // Mojang: list of 'downloads' - client jar, server jar, windows server exe, maybe more. + QMap <QString, std::shared_ptr<MojangDownloadInfo>> mojangDownloads; + /** * arguments that should be used for launching minecraft * @@ -159,9 +163,6 @@ private: /* data */ /// the list of libraries QList<LibraryPtr> m_libraries; - /// the list of native libraries - QList<LibraryPtr> m_nativeLibraries; - /// traits, collected from all the version files (version files can only add) QSet<QString> m_traits; diff --git a/logic/minecraft/MinecraftVersion.cpp b/logic/minecraft/MinecraftVersion.cpp index a3855481..3167fc4a 100644 --- a/logic/minecraft/MinecraftVersion.cpp +++ b/logic/minecraft/MinecraftVersion.cpp @@ -72,10 +72,12 @@ void MinecraftVersion::applyFileTo(MinecraftProfile *profile) QString MinecraftVersion::getUrl() const { + // legacy fallback if(m_versionFileURL.isEmpty()) { return QString("http://") + URLConstants::AWS_DOWNLOAD_VERSIONS + m_descriptor + "/" + m_descriptor + ".json"; } + // current return m_versionFileURL; } diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp index 62c588d1..bd679c73 100644 --- a/logic/minecraft/MinecraftVersionList.cpp +++ b/logic/minecraft/MinecraftVersionList.cpp @@ -470,8 +470,7 @@ void MCVListVersionUpdateTask::executeTask() specificVersionDownloadJob.reset(job); connect(specificVersionDownloadJob.get(), SIGNAL(succeeded()), SLOT(json_downloaded())); connect(specificVersionDownloadJob.get(), SIGNAL(failed(QString)), SIGNAL(failed(QString))); - connect(specificVersionDownloadJob.get(), SIGNAL(progress(qint64, qint64)), - SIGNAL(progress(qint64, qint64))); + connect(specificVersionDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); specificVersionDownloadJob->start(); } diff --git a/logic/minecraft/MojangDownloadInfo.h b/logic/minecraft/MojangDownloadInfo.h index d8cd2e6d..1f3306e0 100644 --- a/logic/minecraft/MojangDownloadInfo.h +++ b/logic/minecraft/MojangDownloadInfo.h @@ -1,5 +1,6 @@ #pragma once #include <QString> +#include <QMap> #include <memory> struct MojangDownloadInfo @@ -22,6 +23,9 @@ struct MojangDownloadInfo struct MojangLibraryDownloadInfo { + MojangLibraryDownloadInfo(MojangDownloadInfo::Ptr artifact): artifact(artifact) {}; + MojangLibraryDownloadInfo() {}; + // types typedef std::shared_ptr<MojangLibraryDownloadInfo> Ptr; diff --git a/logic/minecraft/MojangVersionFormat.cpp b/logic/minecraft/MojangVersionFormat.cpp index 41723493..34129c9e 100644 --- a/logic/minecraft/MojangVersionFormat.cpp +++ b/logic/minecraft/MojangVersionFormat.cpp @@ -8,7 +8,7 @@ using namespace Json; #include "ParseUtils.h" -static const int CURRENT_MINIMUM_LAUNCHER_VERSION = 14; +static const int CURRENT_MINIMUM_LAUNCHER_VERSION = 18; static MojangAssetIndexInfo::Ptr assetIndexFromJson (const QJsonObject &obj); static MojangDownloadInfo::Ptr downloadInfoFromJson (const QJsonObject &obj); @@ -130,7 +130,7 @@ QJsonObject assetIndexToJson(MojangAssetIndexInfo::Ptr info) void MojangVersionFormat::readVersionProperties(const QJsonObject &in, VersionFile *out) { - Bits::readString(in, "id", out->id); + Bits::readString(in, "id", out->minecraftVersion); Bits::readString(in, "mainClass", out->mainClass); Bits::readString(in, "minecraftArguments", out->minecraftArguments); if(out->minecraftArguments.isEmpty()) @@ -212,7 +212,7 @@ VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc out->name = "Minecraft"; out->fileId = "net.minecraft"; - out->version = out->id; + out->version = out->minecraftVersion; out->filename = filename; @@ -231,7 +231,7 @@ VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc void MojangVersionFormat::writeVersionProperties(const VersionFile* in, QJsonObject& out) { - writeString(out, "id", in->id); + writeString(out, "id", in->minecraftVersion); writeString(out, "mainClass", in->mainClass); writeString(out, "minecraftArguments", in->minecraftArguments); writeString(out, "type", in->type); @@ -294,14 +294,14 @@ LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const } out->m_name = libObj.value("name").toString(); - Bits::readString(libObj, "url", out->m_base_url); + Bits::readString(libObj, "url", out->m_repositoryURL); if (libObj.contains("extract")) { - out->applyExcludes = true; + out->m_hasExcludes = true; auto extractObj = requireObject(libObj.value("extract")); for (auto excludeVal : requireArray(extractObj.value("exclude"))) { - out->extract_excludes.append(requireString(excludeVal)); + out->m_extractExcludes.append(requireString(excludeVal)); } } if (libObj.contains("natives")) @@ -316,7 +316,7 @@ LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const OpSys opSys = OpSys_fromString(it.key()); if (opSys != Os_Other) { - out->m_native_classifiers[opSys] = it.value().toString(); + out->m_nativeClassifiers[opSys] = it.value().toString(); } } } @@ -327,7 +327,7 @@ LibraryPtr MojangVersionFormat::libraryFromJson(const QJsonObject &libObj, const } if (libObj.contains("downloads")) { - out->m_mojang_downloads = libDownloadInfoFromJson(libObj); + out->m_mojangDownloads = libDownloadInfoFromJson(libObj); } return out; } @@ -336,27 +336,25 @@ 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()) + if (!library->m_repositoryURL.isEmpty()) { - libRoot.insert("url", library->m_base_url); + libRoot.insert("url", library->m_repositoryURL); } if (library->isNative()) { QJsonObject nativeList; - auto iter = library->m_native_classifiers.begin(); - while (iter != library->m_native_classifiers.end()) + auto iter = library->m_nativeClassifiers.begin(); + while (iter != library->m_nativeClassifiers.end()) { nativeList.insert(OpSys_toString(iter.key()), iter.value()); iter++; } libRoot.insert("natives", nativeList); - if (library->extract_excludes.size()) + if (library->m_extractExcludes.size()) { QJsonArray excludes; QJsonObject extract; - for (auto exclude : library->extract_excludes) + for (auto exclude : library->m_extractExcludes) { excludes.append(exclude); } @@ -374,9 +372,9 @@ QJsonObject MojangVersionFormat::libraryToJson(Library *library) } libRoot.insert("rules", allRules); } - if(library->m_mojang_downloads) + if(library->m_mojangDownloads) { - auto downloadsObj = libDownloadInfoToJson(library->m_mojang_downloads); + auto downloadsObj = libDownloadInfoToJson(library->m_mojangDownloads); libRoot.insert("downloads", downloadsObj); } return libRoot; diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp index 451c3c8b..573c4cb4 100644 --- a/logic/minecraft/VersionFile.cpp +++ b/logic/minecraft/VersionFile.cpp @@ -25,14 +25,14 @@ bool VersionFile::hasJarMods() void VersionFile::applyTo(MinecraftProfile *profile) { auto theirVersion = profile->getMinecraftVersion(); - if (!theirVersion.isNull() && !mcVersion.isNull()) + if (!theirVersion.isNull() && !dependsOnMinecraftVersion.isNull()) { - if (QRegExp(mcVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(theirVersion) == -1) + if (QRegExp(dependsOnMinecraftVersion, Qt::CaseInsensitive, QRegExp::Wildcard).indexIn(theirVersion) == -1) { - throw MinecraftVersionMismatch(fileId, mcVersion, theirVersion); + throw MinecraftVersionMismatch(fileId, dependsOnMinecraftVersion, theirVersion); } } - profile->applyMinecraftVersion(id); + profile->applyMinecraftVersion(minecraftVersion); profile->applyMainClass(mainClass); profile->applyAppletClass(appletClass); profile->applyMinecraftArguments(minecraftArguments); @@ -51,4 +51,10 @@ void VersionFile::applyTo(MinecraftProfile *profile) profile->applyLibrary(library); } profile->applyProblemSeverity(getProblemSeverity()); + auto iter = mojangDownloads.begin(); + while(iter != mojangDownloads.end()) + { + profile->applyMojangDownload(iter.key(), iter.value()); + iter++; + } } diff --git a/logic/minecraft/VersionFile.h b/logic/minecraft/VersionFile.h index 7627cc96..1b692f0f 100644 --- a/logic/minecraft/VersionFile.h +++ b/logic/minecraft/VersionFile.h @@ -143,13 +143,13 @@ public: /* data */ QString version; /// MultiMC: dependency on a Minecraft version - QString mcVersion; + QString dependsOnMinecraftVersion; /// Mojang: used to version the Mojang version format int minimumLauncherVersion = -1; /// Mojang: version of Minecraft this is - QString id; + QString minecraftVersion; /// Mojang: class to launch Minecraft with QString mainClass; diff --git a/logic/minecraft/forge/ForgeInstaller.cpp b/logic/minecraft/forge/ForgeInstaller.cpp index 7957de0e..155a2cac 100644 --- a/logic/minecraft/forge/ForgeInstaller.cpp +++ b/logic/minecraft/forge/ForgeInstaller.cpp @@ -126,8 +126,8 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr QCryptographicHash md5sum(QCryptographicHash::Md5); md5sum.addData(data); - cacheentry->stale = false; - cacheentry->md5sum = md5sum.result().toHex().constData(); + cacheentry->setStale(false); + cacheentry->setMD5Sum(md5sum.result().toHex().constData()); ENV.metacache()->updateEntry(cacheentry); } file.close(); @@ -264,8 +264,8 @@ bool ForgeInstaller::add(OneSixInstance *to) m_forge_json->name = "Forge"; m_forge_json->fileId = id(); m_forge_json->version = m_forgeVersionString; - m_forge_json->mcVersion = to->intendedVersionId(); - m_forge_json->id.clear(); + m_forge_json->dependsOnMinecraftVersion = to->intendedVersionId(); + m_forge_json->minecraftVersion.clear(); m_forge_json->order = 5; QSaveFile file(filename(to->instanceRoot())); @@ -378,16 +378,16 @@ protected: * This fixes some problems with bad files acquired because of unhandled HTTP redirects * in old versions of MultiMC. */ - if (!entry->stale) + if (!entry->isStale()) { QFileInfo localFile(entry->getFullPath()); if (localFile.size() <= 0x4000) { - entry->stale = true; + entry->setStale(true); } } - if (entry->stale) + if (entry->isStale()) { NetJob *fjob = new NetJob("Forge download"); fjob->addNetAction(CacheDownload::make(forgeVersion->url(), entry)); diff --git a/logic/minecraft/forge/ForgeMirror.h b/logic/minecraft/forge/ForgeMirror.h deleted file mode 100644 index 2518dffe..00000000 --- a/logic/minecraft/forge/ForgeMirror.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include <QString> - -struct ForgeMirror -{ - QString name; - QString logo_url; - QString website_url; - QString mirror_url; -};
\ No newline at end of file diff --git a/logic/minecraft/forge/ForgeMirrors.cpp b/logic/minecraft/forge/ForgeMirrors.cpp deleted file mode 100644 index a2fc2c62..00000000 --- a/logic/minecraft/forge/ForgeMirrors.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "Env.h" -#include "ForgeMirrors.h" -#include <QDebug> -#include <algorithm> -#include <random> - -ForgeMirrors::ForgeMirrors(QList<ForgeXzDownloadPtr> &libs, NetJobPtr parent_job, - QString mirrorlist) -{ - m_libs = libs; - m_parent_job = parent_job; - m_url = QUrl(mirrorlist); - m_status = Job_NotStarted; -} - -void ForgeMirrors::start() -{ - qDebug() << "Downloading " << m_url.toString(); - QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); - auto worker = ENV.qnam(); - QNetworkReply *rep = worker->get(request); - - m_reply.reset(rep); - connect(rep, SIGNAL(downloadProgress(qint64, qint64)), - SLOT(downloadProgress(qint64, qint64))); - connect(rep, SIGNAL(finished()), SLOT(downloadFinished())); - connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), - SLOT(downloadError(QNetworkReply::NetworkError))); - connect(rep, SIGNAL(readyRead()), SLOT(downloadReadyRead())); -} - -void ForgeMirrors::downloadError(QNetworkReply::NetworkError error) -{ - // error happened during download. - qCritical() << "Error getting URL:" << m_url.toString().toLocal8Bit() - << "Network error: " << error; - m_status = Job_Failed; -} - -void ForgeMirrors::downloadFinished() -{ - // if the download succeeded - if (m_status != Job_Failed) - { - // nothing went wrong... ? - parseMirrorList(); - return; - } - // else the download failed, we use a fixed list - else - { - m_status = Job_Finished; - m_reply.reset(); - deferToFixedList(); - return; - } -} - -void ForgeMirrors::deferToFixedList() -{ - m_mirrors.clear(); - m_mirrors.append( - {"Minecraft Forge", "http://files.minecraftforge.net/forge_logo.png", - "http://files.minecraftforge.net/", "http://files.minecraftforge.net/maven/"}); - m_mirrors.append({"Creeper Host", - "http://files.minecraftforge.net/forge_logo.png", - "https://www.creeperhost.net/link.php?id=1", - "http://new.creeperrepo.net/forge/maven/"}); - injectDownloads(); - emit succeeded(m_index_within_job); -} - -void ForgeMirrors::parseMirrorList() -{ - m_status = Job_Finished; - auto data = m_reply->readAll(); - m_reply.reset(); - auto dataLines = data.split('\n'); - for(auto line: dataLines) - { - auto elements = line.split('!'); - if (elements.size() == 4) - { - m_mirrors.append({elements[0],elements[1],elements[2],elements[3]}); - } - } - if(!m_mirrors.size()) - deferToFixedList(); - injectDownloads(); - emit succeeded(m_index_within_job); -} - -void ForgeMirrors::injectDownloads() -{ - // shuffle the mirrors randomly - std::random_device rd; - std::mt19937 rng(rd()); - std::shuffle(m_mirrors.begin(), m_mirrors.end(), rng); - - // tell parent to download the libs - for(auto lib: m_libs) - { - lib->setMirrors(m_mirrors); - m_parent_job->addNetAction(lib); - } -} - -void ForgeMirrors::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) -{ - m_total_progress = bytesTotal; - m_progress = bytesReceived; - emit netActionProgress(m_index_within_job, bytesReceived, bytesTotal); -} - -void ForgeMirrors::downloadReadyRead() -{ -} diff --git a/logic/minecraft/forge/ForgeMirrors.h b/logic/minecraft/forge/ForgeMirrors.h deleted file mode 100644 index 0312829b..00000000 --- a/logic/minecraft/forge/ForgeMirrors.h +++ /dev/null @@ -1,61 +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 "ForgeXzDownload.h" - -#include "net/NetAction.h" -#include "net/HttpMetaCache.h" -#include "net/NetJob.h" - -#include <QFile> -#include <QTemporaryFile> - -typedef std::shared_ptr<class ForgeMirrors> ForgeMirrorsPtr; - -class ForgeMirrors : public NetAction -{ - Q_OBJECT -public: - QList<ForgeXzDownloadPtr> m_libs; - NetJobPtr m_parent_job; - QList<ForgeMirror> m_mirrors; - -public: - explicit ForgeMirrors(QList<ForgeXzDownloadPtr> &libs, NetJobPtr parent_job, - QString mirrorlist); - static ForgeMirrorsPtr make(QList<ForgeXzDownloadPtr> &libs, NetJobPtr parent_job, - QString mirrorlist) - { - return ForgeMirrorsPtr(new ForgeMirrors(libs, parent_job, mirrorlist)); - } - virtual ~ForgeMirrors(){}; -protected -slots: - virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); - virtual void downloadError(QNetworkReply::NetworkError error); - virtual void downloadFinished(); - virtual void downloadReadyRead(); - -private: - void parseMirrorList(); - void deferToFixedList(); - void injectDownloads(); - -public -slots: - virtual void start(); -}; diff --git a/logic/minecraft/forge/ForgeVersionList.cpp b/logic/minecraft/forge/ForgeVersionList.cpp index 9b418310..907672f2 100644 --- a/logic/minecraft/forge/ForgeVersionList.cpp +++ b/logic/minecraft/forge/ForgeVersionList.cpp @@ -128,8 +128,8 @@ void ForgeListLoadTask::executeTask() auto gradleForgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "json"); // verify by poking the server. - forgeListEntry->stale = true; - gradleForgeListEntry->stale = true; + forgeListEntry->setStale(true); + gradleForgeListEntry->setStale(true); job->addNetAction(listDownload = CacheDownload::make(QUrl(URLConstants::FORGE_LEGACY_URL), forgeListEntry)); diff --git a/logic/minecraft/forge/ForgeXzDownload.cpp b/logic/minecraft/forge/ForgeXzDownload.cpp index 6009e31e..2a47bb26 100644 --- a/logic/minecraft/forge/ForgeXzDownload.cpp +++ b/logic/minecraft/forge/ForgeXzDownload.cpp @@ -30,19 +30,13 @@ ForgeXzDownload::ForgeXzDownload(QString relative_path, MetaEntryPtr entry) : Ne m_pack200_xz_file.setFileTemplate("./dl_temp.XXXXXX"); m_status = Job_NotStarted; m_url_path = relative_path; -} - -void ForgeXzDownload::setMirrors(QList<ForgeMirror> &mirrors) -{ - m_mirror_index = 0; - m_mirrors = mirrors; - updateUrl(); + m_url = "http://files.minecraftforge.net/maven/" + m_url_path + ".pack.xz"; } void ForgeXzDownload::start() { m_status = Job_InProgress; - if (!m_entry->stale) + if (!m_entry->isStale()) { m_status = Job_Finished; emit succeeded(m_index_within_job); @@ -55,16 +49,10 @@ void ForgeXzDownload::start() emit failed(m_index_within_job); return; } - if (m_mirrors.empty()) - { - m_status = Job_Failed; - emit failed(m_index_within_job); - return; - } qDebug() << "Downloading " << m_url.toString(); QNetworkRequest request(m_url); - request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->etag.toLatin1()); + request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->getETag().toLatin1()); request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); auto worker = ENV.qnam(); @@ -96,44 +84,11 @@ void ForgeXzDownload::downloadError(QNetworkReply::NetworkError error) void ForgeXzDownload::failAndTryNextMirror() { m_status = Job_Failed; - int next = m_mirror_index + 1; - if(m_mirrors.size() == next) - m_mirror_index = 0; - else - m_mirror_index = next; - - updateUrl(); emit failed(m_index_within_job); } -void ForgeXzDownload::updateUrl() -{ - qDebug() << "Updating URL for " << m_url_path; - for (auto possible : m_mirrors) - { - qDebug() << "Possible: " << possible.name << " : " << possible.mirror_url; - } - QString aggregate = m_mirrors[m_mirror_index].mirror_url + m_url_path + ".pack.xz"; - m_url = QUrl(aggregate); -} - void ForgeXzDownload::downloadFinished() { - //TEST: defer to other possible mirrors (autofail the first one) - /* - qDebug() <<"dl " << index_within_job << " mirror " << m_mirror_index; - if( m_mirror_index == 0) - { - qDebug() <<"dl " << index_within_job << " AUTOFAIL"; - m_status = Job_Failed; - m_pack200_xz_file.close(); - m_pack200_xz_file.remove(); - m_reply.reset(); - failAndTryNextMirror(); - return; - } - */ - // if the download succeeded if (m_status != Job_Failed) { @@ -372,16 +327,14 @@ void ForgeXzDownload::decompressAndInstall() failAndTryNextMirror(); return; } - m_entry->md5sum = QCryptographicHash::hash(jar_file.readAll(), QCryptographicHash::Md5) - .toHex() - .constData(); + auto hash = QCryptographicHash::hash(jar_file.readAll(), QCryptographicHash::Md5); + m_entry->setMD5Sum(hash.toHex().constData()); jar_file.close(); QFileInfo output_file_info(m_target_path); - m_entry->etag = m_reply->rawHeader("ETag").constData(); - m_entry->local_changed_timestamp = - output_file_info.lastModified().toUTC().toMSecsSinceEpoch(); - m_entry->stale = false; + m_entry->setETag(m_reply->rawHeader("ETag").constData()); + m_entry->setLocalChangedTimestamp(output_file_info.lastModified().toUTC().toMSecsSinceEpoch()); + m_entry->setStale(false); ENV.metacache()->updateEntry(m_entry); m_reply.reset(); diff --git a/logic/minecraft/forge/ForgeXzDownload.h b/logic/minecraft/forge/ForgeXzDownload.h index 45722812..67524405 100644 --- a/logic/minecraft/forge/ForgeXzDownload.h +++ b/logic/minecraft/forge/ForgeXzDownload.h @@ -19,7 +19,6 @@ #include "net/HttpMetaCache.h" #include <QFile> #include <QTemporaryFile> -#include "ForgeMirror.h" typedef std::shared_ptr<class ForgeXzDownload> ForgeXzDownloadPtr; @@ -32,10 +31,6 @@ public: QString m_target_path; /// this is the output file, if any QTemporaryFile m_pack200_xz_file; - /// mirror index (NOT OPTICS, I SWEAR) - int m_mirror_index = 0; - /// list of mirrors to use. Mirror has the url base - QList<ForgeMirror> m_mirrors; /// path relative to the mirror base QString m_url_path; @@ -46,7 +41,6 @@ public: return ForgeXzDownloadPtr(new ForgeXzDownload(relative_path, entry)); } virtual ~ForgeXzDownload(){}; - void setMirrors(QList<ForgeMirror> & mirrors); protected slots: @@ -62,5 +56,4 @@ slots: private: void decompressAndInstall(); void failAndTryNextMirror(); - void updateUrl(); }; diff --git a/logic/minecraft/ftb/FTBProfileStrategy.cpp b/logic/minecraft/ftb/FTBProfileStrategy.cpp index d43fbf6e..f5faacae 100644 --- a/logic/minecraft/ftb/FTBProfileStrategy.cpp +++ b/logic/minecraft/ftb/FTBProfileStrategy.cpp @@ -59,7 +59,7 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches() auto file = ProfileUtils::parseJsonFile(QFileInfo(mcJson), false); // adapt the loaded file - the FTB patch file format is different than ours. - file->id.clear(); + file->minecraftVersion.clear(); for(auto addLib: file->libraries) { addLib->setHint("local"); diff --git a/logic/minecraft/legacy/LegacyUpdate.cpp b/logic/minecraft/legacy/LegacyUpdate.cpp index af787f8c..2d7e8dd2 100644 --- a/logic/minecraft/legacy/LegacyUpdate.cpp +++ b/logic/minecraft/legacy/LegacyUpdate.cpp @@ -367,14 +367,12 @@ void LegacyUpdate::jarStart() setStatus(tr("Downloading new minecraft.jar ...")); QString version_id = inst->intendedVersionId(); - QString localPath = version_id + "/" + version_id + ".jar"; - QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + localPath; auto dljob = new NetJob("Minecraft.jar for version " + version_id); auto metacache = ENV.metacache(); - auto entry = metacache->resolveEntry("versions", localPath); - dljob->addNetAction(CacheDownload::make(QUrl(urlstr), entry)); + auto entry = metacache->resolveEntry("versions", URLConstants::getJarPath(version_id)); + dljob->addNetAction(CacheDownload::make(QUrl(URLConstants::getLegacyJarUrl(version_id)), entry)); connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished())); connect(dljob, SIGNAL(failed(QString)), SLOT(jarFailed(QString))); connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); diff --git a/logic/minecraft/liteloader/LiteLoaderVersionList.cpp b/logic/minecraft/liteloader/LiteLoaderVersionList.cpp index 42698ccc..b0c9736a 100644 --- a/logic/minecraft/liteloader/LiteLoaderVersionList.cpp +++ b/logic/minecraft/liteloader/LiteLoaderVersionList.cpp @@ -144,7 +144,7 @@ void LLListLoadTask::executeTask() auto liteloaderEntry = ENV.metacache()->resolveEntry("liteloader", "versions.json"); // verify by poking the server. - liteloaderEntry->stale = true; + liteloaderEntry->setStale(true); job->addNetAction(listDownload = CacheDownload::make(QUrl(URLConstants::LITELOADER_URL), liteloaderEntry)); @@ -251,7 +251,7 @@ void LLListLoadTask::listDownloaded() // hack to make liteloader 1.7.10_00 work if(lib->rawName() == GradleSpecifier("org.ow2.asm:asm-all:5.0.3")) { - lib->setBaseUrl("http://repo.maven.apache.org/maven2/"); + lib->setRepositoryURL("http://repo.maven.apache.org/maven2/"); } version->libraries.append(lib); } diff --git a/logic/minecraft/onesix/OneSixInstance.cpp b/logic/minecraft/onesix/OneSixInstance.cpp index 328c3b38..8d46eefc 100644 --- a/logic/minecraft/onesix/OneSixInstance.cpp +++ b/logic/minecraft/onesix/OneSixInstance.cpp @@ -180,24 +180,6 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session) launchScript += "jarmod " + jarmod->originalName + " (" + jarmod->name + ")\n"; } - // libraries and class path. - { - auto libs = m_profile->getLibraries(); - for (auto lib : libs) - { - launchScript += "cp " + QFileInfo(lib->storagePath()).absoluteFilePath() + "\n"; - } - auto jarMods = getJarMods(); - if (!jarMods.isEmpty()) - { - launchScript += "cp " + QDir(instanceRoot()).absoluteFilePath("minecraft.jar") + "\n"; - } - else - { - QString relpath = m_profile->getMinecraftVersion() + "/" + m_profile->getMinecraftVersion() + ".jar"; - launchScript += "cp " + versionsPath().absoluteFilePath(relpath) + "\n"; - } - } auto mainClass = m_profile->getMainClass(); if (!mainClass.isEmpty()) { @@ -234,15 +216,43 @@ QString OneSixInstance::createLaunchScript(AuthSessionPtr session) launchScript += "sessionId " + session->session + "\n"; } - // native libraries (mostly LWJGL) + // libraries and class path. { - QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/")); - for (auto native : m_profile->getNativeLibraries()) + auto libs = m_profile->getLibraries(); + + QStringList jar, native, native32, native64; + for (auto lib : libs) + { + lib->getApplicableFiles(currentSystem, jar, native, native32, native64); + } + for(auto file: jar) + { + launchScript += "cp " + file + "\n"; + } + for(auto file: native) { - QFileInfo finfo(native->storagePath()); - launchScript += "ext " + finfo.absoluteFilePath() + "\n"; + launchScript += "ext " + file + "\n"; } + for(auto file: native32) + { + launchScript += "ext32 " + file + "\n"; + } + for(auto file: native64) + { + launchScript += "ext64 " + file + "\n"; + } + QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/")); launchScript += "natives " + natives_dir.absolutePath() + "\n"; + auto jarMods = getJarMods(); + if (!jarMods.isEmpty()) + { + launchScript += "cp " + QDir(instanceRoot()).absoluteFilePath("minecraft.jar") + "\n"; + } + else + { + QString relpath = m_profile->getMinecraftVersion() + "/" + m_profile->getMinecraftVersion() + ".jar"; + launchScript += "cp " + versionsPath().absoluteFilePath(relpath) + "\n"; + } } // traits. including legacyLaunch and others ;) diff --git a/logic/minecraft/onesix/OneSixProfileStrategy.cpp b/logic/minecraft/onesix/OneSixProfileStrategy.cpp index aaaa9d97..af42286d 100644 --- a/logic/minecraft/onesix/OneSixProfileStrategy.cpp +++ b/logic/minecraft/onesix/OneSixProfileStrategy.cpp @@ -54,7 +54,7 @@ void OneSixProfileStrategy::upgradeDeprecatedFiles() auto file = ProfileUtils::parseJsonFile(QFileInfo(sourceFile), false); ProfileUtils::removeLwjglFromPatch(file); file->fileId = "net.minecraft"; - file->version = file->id; + file->version = file->minecraftVersion; file->name = "Minecraft"; auto data = OneSixVersionFormat::versionFileToJson(file, false).toJson(); QSaveFile newPatchFile(mcJson); diff --git a/logic/minecraft/onesix/OneSixUpdate.cpp b/logic/minecraft/onesix/OneSixUpdate.cpp index 10d1e294..1c2cd196 100644 --- a/logic/minecraft/onesix/OneSixUpdate.cpp +++ b/logic/minecraft/onesix/OneSixUpdate.cpp @@ -14,6 +14,7 @@ */ #include "Env.h" +#include <minecraft/forge/ForgeXzDownload.h> #include "OneSixUpdate.h" #include "OneSixInstance.h" @@ -29,7 +30,6 @@ #include "minecraft/MinecraftVersionList.h" #include "minecraft/MinecraftProfile.h" #include "minecraft/Library.h" -#include "minecraft/forge/ForgeMirrors.h" #include "net/URLConstants.h" #include "minecraft/AssetsUtils.h" #include "Exception.h" @@ -95,7 +95,7 @@ void OneSixUpdate::assetIndexStart() auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("asset_indexes", localPath); - entry->stale = true; + entry->setStale(true); job->addNetAction(CacheDownload::make(indexUrl, entry)); jarlibDownloadJob.reset(job); @@ -174,88 +174,41 @@ void OneSixUpdate::jarlibStart() { QString version_id = profile->getMinecraftVersion(); QString localPath = version_id + "/" + version_id + ".jar"; - QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + localPath; + QString urlstr = profile->getMainJarUrl(); auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name())); auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("versions", localPath); job->addNetAction(CacheDownload::make(QUrl(urlstr), entry)); - jarHashOnEntry = entry->md5sum; - jarlibDownloadJob.reset(job); } - auto libs = profile->getNativeLibraries(); - libs.append(profile->getLibraries()); + auto libs = profile->getLibraries(); auto metacache = ENV.metacache(); - QList<ForgeXzDownloadPtr> ForgeLibs; QList<LibraryPtr> brokenLocalLibs; + QStringList failedFiles; for (auto lib : libs) { - if (lib->hint() == "local") - { - if (!lib->filesExist(m_inst->librariesPath())) - brokenLocalLibs.append(lib); - continue; - } - - QString raw_storage = lib->storageSuffix(); - QString raw_dl = lib->url(); - - auto f = [&](QString storage, QString dl) - { - auto entry = metacache->resolveEntry("libraries", storage); - if (entry->stale) - { - if (lib->hint() == "forge-pack-xz") - { - ForgeLibs.append(ForgeXzDownload::make(storage, entry)); - } - else - { - jarlibDownloadJob->addNetAction(CacheDownload::make(dl, entry)); - } - } - }; - if (raw_storage.contains("${arch}")) - { - QString cooked_storage = raw_storage; - QString cooked_dl = raw_dl; - f(cooked_storage.replace("${arch}", "32"), cooked_dl.replace("${arch}", "32")); - cooked_storage = raw_storage; - cooked_dl = raw_dl; - f(cooked_storage.replace("${arch}", "64"), cooked_dl.replace("${arch}", "64")); - } - else + auto dls = lib->getDownloads(currentSystem, metacache.get(), failedFiles); + for(auto dl : dls) { - f(raw_storage, raw_dl); + jarlibDownloadJob->addNetAction(dl); } } if (!brokenLocalLibs.empty()) { jarlibDownloadJob.reset(); - QStringList failed; - for (auto brokenLib : brokenLocalLibs) - { - failed.append(brokenLib->files()); - } - QString failed_all = failed.join("\n"); + + QString failed_all = failedFiles.join("\n"); emitFailed(tr("Some libraries marked as 'local' are missing their jar " "files:\n%1\n\nYou'll have to correct this problem manually. If this is " "an externally tracked instance, make sure to run it at least once " "outside of MultiMC.").arg(failed_all)); return; } - // TODO: think about how to propagate this from the original json file... or IF AT ALL - QString forgeMirrorList = "http://files.minecraftforge.net/mirror-brand.list"; - if (!ForgeLibs.empty()) - { - jarlibDownloadJob->addNetAction( - ForgeMirrors::make(ForgeLibs, jarlibDownloadJob, forgeMirrorList)); - } connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(jarlibFinished())); connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::jarlibFailed); diff --git a/logic/minecraft/onesix/OneSixUpdate.h b/logic/minecraft/onesix/OneSixUpdate.h index 6901e3d6..b5195364 100644 --- a/logic/minecraft/onesix/OneSixUpdate.h +++ b/logic/minecraft/onesix/OneSixUpdate.h @@ -63,6 +63,5 @@ private: std::shared_ptr<Task> versionUpdateTask; OneSixInstance *m_inst = nullptr; - QString jarHashOnEntry; QList<FMLlib> fmlLibsToProcess; }; diff --git a/logic/minecraft/onesix/OneSixVersionFormat.cpp b/logic/minecraft/onesix/OneSixVersionFormat.cpp index b5e05b22..49a18563 100644 --- a/logic/minecraft/onesix/OneSixVersionFormat.cpp +++ b/logic/minecraft/onesix/OneSixVersionFormat.cpp @@ -19,16 +19,16 @@ LibraryPtr OneSixVersionFormat::libraryFromJson(const QJsonObject &libObj, const { 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); + readString(libObj, "MMC-absulute_url", out->m_absoluteURL); + readString(libObj, "MMC-absoluteUrl", out->m_absoluteURL); return out; } QJsonObject OneSixVersionFormat::libraryToJson(Library *library) { QJsonObject libRoot = MojangVersionFormat::libraryToJson(library); - if (library->m_absolute_url.size()) - libRoot.insert("MMC-absoluteUrl", library->m_absolute_url); + if (library->m_absoluteURL.size()) + libRoot.insert("MMC-absoluteUrl", library->m_absoluteURL); if (library->m_hint.size()) libRoot.insert("MMC-hint", library->m_hint); return libRoot; @@ -64,7 +64,7 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc 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->dependsOnMinecraftVersion = root.value("mcVersion").toString(); out->filename = filename; MojangVersionFormat::readVersionProperties(root, out.get()); @@ -167,7 +167,7 @@ QJsonDocument OneSixVersionFormat::versionFileToJson(const VersionFilePtr &patch writeString(root, "name", patch->name); writeString(root, "fileId", patch->fileId); writeString(root, "version", patch->version); - writeString(root, "mcVersion", patch->mcVersion); + writeString(root, "mcVersion", patch->dependsOnMinecraftVersion); MojangVersionFormat::writeVersionProperties(patch.get(), root); |