From 2e0cbf393a5320dbf5448ca44a9b5905314b0be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 29 Jul 2013 00:59:35 +0200 Subject: Massive renaming in the backend folder, all around restructure in the same. --- backend/tasks/GameUpdateTask.cpp | 283 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 backend/tasks/GameUpdateTask.cpp (limited to 'backend/tasks/GameUpdateTask.cpp') diff --git a/backend/tasks/GameUpdateTask.cpp b/backend/tasks/GameUpdateTask.cpp new file mode 100644 index 00000000..0a1df0e1 --- /dev/null +++ b/backend/tasks/GameUpdateTask.cpp @@ -0,0 +1,283 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "GameUpdateTask.h" + +#include + +#include +#include +#include +#include + +#include + +#include "lists/MinecraftVersionList.h" +#include "VersionFactory.h" +#include "OneSixVersion.h" + +#include "pathutils.h" + + +GameUpdateTask::GameUpdateTask(const LoginResponse &response, BaseInstance *inst, QObject *parent) : + Task(parent), m_response(response) +{ + m_inst = inst; + m_updateState = StateInit; +} + +void GameUpdateTask::executeTask() +{ + updateStatus(); + + // Get a pointer to the version object that corresponds to the instance's version. + targetVersion = (MinecraftVersion *)MinecraftVersionList::getMainList(). + findVersion(m_inst->intendedVersion()); + if(targetVersion == NULL) + { + //Q_ASSERT_X(targetVersion != NULL, "game update", "instance's intended version is not an actual version"); + setState(StateFinished); + emit gameUpdateComplete(m_response); + return; + } + + ///////////////////////// + // BUILD DOWNLOAD LIST // + ///////////////////////// + // Build a list of URLs that will need to be downloaded. + + setState(StateDetermineURLs); + + if (targetVersion->versionSource() == MinecraftVersion::Launcher16) + { + determineNewVersion(); + } + else + { + getLegacyJar(); + } + QEventLoop loop; + loop.exec(); +} + +void GameUpdateTask::determineNewVersion() +{ + QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/"); + urlstr += targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".json"; + auto dljob = DownloadJob::create(QUrl(urlstr)); + specificVersionDownloadJob.reset(new JobList()); + specificVersionDownloadJob->add(dljob); + connect(specificVersionDownloadJob.data(), SIGNAL(finished()), SLOT(versionFileFinished())); + connect(specificVersionDownloadJob.data(), SIGNAL(failed()), SLOT(versionFileFailed())); + connect(specificVersionDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64))); + download_queue.enqueue(specificVersionDownloadJob); +} + +void GameUpdateTask::versionFileFinished() +{ + JobPtr firstJob = specificVersionDownloadJob->getFirstJob(); + auto DlJob = firstJob.dynamicCast(); + FullVersionFactory parser; + auto version = parser.parse(DlJob->m_data); + + if(!version) + { + error(parser.error_string); + exit(0); + } + + if(version->isLegacy) + { + getLegacyJar(); + return; + } + + // save the version file in $instanceId/version.json and versions/$version/$version.json + QString version_id = targetVersion->descriptor(); + QString mc_dir = m_inst->minecraftDir(); + QString inst_dir = m_inst->rootDir(); + QString version1 = PathCombine(inst_dir, "/version.json"); + QString version2 = QString("versions/") + version_id + "/" + version_id + ".json"; + DownloadJob::ensurePathExists(version1); + DownloadJob::ensurePathExists(version2); + QFile vfile1 (version1); + QFile vfile2 (version2); + vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly ); + vfile2.open(QIODevice::Truncate | QIODevice::WriteOnly ); + vfile1.write(DlJob->m_data); + vfile2.write(DlJob->m_data); + vfile1.close(); + vfile2.close(); + + // download the right jar, save it in versions/$version/$version.jar + QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/"); + urlstr += targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".jar"; + QString targetstr ("versions/"); + targetstr += targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".jar"; + auto dljob = DownloadJob::create(QUrl(urlstr), targetstr); + + jarlibDownloadJob.reset(new JobList()); + jarlibDownloadJob->add(dljob); + connect(jarlibDownloadJob.data(), SIGNAL(finished()), SLOT(jarlibFinished())); + connect(jarlibDownloadJob.data(), SIGNAL(failed()), SLOT(jarlibFailed())); + connect(jarlibDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64))); + // determine and download all the libraries, save them in libraries/whatever... + download_queue.enqueue(jarlibDownloadJob); +} + +void GameUpdateTask::jarlibFinished() +{ + m_inst->setCurrentVersion(targetVersion->descriptor()); + m_inst->setShouldUpdate(false); + // m_inst->setIsForNewLauncher(true); + exit(1); +} + +void GameUpdateTask::jarlibFailed() +{ + error("Failed to download the binary garbage. Try again. Maybe. IF YOU DARE"); + exit(0); +} + +void GameUpdateTask::versionFileFailed() +{ + error("Failed to download the version description. Try again."); + exit(0); +} + + +// this is legacy minecraft... +void GameUpdateTask::getLegacyJar() +{ + // Make directories + QDir binDir(m_inst->binDir()); + if (!binDir.exists() && !binDir.mkpath(".")) + { + error("Failed to create bin folder."); + return; + } + + // Add the URL for minecraft.jar + // This will be either 'minecraft' or the version number, depending on where + // we're downloading from. + QString jarFilename = "minecraft"; + if (targetVersion->versionSource() == MinecraftVersion::Launcher16) + { + jarFilename = targetVersion->descriptor(); + } + + QUrl mcJarURL = targetVersion->downloadURL() + jarFilename + ".jar"; + qDebug() << mcJarURL.toString(); + auto dljob = DownloadJob::create(mcJarURL, PathCombine(m_inst->minecraftDir(), "bin/minecraft.jar")); + + legacyDownloadJob.reset(new JobList()); + legacyDownloadJob->add(dljob); + connect(legacyDownloadJob.data(), SIGNAL(finished()), SLOT(legacyJarFinished())); + connect(legacyDownloadJob.data(), SIGNAL(failed()), SLOT(legacyJarFailed())); + connect(legacyDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64))); + + download_queue.enqueue(legacyDownloadJob); +} + + +void GameUpdateTask::legacyJarFinished() +{ + setState(StateFinished); + emit gameUpdateComplete(m_response); + // m_inst->setIsForNewLauncher(true); + exit(1); +} + +void GameUpdateTask::legacyJarFailed() +{ + emit gameUpdateError("failed to download the minecraft.jar"); + exit(0); +} + +int GameUpdateTask::state() const +{ + return m_updateState; +} + +void GameUpdateTask::setState(int state, bool resetSubStatus) +{ + m_updateState = state; + if (resetSubStatus) + setSubStatus(""); + else // We only need to update if we're not resetting substatus becasue setSubStatus updates status for us. + updateStatus(); +} + +QString GameUpdateTask::subStatus() const +{ + return m_subStatusMsg; +} + +void GameUpdateTask::setSubStatus(const QString &msg) +{ + m_subStatusMsg = msg; + updateStatus(); +} + +QString GameUpdateTask::getStateMessage(int state) +{ + switch (state) + { + case StateInit: + return "Initializing"; + + case StateDetermineURLs: + return "Determining files to download"; + + case StateDownloadFiles: + return "Downloading files"; + + case StateInstall: + return "Installing"; + + case StateFinished: + return "Finished"; + + default: + return "Downloading instance files"; + } +} + +void GameUpdateTask::updateStatus() +{ + QString newStatus; + + newStatus = getStateMessage(state()); + if (!subStatus().isEmpty()) + newStatus += ": " + subStatus(); + else + newStatus += "..."; + + setStatus(newStatus); +} + + +void GameUpdateTask::error(const QString &msg) +{ + emit gameUpdateError(msg); +} + +void GameUpdateTask::updateDownloadProgress(qint64 current, qint64 total) +{ + // The progress on the current file is current / total + float currentDLProgress = (float) current / (float) total; + setProgress((int)(currentDLProgress * 100)); // convert to percentage +} + -- cgit v1.2.3