diff options
Diffstat (limited to 'logic/updater/DownloadUpdateTask.h')
-rw-r--r-- | logic/updater/DownloadUpdateTask.h | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/logic/updater/DownloadUpdateTask.h b/logic/updater/DownloadUpdateTask.h new file mode 100644 index 00000000..f5b23d12 --- /dev/null +++ b/logic/updater/DownloadUpdateTask.h @@ -0,0 +1,192 @@ +/* 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. + */ + +#pragma once + +#include "logic/tasks/Task.h" +#include "logic/net/NetJob.h" + +/*! + * The DownloadUpdateTask is a task that takes a given version ID and repository URL, + * downloads that version's files from the repository, and prepares to install them. + */ +class DownloadUpdateTask : public Task +{ + Q_OBJECT + +public: + explicit DownloadUpdateTask(QString repoUrl, int versionId, QObject* parent=0); + + /*! + * Gets the directory that contains the update files. + */ + QString updateFilesDir(); + +protected: + // TODO: We should probably put these data structures into a separate header... + + /*! + * Struct that describes an entry in a VersionFileEntry's `Sources` list. + */ + struct FileSource + { + FileSource(QString type, QString url, QString compression="") + { + this->type = type; + this->url = url; + this->compressionType = compression; + } + + QString type; + QString url; + QString compressionType; + }; + + typedef QList<FileSource> FileSourceList; + + /*! + * Structure that describes an entry in a GoUpdate version's `Files` list. + */ + struct VersionFileEntry + { + QString path; + int mode; + FileSourceList sources; + QString md5; + }; + + typedef QList<VersionFileEntry> VersionFileList; + + + /*! + * Structure that describes an operation to perform when installing updates. + */ + struct UpdateOperation + { + static UpdateOperation CopyOp(QString fsource, QString fdest, int fmode=0644) { return UpdateOperation{OP_COPY, fsource, fdest, fmode}; } + static UpdateOperation MoveOp(QString fsource, QString fdest, int fmode=0644) { return UpdateOperation{OP_MOVE, fsource, fdest, fmode}; } + static UpdateOperation DeleteOp(QString file) { return UpdateOperation{OP_DELETE, file, "", 0644}; } + static UpdateOperation ChmodOp(QString file, int fmode) { return UpdateOperation{OP_CHMOD, file, "", fmode}; } + + //! Specifies the type of operation that this is. + enum Type + { + OP_COPY, + OP_DELETE, + OP_MOVE, + OP_CHMOD, + } type; + + //! The file to operate on. If this is a DELETE or CHMOD operation, this is the file that will be modified. + QString file; + + //! The destination file. If this is a DELETE or CHMOD operation, this field will be ignored. + QString dest; + + //! The mode to change the source file to. Ignored if this isn't a CHMOD operation. + int mode; + + // Yeah yeah, polymorphism blah blah inheritance, blah blah object oriented. I'm lazy, OK? + }; + + typedef QList<UpdateOperation> UpdateOperationList; + + /*! + * Used for arguments to parseVersionInfo and friends to specify which version info file to parse. + */ + enum VersionInfoFileEnum { NEW_VERSION, CURRENT_VERSION }; + + + //! Entry point for tasks. + virtual void executeTask(); + + /*! + * Attempts to find the version ID and repository URL for the current version. + * The function will look up the repository URL in the UpdateChecker's channel list. + * If the repository URL can't be found, this function will return false. + */ + virtual void findCurrentVersionInfo(); + + /*! + * Downloads the version info files from the repository. + * The files for both the current build, and the build that we're updating to need to be downloaded. + * If the current version's info file can't be found, MultiMC will not delete files that + * were removed between versions. It will still replace files that have changed, however. + * Note that although the repository URL for the current version is not given to the update task, + * the task will attempt to look it up in the UpdateChecker's channel list. + * If an error occurs here, the function will call emitFailed and return false. + */ + virtual void loadVersionInfo(); + + /*! + * This function is called when version information is finished downloading. + * This handles parsing the JSON downloaded by the version info network job and then calls processFileLists. + * Note that this function will sometimes be called even if the version info download emits failed. If + * we couldn't download the current version's info file, we can still update. This will be called even if the + * current version's info file fails to download, as long as the new version's info file succeeded. + */ + virtual void parseDownloadedVersionInfo(); + + /*! + * Loads the file list from the given version info JSON object into the given list. + */ + virtual void parseVersionInfo(VersionInfoFileEnum vfile, VersionFileList* list); + + /*! + * Takes a list of file entries for the current version's files and the new version's files + * and populates the downloadList and operationList with information about how to download and install the update. + */ + virtual void processFileLists(); + + /*! + * Takes the operations list and writes an install script for the updater to the update files directory. + */ + virtual void writeInstallScript(UpdateOperationList& opsList, QString scriptFile); + + VersionFileList m_downloadList; + UpdateOperationList m_operationList; + + VersionFileList m_nVersionFileList; + VersionFileList m_cVersionFileList; + + //! Network job for downloading version info files. + NetJobPtr m_vinfoNetJob; + + //! Network job for downloading update files. + NetJobPtr m_filesNetJob; + + // Version ID and repo URL for the new version. + int m_nVersionId; + QString m_nRepoUrl; + + // Version ID and repo URL for the currently installed version. + int m_cVersionId; + QString m_cRepoUrl; + + /*! + * Temporary directory to store update files in. + * This will be set to not auto delete. Task will fail if this fails to be created. + */ + QTemporaryDir m_updateFilesDir; + +protected slots: + void vinfoDownloadFinished(); + void vinfoDownloadFailed(); + + void fileDownloadFinished(); + void fileDownloadFailed(); + void fileDownloadProgressChanged(qint64 current, qint64 total); +}; + |