From 163a3095b1fb8c2735fdd379e84d99f4c583d433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 17 Feb 2016 08:10:31 +0100 Subject: GH-1453 separate out Mojang version reading, use version file URLs --- logic/minecraft/MinecraftVersion.cpp | 9 +++ logic/minecraft/MinecraftVersion.h | 8 ++- logic/minecraft/MinecraftVersionList.cpp | 42 ++++++------ logic/minecraft/OneSixUpdate.cpp | 13 ++-- logic/minecraft/VersionFile.cpp | 107 ++++++++++++++++++++++--------- logic/minecraft/VersionFile.h | 1 + 6 files changed, 119 insertions(+), 61 deletions(-) diff --git a/logic/minecraft/MinecraftVersion.cpp b/logic/minecraft/MinecraftVersion.cpp index 1451c39d..96d64d6d 100644 --- a/logic/minecraft/MinecraftVersion.cpp +++ b/logic/minecraft/MinecraftVersion.cpp @@ -77,6 +77,15 @@ QJsonDocument MinecraftVersion::toJson(bool saveOrder) } } +QString MinecraftVersion::getUrl() const +{ + if(m_versionFileURL.isEmpty()) + { + return QString("http://") + URLConstants::AWS_DOWNLOAD_VERSIONS + m_descriptor + "/" + m_descriptor + ".json"; + } + return m_versionFileURL; +} + VersionFilePtr MinecraftVersion::getVersionFile() { QFileInfo versionFile(QString("versions/%1/%1.dat").arg(m_descriptor)); diff --git a/logic/minecraft/MinecraftVersion.h b/logic/minecraft/MinecraftVersion.h index 234e5566..120ea8ce 100644 --- a/logic/minecraft/MinecraftVersion.h +++ b/logic/minecraft/MinecraftVersion.h @@ -76,15 +76,17 @@ public: /* methods */ virtual QJsonDocument toJson(bool saveOrder) override; + QString getUrl() const; + private: /* methods */ void applyFileTo(MinecraftProfile *version); public: /* data */ - /// The URL that this version will be downloaded from. maybe. - QString download_url; - VersionSource m_versionSource = Builtin; + /// The URL that this version will be downloaded from. + QString m_versionFileURL; + /// the human readable version name QString m_name; diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp index afd8bde8..9a1c18b7 100644 --- a/logic/minecraft/MinecraftVersionList.cpp +++ b/logic/minecraft/MinecraftVersionList.cpp @@ -56,7 +56,7 @@ class MCVListVersionUpdateTask : public Task Q_OBJECT public: - explicit MCVListVersionUpdateTask(MinecraftVersionList *vlist, QString updatedVersion); + explicit MCVListVersionUpdateTask(MinecraftVersionList *vlist, std::shared_ptr updatedVersion); virtual ~MCVListVersionUpdateTask() override{}; virtual void executeTask() override; @@ -66,7 +66,7 @@ slots: protected: NetJobPtr specificVersionDownloadJob; - QString versionToUpdate; + std::shared_ptr updatedVersion; MinecraftVersionList *m_list; }; @@ -190,10 +190,7 @@ void MinecraftVersionList::loadBuiltinList() continue; } - // Get the download URL. - mcVersion->download_url = - "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + versionID + "/"; - + mcVersion->m_versionFileURL = QString(); mcVersion->m_versionSource = Builtin; mcVersion->m_type = versionTypeStr; mcVersion->m_appletClass = versionObj.value("appletClass").toString(""); @@ -293,9 +290,7 @@ void MinecraftVersionList::loadMojangList(QJsonDocument jsonDoc, VersionSource s // depends on where we load the version from -- network request or local file? mcVersion->m_versionSource = source; - - QString dlUrl = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + versionID + "/"; - mcVersion->download_url = dlUrl; + mcVersion->m_versionFileURL = versionObj.value("url").toString(""); QString versionTypeStr = versionObj.value("type").toString(""); if (versionTypeStr.isEmpty()) { @@ -479,20 +474,17 @@ void MCVListLoadTask::list_downloaded() return; } -MCVListVersionUpdateTask::MCVListVersionUpdateTask(MinecraftVersionList *vlist, - QString updatedVersion) +MCVListVersionUpdateTask::MCVListVersionUpdateTask(MinecraftVersionList *vlist, std::shared_ptr updatedVersion) : Task() { m_list = vlist; - versionToUpdate = updatedVersion; + this->updatedVersion = updatedVersion; } void MCVListVersionUpdateTask::executeTask() { - QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + versionToUpdate + "/" + - versionToUpdate + ".json"; auto job = new NetJob("Version index"); - job->addNetAction(ByteArrayDownload::make(QUrl(urlstr))); + job->addNetAction(ByteArrayDownload::make(QUrl(updatedVersion->getUrl()))); specificVersionDownloadJob.reset(job); connect(specificVersionDownloadJob.get(), SIGNAL(succeeded()), SLOT(json_downloaded())); connect(specificVersionDownloadJob.get(), SIGNAL(failed(QString)), SIGNAL(failed(QString))); @@ -518,7 +510,7 @@ void MCVListVersionUpdateTask::json_downloaded() VersionFilePtr file; try { - file = VersionFile::fromJson(jsonDoc, "net.minecraft.json", false); + file = VersionFile::fromMojangJson(jsonDoc, "net.minecraft.json"); } catch (Exception &e) { @@ -536,7 +528,8 @@ void MCVListVersionUpdateTask::json_downloaded() // now dump the file to disk auto doc = file->toJson(false); auto newdata = doc.toBinaryData(); - QString targetPath = "versions/" + versionToUpdate + "/" + versionToUpdate + ".dat"; + auto id = updatedVersion->descriptor(); + QString targetPath = "versions/" + id + "/" + id + ".dat"; FS::ensureFilePathExists(targetPath); QSaveFile vfile1(targetPath); if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly)) @@ -559,13 +552,23 @@ void MCVListVersionUpdateTask::json_downloaded() return; } - m_list->finalizeUpdate(versionToUpdate); + m_list->finalizeUpdate(id); emitSucceeded(); } std::shared_ptr MinecraftVersionList::createUpdateTask(QString version) { - return std::shared_ptr(new MCVListVersionUpdateTask(this, version)); + auto iter = m_lookup.find(version); + if(iter == m_lookup.end()) + return nullptr; + + auto mcversion = std::dynamic_pointer_cast(*iter); + if(!mcversion) + { + return nullptr; + } + + return std::shared_ptr(new MCVListVersionUpdateTask(this, mcversion)); } void MinecraftVersionList::saveCachedList() @@ -590,6 +593,7 @@ void MinecraftVersionList::saveCachedList() entryObj.insert("version", mcversion->descriptor()); entryObj.insert("time", mcversion->m_updateTimeString); entryObj.insert("releaseTime", mcversion->m_releaseTimeString); + entryObj.insert("url", mcversion->m_versionFileURL); entryObj.insert("type", mcversion->m_type); entriesArr.append(entryObj); } diff --git a/logic/minecraft/OneSixUpdate.cpp b/logic/minecraft/OneSixUpdate.cpp index 9159f038..75a16824 100644 --- a/logic/minecraft/OneSixUpdate.cpp +++ b/logic/minecraft/OneSixUpdate.cpp @@ -74,8 +74,7 @@ void OneSixUpdate::executeTask() } connect(versionUpdateTask.get(), SIGNAL(succeeded()), SLOT(jarlibStart())); connect(versionUpdateTask.get(), &NetJob::failed, this, &OneSixUpdate::versionUpdateFailed); - connect(versionUpdateTask.get(), SIGNAL(progress(qint64, qint64)), - SIGNAL(progress(qint64, qint64))); + connect(versionUpdateTask.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); setStatus(tr("Getting the version files from Mojang...")); versionUpdateTask->start(); } @@ -103,8 +102,7 @@ void OneSixUpdate::assetIndexStart() connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetIndexFinished())); connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::assetIndexFailed); - connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), - SIGNAL(progress(qint64, qint64))); + connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); qDebug() << m_inst->name() << ": Starting asset index download"; jarlibDownloadJob->start(); @@ -135,9 +133,7 @@ void OneSixUpdate::assetIndexFinished() QFileInfo objectFile("assets/objects/" + objectName); if ((!objectFile.isFile()) || (objectFile.size() != object.size)) { - auto objectDL = MD5EtagDownload::make( - QUrl("http://" + URLConstants::RESOURCE_BASE + objectName), - objectFile.filePath()); + auto objectDL = MD5EtagDownload::make(QUrl("http://" + URLConstants::RESOURCE_BASE + objectName), objectFile.filePath()); objectDL->m_total_progress = object.size; dls.append(objectDL); } @@ -151,8 +147,7 @@ void OneSixUpdate::assetIndexFinished() jarlibDownloadJob.reset(job); connect(jarlibDownloadJob.get(), SIGNAL(succeeded()), SLOT(assetsFinished())); connect(jarlibDownloadJob.get(), &NetJob::failed, this, &OneSixUpdate::assetsFailed); - connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), - SIGNAL(progress(qint64, qint64))); + connect(jarlibDownloadJob.get(), SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); jarlibDownloadJob->start(); return; } diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp index 601e1638..50f4c289 100644 --- a/logic/minecraft/VersionFile.cpp +++ b/logic/minecraft/VersionFile.cpp @@ -17,6 +17,23 @@ using namespace Json; #define CURRENT_MINIMUM_LAUNCHER_VERSION 18 +static void readString(const QJsonObject &root, const QString &key, QString &variable) +{ + if (root.contains(key)) + { + variable = requireString(root.value(key)); + } +} + +static QString readStringRet(const QJsonObject &root, const QString &key) +{ + if (root.contains(key)) + { + return requireString(root.value(key)); + } + return QString(); +} + int findLibraryByName(QList haystack, const GradleSpecifier &needle) { int retval = -1; @@ -33,8 +50,55 @@ int findLibraryByName(QList haystack, const GradleSpecifier &n return retval; } -VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &filename, - const bool requireOrder) +VersionFilePtr VersionFile::fromMojangJson(const QJsonDocument &doc, const QString &filename) +{ + VersionFilePtr out(new VersionFile()); + if (doc.isEmpty() || doc.isNull()) + { + throw JSONValidationError(filename + " is empty or null"); + } + if (!doc.isObject()) + { + throw JSONValidationError(filename + " is not an object"); + } + + QJsonObject root = doc.object(); + + out->name = root.value("name").toString(); + out->fileId = root.value("fileId").toString(); + out->version = root.value("version").toString(); + out->mcVersion = root.value("mcVersion").toString(); + out->filename = filename; + + readString(root, "id", out->id); + + readString(root, "mainClass", out->mainClass); + readString(root, "appletClass", out->appletClass); + readString(root, "minecraftArguments", out->overwriteMinecraftArguments); + readString(root, "type", out->type); + + readString(root, "assets", out->assets); + + if (root.contains("minimumLauncherVersion")) + { + out->minimumLauncherVersion = requireInteger(root.value("minimumLauncherVersion")); + } + + if (root.contains("libraries")) + { + out->shouldOverwriteLibs = true; + for (auto libVal : requireArray(root.value("libraries"))) + { + auto libObj = requireObject(libVal); + + auto lib = RawLibrary::fromJson(libObj, filename); + out->overwriteLibs.append(lib); + } + } + return out; +} + +VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder) { VersionFilePtr out(new VersionFile()); if (doc.isEmpty() || doc.isNull()) @@ -67,37 +131,20 @@ VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &fi out->mcVersion = root.value("mcVersion").toString(); out->filename = filename; - auto readString = [root](const QString &key, QString &variable) - { - if (root.contains(key)) - { - variable = requireString(root.value(key)); - } - }; - - auto readStringRet = [root](const QString &key) -> QString - { - if (root.contains(key)) - { - return requireString(root.value(key)); - } - return QString(); - }; - - readString("id", out->id); + readString(root, "id", out->id); - readString("mainClass", out->mainClass); - readString("appletClass", out->appletClass); - readString("processArguments", out->processArguments); - readString("minecraftArguments", out->overwriteMinecraftArguments); - readString("+minecraftArguments", out->addMinecraftArguments); - readString("-minecraftArguments", out->removeMinecraftArguments); - readString("type", out->type); + readString(root, "mainClass", out->mainClass); + readString(root, "appletClass", out->appletClass); + readString(root, "processArguments", out->processArguments); + readString(root, "minecraftArguments", out->overwriteMinecraftArguments); + readString(root, "+minecraftArguments", out->addMinecraftArguments); + readString(root, "-minecraftArguments", out->removeMinecraftArguments); + readString(root, "type", out->type); - parse_timestamp(readStringRet("releaseTime"), out->m_releaseTimeString, out->m_releaseTime); - parse_timestamp(readStringRet("time"), out->m_updateTimeString, out->m_updateTime); + parse_timestamp(readStringRet(root, "releaseTime"), out->m_releaseTimeString, out->m_releaseTime); + parse_timestamp(readStringRet(root, "time"), out->m_updateTimeString, out->m_updateTime); - readString("assets", out->assets); + readString(root, "assets", out->assets); if (root.contains("minimumLauncherVersion")) { diff --git a/logic/minecraft/VersionFile.h b/logic/minecraft/VersionFile.h index e5ce4026..5df1cd29 100644 --- a/logic/minecraft/VersionFile.h +++ b/logic/minecraft/VersionFile.h @@ -19,6 +19,7 @@ typedef std::shared_ptr VersionFilePtr; class VersionFile : public ProfilePatch { public: /* methods */ + static VersionFilePtr fromMojangJson(const QJsonDocument &doc, const QString &filename); static VersionFilePtr fromJson(const QJsonDocument &doc, const QString &filename, const bool requireOrder); virtual QJsonDocument toJson(bool saveOrder) override; -- cgit v1.2.3