Permalink
Browse files

Merge branch 'master' into ret

  • Loading branch information...
DolceTriade committed Sep 28, 2017
2 parents acf625c + 25939bf commit 767ece96c4b714a729d87ab72218e63cdc4c021c
Showing with 390 additions and 36 deletions.
  1. +3 −3 Dockerfile
  2. +2 −1 Dockerfile.win
  3. +1 −1 README.md
  4. +7 −0 ariadownloader.cpp
  5. +21 −4 currentversionfetcher.cpp
  6. +1 −1 currentversionfetcher.h
  7. +19 −4 downloadworker.cpp
  8. +3 −1 downloadworker.h
  9. +96 −0 osx.cpp
  10. +47 −18 qmldownloader.cpp
  11. +7 −1 qmldownloader.h
  12. +22 −0 resources/Info.plist
  13. BIN resources/Unvanquished.icns
  14. +20 −0 splash.qml
  15. +5 −0 system.h
  16. +73 −0 unix.cpp
  17. +2 −2 updater2.pro
  18. +61 −0 win.cpp
@@ -1,8 +1,8 @@
FROM freeslave/qt5-base-static:5.9.1-1
RUN apt-get install -y autopoint autoconf gettext libcppunit-dev libtool libgcrypt11-dev pkgconf
FROM dolcetriade/qt5-linux-static-openssl:5.9.0
RUN apt-get update && apt-get install -y autopoint autoconf gettext libcppunit-dev libtool libgcrypt11-dev pkgconf git
COPY . /updater2
WORKDIR /updater2/aria2
RUN autoreconf -i && ./configure --without-libxml2 --without-libexpat --without-sqlite3 --disable-ssl --enable-libaria2 --without-zlib --without-libcares --enable-static=yes ARIA2_STATIC=yes --without-libssh2 --disable-websocket && make clean && make -j`nproc`
RUN autoreconf -i && ./configure --without-libxml2 --without-libexpat --without-sqlite3 --enable-libaria2 --without-zlib --without-libcares --enable-static=yes ARIA2_STATIC=yes --without-libssh2 --disable-websocket && make clean && make -j`nproc`
WORKDIR /updater2
RUN qmake -config release && make clean && make -j`nproc`
CMD cp updater2 /build-docker
@@ -1,7 +1,8 @@
FROM dolcetriade/qt5-windows-static:5.8.0
RUN pacman -Sy --noconfirm git
COPY . /updater2
WORKDIR /updater2/aria2
RUN autoreconf -i && ./configure --without-libxml2 --without-libexpat --without-sqlite3 --disable-ssl --enable-libaria2 --without-libz --without-libcares --enable-static=yes ARIA2_STATIC=yes --without-libssh2 --disable-websocket --host i686-w64-mingw32 && make clean && make -j`nproc`
RUN autoreconf -i && ./configure --without-libxml2 --without-libexpat --without-sqlite3 --enable-libaria2 --without-libz --without-libcares --enable-static=yes ARIA2_STATIC=yes --without-libssh2 --disable-websocket --host i686-w64-mingw32 && make clean && make -j`nproc`
WORKDIR /updater2
ENV PATH=/build/qt-static/bin:$PATH
RUN qmake -config release CONFIG+=static INCLUDEPATH+=/build/qt-static/include/QtZlib QMAKE_LFLAGS+="-static -static-libgcc -static-libstdc++" && make clean && make -j`nproc`
@@ -11,7 +11,7 @@ Before building the updater itself you need to build aria2 library
```
cd aria2
autoreconf -i
./configure --without-libxml2 --without-libexpat --without-sqlite3 --disable-ssl --enable-libaria2 --without-zlib --without-libcares --enable-static=yes ARIA2_STATIC=yes --without-libssh2 --disable-websocket
./configure --without-libxml2 --without-libexpat --without-sqlite3 --enable-libaria2 --without-zlib --without-libcares --enable-static=yes ARIA2_STATIC=yes --without-libssh2 --disable-websocket
make -j4
cd ..
```
@@ -1,4 +1,5 @@
#include "ariadownloader.h"
#include "system.h"

#include <QDebug>

@@ -25,6 +26,12 @@ AriaDownloader::AriaDownloader() : callback_(nullptr)
options.push_back({ "seed-time", "0" });
options.push_back({ "file-allocation", "none" });
options.push_back({ "follow-torrent", "mem" });
options.push_back({ "quiet", "false" });

std::string certsPath = Sys::getCertStore();
if (!certsPath.empty()) {
options.push_back({ "ca-certificates", certsPath });
}
session = aria2::sessionNew(options, config);
}

@@ -3,6 +3,8 @@
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>

CurrentVersionFetcher::CurrentVersionFetcher(QObject* parent) : QObject(parent), manager(new QNetworkAccessManager(this))
{
@@ -17,11 +19,26 @@ void CurrentVersionFetcher::fetchCurrentVersion(QString url)

void CurrentVersionFetcher::reply(QNetworkReply* reply)
{
if (reply->error() == QNetworkReply::NoError) {
QString version = reply->readAll();
emit onCurrentVersion(version);
QString game;
QString updater;
if (reply->error() != QNetworkReply::NoError) {
emit onCurrentVersions(updater, game);
return;
}
emit onCurrentVersion("");
QJsonParseError error;
QJsonDocument json = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
emit onCurrentVersions(updater, game);
return;
}
QJsonValue value = json.object().value("updater");
if (value != QJsonValue::Undefined) {
updater = value.toString();
}
value = json.object().value("unvanquished");
if (value != QJsonValue::Undefined) {
game = value.toString();
}
emit onCurrentVersions(updater, game);
}

@@ -14,7 +14,7 @@ class CurrentVersionFetcher : public QObject
void fetchCurrentVersion(QString url);

signals:
void onCurrentVersion(QString version);
void onCurrentVersions(QString updater, QString game);

private slots:
void reply(QNetworkReply* reply);
@@ -7,6 +7,7 @@

#include "quazip/quazip/JlCompress.h"
#include "system.h"
#include <QDebug>

DownloadWorker::DownloadWorker(QObject *parent) : QObject(parent), downloadSpeed(0), uploadSpeed(0),
totalSize(0), completedSize(0), paused(true), state(IDLE), running(false), renameRegex(".*unvanquished_([0-9\\.]+/)")
@@ -19,9 +20,16 @@ DownloadWorker::~DownloadWorker()
downloader.unregisterCallback(this);
}

void DownloadWorker::addUri(const std::string& uri)
void DownloadWorker::addUpdaterUri(const std::string& uri)
{
downloader.addUri(uri);
state = DOWNLOADING_UPDATER;
}

void DownloadWorker::addTorrent(const std::string& uri)
{
downloader.addUri(uri);
state = DOWNLOADING_TORRENT;
}

void DownloadWorker::onDownloadCallback(aria2::Session* session, aria2::DownloadEvent event,
@@ -39,6 +47,16 @@ void DownloadWorker::onDownloadCallback(aria2::Session* session, aria2::Download
aria2::A2Gid torrentGid = handle->getFollowedBy()[0];
setDownloadPathAndFiles(session, torrentGid);
aria2::deleteDownloadHandle(handle);
} else if (state == DOWNLOADING_UPDATER) {
aria2::DownloadHandle* handle = aria2::getDownloadHandle(session, gid);
qDebug() << handle->getNumFiles();
if (handle->getNumFiles() > 1) {
return;
}
auto files = handle->getFiles();
qDebug() << files[0].path.c_str();
Sys::updateUpdater(QString(files[0].path.c_str()));
return;
} else {
event = aria2::EVENT_ON_BT_DOWNLOAD_COMPLETE;
if (!extractUpdate()) return;
@@ -52,9 +70,6 @@ void DownloadWorker::onDownloadCallback(aria2::Session* session, aria2::Download
break;

case aria2::EVENT_ON_DOWNLOAD_START:
if (state == IDLE) {
state = DOWNLOADING_TORRENT;
}
break;

case aria2::EVENT_ON_DOWNLOAD_STOP:
@@ -19,7 +19,8 @@ class DownloadWorker : public QObject, public AriaDownloader::DownloadCallback
~DownloadWorker();
void onDownloadCallback(aria2::Session* session, aria2::DownloadEvent event,
aria2::A2Gid gid, void* userDataevent);
void addUri(const std::string& uri);
void addUpdaterUri(const std::string& uri);
void addTorrent(const std::string& uri);
void setDownloadDirectory(const std::string& dir);
void toggle(void);
void stop(void);
@@ -42,6 +43,7 @@ public slots:
enum State {
IDLE,
DOWNLOADING_TORRENT,
DOWNLOADING_UPDATER,
DOWNLOADING_UNVANQUISHED
};

96 osx.cpp
@@ -1,7 +1,34 @@
#include "system.h"
#include "settings.h"
#include "quazip/quazip/JlCompress.h"

#include <QDir>
#include <QFile>
#include <QDebug>
#include <QCoreApplication>
#include <QFileInfo>
#include <QProcess>

namespace {
// Enter path of file within an app, and get the
// path of the app. Returns empty string if not within
// an app.
QString extractAppPath(const QString& path) {
QFileInfo info(path);
if (info.canonicalFilePath().contains(".app")) {
QDir path = info.absoluteDir();
while (!path.isRoot() && !path.absolutePath().endsWith(".app")) {
path.cdUp();
}
if (path.isRoot()) {
qDebug() << "Failed to find .app name.";
return "false""";
}
return path.absolutePath();
}
return "";
}
}

namespace Sys {
QString archiveName(void)
@@ -26,4 +53,73 @@ bool install(void)
QDir::homePath() + "/Applications/Unvanquished.app");
return true;
}

bool updateUpdater(const QString& updaterArchive)
{
QString currentAppPath = extractAppPath(QCoreApplication::applicationFilePath());
if (currentAppPath.isEmpty()) return false;
QDir currentApp(currentAppPath);
QDir backupUpdater(currentAppPath + ".bak");
if (backupUpdater.exists()) {
if (!backupUpdater.removeRecursively()) {
qDebug() << "Error deleting old update. pls update manually";
return false;
}
}
QDir extractDir = backupUpdater;
extractDir.cdUp();
if (!extractDir.rename(currentApp.dirName(), backupUpdater.dirName())) {
qDebug() << "Could not rename bkup. pls manually update.";
return false;
}
QStringList extractedFiles = JlCompress::extractDir(updaterArchive, extractDir.absolutePath());
if (extractedFiles.size() < 1) {
return false;
}
// Extract the .app name.
// Since it's an .app file, it must contain an Info.plist. Use
// this file to determine the .app name in the zip.
// NOTE: We could have hard coded this, but there is no guarantee
// that the person running this app is running the app that has
// the same name as the one in the zip.
constexpr char kFileInApp[] = "Info.plist";
QStringList infos = extractedFiles.filter(kFileInApp);
if (infos.size() < 1) {
qDebug() << "Error finding " << kFileInApp;
return false;
}

QString extractedAppPath = "";
for (int i = 0; i < infos.size() && extractedAppPath.isEmpty(); ++i) {
extractedAppPath = extractAppPath(infos[i]);
}
if (extractedAppPath.isEmpty()) return false;
QDir extractedApp(extractedAppPath);
if (extractedApp.dirName() != currentApp.dirName()) {
if (!extractDir.rename(extractedApp.dirName(), currentApp.dirName())) {
qDebug() << "Could not rename update. pls manually update.";
return false;
}
}
// TODO: Maybe don't use system? startDetached didn't work for me...
int i = system((QString("/usr/bin/open -F -n \"%1\"").arg(currentAppPath)).toStdString().c_str());
if (i != 0) {
qDebug() << "Error launching new updater. Please try manually.";
return false;
}
QCoreApplication::quit();
return true;
}

QString updaterArchiveName(void)
{
return "UnvUpdaterOSX.zip";
}

std::string getCertStore()
{
return ""; // Not used on OSX.
}


} // namespace Sys
@@ -8,9 +8,23 @@

namespace {
static const QRegularExpression COMMAND_REGEX("%command%");
static QString UPDATER_BASE_URL("http://github.com/Unvanquished/updater2/releases/download");
} // namespace

QmlDownloader::QmlDownloader() : worker_(nullptr), state_(IDLE) {}
QmlDownloader::QmlDownloader() : downloadSpeed_(0),
uploadSpeed_(0),
eta_(0),
totalSize_(0),
completedSize_(0),
paused_(true),
updater_update_(false),
worker_(nullptr),
state_(IDLE) {}

QmlDownloader::~QmlDownloader()
{
stopAria();
}

int QmlDownloader::downloadSpeed() const {
return downloadSpeed_;
@@ -118,7 +132,7 @@ void QmlDownloader::startUpdate(void)

worker_ = new DownloadWorker();
worker_->setDownloadDirectory(dir.canonicalPath().toStdString());
worker_->addUri("http://cdn.unvanquished.net/current.torrent");
worker_->addTorrent("http://cdn.unvanquished.net/current.torrent");
worker_->moveToThread(&thread_);
connect(&thread_, SIGNAL(finished()), worker_, SLOT(deleteLater()));
connect(worker_, SIGNAL(onDownloadEvent(int)), this, SLOT(onDownloadEvent(int)));
@@ -163,37 +177,52 @@ void QmlDownloader::stopAria(void)
}
}

void QmlDownloader::checkForUpdate() {
if (!settings_.installFinished()) {
void QmlDownloader::checkForUpdate()
{
if (networkManager_.isOnline()) {
connect(&fetcher_, SIGNAL(onCurrentVersions(QString, QString)), this, SLOT(onCurrentVersions(QString, QString)));
fetcher_.fetchCurrentVersion("http://dl.unvanquished.net/versions.json");
return;
}
else if (!settings_.installFinished()) {
emit updateNeeded(true);
return;
} else {
if (networkManager_.isOnline()) {
connect(&fetcher_, SIGNAL(onCurrentVersion(QString)), this, SLOT(onCurrentVersion(QString)));
fetcher_.fetchCurrentVersion("http://dl.unvanquished.net/current.txt");
return;
}
}
emit updateNeeded(false);
}

void QmlDownloader::onCurrentVersion(QString version) {
if (version.isEmpty() || settings_.currentVersion() != version) {
currentVersion_ = version;
void QmlDownloader::onCurrentVersions(QString updater, QString game)
{
if (!updater.isEmpty() && updater != QString(GIT_VERSION)) {
QString url = UPDATER_BASE_URL + "/" + updater + "/" + Sys::updaterArchiveName();
temp_dir_.reset(new QTemporaryDir());
worker_ = new DownloadWorker();
worker_->setDownloadDirectory(QDir(temp_dir_->path()).canonicalPath().toStdString());
worker_->addUpdaterUri(url.toStdString());
worker_->moveToThread(&thread_);
connect(&thread_, SIGNAL(finished()), worker_, SLOT(deleteLater()));
connect(worker_, SIGNAL(onDownloadEvent(int)), this, SLOT(onDownloadEvent(int)));
connect(worker_, SIGNAL(downloadSpeedChanged(int)), this, SLOT(setDownloadSpeed(int)));
connect(worker_, SIGNAL(uploadSpeedChanged(int)), this, SLOT(setUploadSpeed(int)));
connect(worker_, SIGNAL(totalSizeChanged(int)), this, SLOT(setTotalSize(int)));
connect(worker_, SIGNAL(completedSizeChanged(int)), this, SLOT(setCompletedSize(int)));
connect(&thread_, SIGNAL(started()), worker_, SLOT(download()));
thread_.start();
} else if (game.isEmpty() || settings_.currentVersion() != game) {
currentVersion_ = game;
emit updateNeeded(true);
} else {
emit updateNeeded(false);
}
}

QmlDownloader::DownloadState QmlDownloader::state() const {
QmlDownloader::DownloadState QmlDownloader::state() const
{
return state_;
}

void QmlDownloader::setState(DownloadState state) {
void QmlDownloader::setState(DownloadState state)
{
state_ = state;
emit stateChanged(state);
}



Oops, something went wrong.

0 comments on commit 767ece9

Please sign in to comment.