193 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* 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);
 | 
						|
};
 | 
						|
 |