Bläddra i källkod

Merge pull request #2726 from Nordsoft91/launcher-size-support

Nordsoft91 2 år sedan
förälder
incheckning
24ad06b5c3

+ 4 - 0
config/schemas/mod.json

@@ -22,6 +22,10 @@
 					"type" : "string",
 					"description" : "Author of the mod. Can be nickname, real name or name of team"
 				},
+				"downloadSize": {
+					"type" : "number",
+					"description" : "Approximate size of mod, compressed by zip algorithm, in Mb"
+				},
 				"changelog" : {
 					"type" : "object",
 					"description" : "List of changes/new features in each version",

+ 9 - 5
launcher/modManager/cdownloadmanager_moc.cpp

@@ -18,13 +18,13 @@ CDownloadManager::CDownloadManager()
 		SLOT(downloadFinished(QNetworkReply *)));
 }
 
-void CDownloadManager::downloadFile(const QUrl & url, const QString & file)
+void CDownloadManager::downloadFile(const QUrl & url, const QString & file, qint64 bytesTotal)
 {
 	QNetworkRequest request(url);
 	FileEntry entry;
 	entry.file.reset(new QFile(CLauncherDirs::get().downloadsPath() + '/' + file));
 	entry.bytesReceived = 0;
-	entry.totalSize = 0;
+	entry.totalSize = bytesTotal;
 	entry.filename = file;
 
 	if(entry.file->open(QIODevice::WriteOnly | QIODevice::Truncate))
@@ -79,7 +79,7 @@ void CDownloadManager::downloadFinished(QNetworkReply * reply)
 				break;
 			}
 		}
-		downloadFile(qurl, filename);
+		downloadFile(qurl, filename, file.totalSize);
 		return;
 	}
 
@@ -131,7 +131,8 @@ void CDownloadManager::downloadProgressChanged(qint64 bytesReceived, qint64 byte
 
 	entry.file->write(entry.reply->readAll());
 	entry.bytesReceived = bytesReceived;
-	entry.totalSize = bytesTotal;
+	if(bytesTotal)
+		entry.totalSize = bytesTotal;
 
 	quint64 total = 0;
 	for(auto & entry : currentDownloads)
@@ -140,11 +141,14 @@ void CDownloadManager::downloadProgressChanged(qint64 bytesReceived, qint64 byte
 	quint64 received = 0;
 	for(auto & entry : currentDownloads)
 		received += entry.bytesReceived > 0 ? entry.bytesReceived : 0;
+	
+	if(received > total)
+		total = received;
 
 	emit downloadProgress(received, total);
 }
 
-bool CDownloadManager::downloadInProgress(const QUrl & url)
+bool CDownloadManager::downloadInProgress(const QUrl & url) const
 {
 	for(auto & entry : currentDownloads)
 	{

+ 2 - 2
launcher/modManager/cdownloadmanager_moc.h

@@ -48,10 +48,10 @@ public:
 
 	// returns true if download with such URL is in progress/queued
 	// FIXME: not sure what's right place for "mod download in progress" check
-	bool downloadInProgress(const QUrl & url);
+	bool downloadInProgress(const QUrl & url) const;
 
 	// returns network reply so caller can connect to required signals
-	void downloadFile(const QUrl & url, const QString & file);
+	void downloadFile(const QUrl & url, const QString & file, qint64 bytesTotal = 0);
 
 public slots:
 	void downloadFinished(QNetworkReply * reply);

+ 6 - 6
launcher/modManager/cmodlist.cpp

@@ -18,12 +18,9 @@
 
 QString CModEntry::sizeToString(double size)
 {
-	static const QString sizes[] =
-	{
-		/*"%1 B", */ "%1 KiB", "%1 MiB", "%1 GiB", "%1 TiB"
-	};
+	static const std::array<QString, 5> sizes { "%1 B", "%1 KiB", "%1 MiB", "%1 GiB", "%1 TiB" };
 	size_t index = 0;
-	while(size > 1024 && index < 4)
+	while(size > 1024 && index < sizes.size())
 	{
 		size /= 1024;
 		index++;
@@ -285,9 +282,10 @@ CModEntry CModList::getMod(QString modname) const
 					|| CModVersion::fromString(repo["version"].toString().toStdString())
 					 < CModVersion::fromString(repoValMap["version"].toString().toStdString()))
 				{
-					//take valid download link and screenshots before assignment
+					//take valid download link, screenshots and mod size before assignment
 					auto download = repo.value("download");
 					auto screenshots = repo.value("screenshots");
+					auto size = repo.value("downloadSize");
 					repo = repoValMap;
 					if(repo.value("download").isNull())
 					{
@@ -295,6 +293,8 @@ CModEntry CModList::getMod(QString modname) const
 						if(repo.value("screenshots").isNull()) //taking screenshot from the downloadable version
 							repo["screenshots"] = screenshots;
 					}
+					if(repo.value("downloadSize").isNull())
+						repo["downloadSize"] = size;
 				}
 			}
 		}

+ 25 - 17
launcher/modManager/cmodlistview_moc.cpp

@@ -27,6 +27,11 @@
 #include "../../lib/Languages.h"
 #include "../../lib/modding/CModVersion.h"
 
+static double mbToBytes(double mb)
+{
+	return mb * 1024 * 1024;
+}
+
 void CModListView::setupModModel()
 {
 	modModel = new CModListModel(this);
@@ -244,8 +249,11 @@ QString CModListView::genModInfoText(CModEntry & mod)
 	result += replaceIfNotEmpty(mod.getValue("installedVersion"), lineTemplate.arg(tr("Installed version")));
 	result += replaceIfNotEmpty(mod.getValue("latestVersion"), lineTemplate.arg(tr("Latest version")));
 
-	if(mod.getValue("size").isValid())
-		result += replaceIfNotEmpty(CModEntry::sizeToString(mod.getValue("size").toDouble()), lineTemplate.arg(tr("Download size")));
+	if(mod.getValue("localSizeBytes").isValid())
+		result += replaceIfNotEmpty(CModEntry::sizeToString(mod.getValue("localSizeBytes").toDouble()), lineTemplate.arg(tr("downloadSize")));
+	if((mod.isAvailable() || mod.isUpdateable()) && mod.getValue("downloadSize").isValid())
+		result += replaceIfNotEmpty(CModEntry::sizeToString(mbToBytes(mod.getValue("downloadSize").toDouble())), lineTemplate.arg(tr("Download size")));
+	
 	result += replaceIfNotEmpty(mod.getValue("author"), lineTemplate.arg(tr("Authors")));
 
 	if(mod.getValue("licenseURL").isValid())
@@ -536,7 +544,7 @@ void CModListView::on_updateButton_clicked()
 		auto mod = modModel->getMod(name);
 		// update required mod, install missing (can be new dependency)
 		if(mod.isUpdateable() || !mod.isInstalled())
-			downloadFile(name + ".zip", mod.getValue("download").toString(), "mods");
+			downloadFile(name + ".zip", mod.getValue("download").toString(), "mods", mbToBytes(mod.getValue("downloadSize").toDouble()));
 	}
 }
 
@@ -566,11 +574,11 @@ void CModListView::on_installButton_clicked()
 	{
 		auto mod = modModel->getMod(name);
 		if(!mod.isInstalled())
-			downloadFile(name + ".zip", mod.getValue("download").toString(), "mods");
+			downloadFile(name + ".zip", mod.getValue("download").toString(), "mods", mbToBytes(mod.getValue("downloadSize").toDouble()));
 	}
 }
 
-void CModListView::downloadFile(QString file, QString url, QString description)
+void CModListView::downloadFile(QString file, QString url, QString description, qint64 size)
 {
 	if(!dlManager)
 	{
@@ -585,28 +593,28 @@ void CModListView::downloadFile(QString file, QString url, QString description)
 		
 		connect(modModel, &CModListModel::dataChanged, filterModel, &QAbstractItemModel::dataChanged);
 
-
-		QString progressBarFormat = "Downloading %s%. %p% (%v KB out of %m KB) finished";
+		
+		QString progressBarFormat = tr("Downloading %s%. %p% (%v MB out of %m MB) finished");
 
 		progressBarFormat.replace("%s%", description);
 		ui->progressBar->setFormat(progressBarFormat);
 	}
 
-	dlManager->downloadFile(QUrl(url), file);
+	dlManager->downloadFile(QUrl(url), file, size);
 }
 
 void CModListView::downloadProgress(qint64 current, qint64 max)
 {
-	// display progress, in kilobytes
-	ui->progressBar->setMaximum(max / 1024);
-	ui->progressBar->setValue(current / 1024);
+	// display progress, in megabytes
+	ui->progressBar->setMaximum(max / (1024 * 1024));
+	ui->progressBar->setValue(current / (1024 * 1024));
 }
 
 void CModListView::downloadFinished(QStringList savedFiles, QStringList failedFiles, QStringList errors)
 {
-	QString title = "Download failed";
-	QString firstLine = "Unable to download all files.\n\nEncountered errors:\n\n";
-	QString lastLine = "\n\nInstall successfully downloaded?";
+	QString title = tr("Download failed");
+	QString firstLine = tr("Unable to download all files.\n\nEncountered errors:\n\n");
+	QString lastLine = tr("\n\nInstall successfully downloaded?");
 	bool doInstallFiles = false;
 
 	// if all files were d/loaded there should be no errors. And on failure there must be an error
@@ -789,8 +797,8 @@ void CModListView::checkManagerErrors()
 	QString errors = manager->getErrors().join('\n');
 	if(errors.size() != 0)
 	{
-		QString title = "Operation failed";
-		QString description = "Encountered errors:\n" + errors;
+		QString title = tr("Operation failed");
+		QString description = tr("Encountered errors:\n") + errors;
 		QMessageBox::warning(this, title, description, QMessageBox::Ok, QMessageBox::Ok);
 	}
 }
@@ -856,7 +864,7 @@ void CModListView::doInstallMod(const QString & modName)
 	{
 		auto mod = modModel->getMod(name);
 		if(!mod.isInstalled())
-			downloadFile(name + ".zip", mod.getValue("download").toString(), "mods");
+			downloadFile(name + ".zip", mod.getValue("download").toString(), "mods", mbToBytes(mod.getValue("downloadSize").toDouble()));
 	}
 }
 

+ 1 - 1
launcher/modManager/cmodlistview_moc.h

@@ -51,7 +51,7 @@ class CModListView : public QWidget
 	// find mods that depend on this one
 	QStringList findDependentMods(QString mod, bool excludeDisabled);
 
-	void downloadFile(QString file, QString url, QString description);
+	void downloadFile(QString file, QString url, QString description, qint64 size = 0);
 
 	void installMods(QStringList archives);
 	void installFiles(QStringList mods);

+ 13 - 5
launcher/modManager/cmodmanager.cpp

@@ -87,15 +87,23 @@ void CModManager::loadMods()
 		auto resID = CModInfo::getModFile(modname);
 		if(CResourceHandler::get()->existsResource(resID))
 		{
+			//calculate mod size
+			qint64 total = 0;
+			ResourcePath resDir(CModInfo::getModDir(modname), EResType::DIRECTORY);
+			if(CResourceHandler::get()->existsResource(resDir))
+			{
+				for(QDirIterator iter(QString::fromStdString(CResourceHandler::get()->getResourceName(resDir)->string()), QDirIterator::Subdirectories); iter.hasNext(); iter.next())
+					total += iter.fileInfo().size();
+			}
+			
 			boost::filesystem::path name = *CResourceHandler::get()->getResourceName(resID);
 			auto mod = JsonUtils::JsonFromFile(pathToQString(name));
+			auto json = JsonUtils::toJson(mod);
+			json["localSizeBytes"].Float() = total;
 			if(!name.is_absolute())
-			{
-				auto json = JsonUtils::toJson(mod);
 				json["storedLocaly"].Bool() = true;
-				mod = JsonUtils::toVariant(json);
-			}
-			
+
+			mod = JsonUtils::toVariant(json);
 			localMods.insert(QString::fromUtf8(modname.c_str()).toLower(), mod);
 		}
 	}