123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- #include "patchdownloader.h"
- #include "models/filesystem.h"
- #include <QApplication>
- #include <QDir>
- #include <QStringList>
- #include <QUrlQuery>
- #include <QVariant>
- #include <QDebug>
- PatchDownloader::PatchDownloader(QSettings *settings, QObject *parent) : QObject(parent), patch_download_dir(QApplication::applicationDirPath() + "/data")
- {
- app_settings = settings;
- active_downloads_number = 0;
- connect(&update_check_timer, &QTimer::timeout, this, &PatchDownloader::checkForUpdates);
- update_check_timer.setInterval(1000 * 60 * 5); // 5 minutes
- update_check_timer.start();
- }
- PatchDownloader::~PatchDownloader()
- {
- foreach (Downloader* downloader, downloads_list) {
- downloader->waitForDownloaded();
- downloader->deleteLater();
- }
- }
- void PatchDownloader::checkForUpdates()
- {
- foreach (QString patch_name, all_patch_names) {
- if (downloads_list.contains(patch_name))
- continue;
- downloads_list[patch_name] = new Downloader();
- connect(downloads_list[patch_name], &Downloader::progressChanged, this, &PatchDownloader::onDownloaderProgressChanged);
- connect(downloads_list[patch_name], &Downloader::downloadFinished, this, &PatchDownloader::onDownloaderCompleted);
- }
- if (active_downloads_number > 0) {
- qDebug() << "PatchDownloader: downloads are not ready yet, passing checkForUpdates";
- return;
- }
- emit checkForUpdatesStarted();
- if (!updatePatchList()) {
- emit checkForUpdatesFinished();
- return;
- }
- removeOldPatchesFromDirecrory();
- addMissingPatchesToDownloadList();
- emit checkForUpdatesFinished();
- }
- void PatchDownloader::onDownloaderCompleted(Downloader *downloader_ptr)
- {
- if (downloader_ptr->targetFile) {
- downloader_ptr->targetFile->close();
- downloader_ptr->targetFile->deleteLater();
- }
- active_downloads_number--;
- if (active_downloads_number == 0) {
- emit downloadCompleted();
- }
- }
- void PatchDownloader::onDownloaderProgressChanged(Downloader*)
- {
- quint64 totalSize = 0;
- quint64 downloadedSize = 0;
- quint64 summary_speed = 0;
- quint64 time_elapsed = 0;
- foreach (Downloader* downloader, downloads_list) {
- totalSize += downloader->getBytesTotal();
- downloadedSize += downloader->getBytesDownloaded();
- if (downloader->getBytesTotal() != downloader->getBytesDownloaded()) {
- summary_speed += downloader->getSpeed();
- }
- }
- time_elapsed = (totalSize - downloadedSize) / qMax(quint64(1), summary_speed);
- emit progressChanged(downloadedSize, totalSize,
- Downloader::getSpeedFormatted(summary_speed),
- Downloader::getElapsedTimeFormatted(time_elapsed));
- }
- int PatchDownloader::versionFromPatchFilename(QString filename)
- {
- int version = 0;
- for (int i = filename.indexOf("_v") + 2; i < filename.indexOf("_v") + 7; i += 2) {
- version = version * 10 + (filename.at(i).toLatin1() - '0');
- }
- return version;
- }
- bool PatchDownloader::updatePatchList()
- {
- QUrlQuery query; // query for building GET-request aka patch-version
- foreach (QString patch_name, all_patch_names) {
- query.addQueryItem(patch_name, "100");
- }
- QUrl target_url;
- target_url.setUrl("http://translate.lotros.ru/groupware/check_updates");
- target_url.setQuery(query);
- QByteArray target_array;
- Downloader downloader;
- downloader.setUrl(target_url);
- downloader.targetBytearray = &target_array;
- downloader.start();
- downloader.waitForDownloaded();
- if (target_array.isEmpty()) {
- qDebug() << __FUNCTION__ << "Cannot download, target_array is empty!";
- emit getPatchListError();
- return false;
- }
- QStringList entry_list = QString(target_array).split('|');
- if (entry_list.size() != all_patch_names.size()) {
- qDebug() << __FUNCTION__ << "Entry list size is not equal to patch names size!" << QString(target_array);
- emit getPatchListError();
- return false;
- }
- for (int i = 0; i < entry_list.size(); ++i) {
- QStringList current_patch_data = entry_list[i].split(":::");
- if (current_patch_data.size() != 3) {
- qDebug() << __FUNCTION__ << "Incorrect patch entry size! Entry: " << entry_list[i];
- emit getPatchListError();
- return false;
- }
- patch_data[all_patch_names[i]] = {current_patch_data[0], current_patch_data[1], current_patch_data[2], all_patch_names[i]};
- }
- return true;
- }
- bool PatchDownloader::removeOldPatchesFromDirecrory()
- {
- QStringList actual_hash_list;
- foreach (Patch patch, patch_data) {
- actual_hash_list.append(patch.md5_hash);
- }
- qDebug() << "Removing old patches. Current hash list " << actual_hash_list;
- QStringList paths = patch_download_dir.entryList(QDir::Files);
- foreach (QString filename, paths) {
- QString hash = FileSystem::fileHash(patch_download_dir.absolutePath() + "/" + filename, QCryptographicHash::Md5);
- if (!actual_hash_list.contains(hash)) {
- qDebug() << "File " << filename << " with hash " << hash << "seems outdated, deleting!";
- if (!QFile::remove(patch_download_dir.absolutePath() + "/" +filename)) {
- qDebug() << __FUNCTION__ << "Unable to remove file " << filename;
- emit removeFileError(patch_download_dir.absolutePath() + "/" + filename);
- }
- }
- }
- return true;
- }
- bool PatchDownloader::addMissingPatchesToDownloadList()
- {
- QDir dir(patch_download_dir);
- if (!dir.exists())
- QDir().mkdir(patch_download_dir.absolutePath());
- bool download_started = false;
- foreach (Patch patch, patch_data) {
- QString patch_filepath = patch_download_dir.absolutePath() + "/" + patch.url.fileName();
- qDebug() << "Patch" << patch.name << "is marked as" << app_settings->value("patches/" + patch.name, "Disabled");
- if (app_settings->value("patches/" + patch.name, "Disabled").toString() != "Enabled")
- continue;
- if (FileSystem::fileExists(patch_filepath)) {
- if (FileSystem::fileHash(patch_filepath, QCryptographicHash::Md5) == patch.md5_hash)
- continue;
- if (!QFile::remove(patch_filepath)) {
- qDebug() << __FUNCTION__ << "Unable to remove file " << patch_filepath;
- emit removeFileError(patch_filepath);
- continue;
- }
- }
- if (!download_started) {
- download_started = true;
- qDebug() << "Started downloads of PatchDownloader!";
- emit downloadStarted();
- }
- qDebug() << "Starting download of file " << patch_filepath << " from url " << patch.url;
- downloads_list[patch.name]->setUrl(patch.url);
- downloads_list[patch.name]->targetFile = new QFile(patch_filepath, downloads_list[patch.name]);
- downloads_list[patch.name]->targetFile->open(QIODevice::ReadWrite);
- downloads_list[patch.name]->start();
- active_downloads_number++;
- }
- return true;
- }
|