Skip to content

Commit 0f81b66

Browse files
committed
WIP: attempt to restart torrent download
1 parent abc4af0 commit 0f81b66

File tree

8 files changed

+108
-44
lines changed

8 files changed

+108
-44
lines changed

currentversionfetcher.cpp

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ void CurrentVersionFetcher::fetchCurrentVersion()
5353
}
5454
}
5555

56-
void ComponentVersionFetcher(QJsonObject components, QString name, QString system, QString *version, QString *url)
56+
void ComponentVersionFetcher(QJsonObject components, QString name, QString system, QString *version, std::vector<QString> *urls)
5757
{
58-
QString mirror;
5958
QString path;
59+
QJsonArray mirrors;
6060

6161
QJsonObject component = components[name].toObject();
6262

@@ -70,11 +70,9 @@ void ComponentVersionFetcher(QJsonObject components, QString name, QString syste
7070
*version = versionValue.toString();
7171
}
7272

73-
QJsonArray mirrors = component["mirrors"].toArray();
73+
mirrors = component["mirrors"].toArray();
7474
if (!mirrors.count()) {
7575
qDebug() << "ComponentVersionFetcher: undefined “mirrors” key for " << name;
76-
} else {
77-
mirror = mirrors.first().toString();
7876
}
7977

8078
QJsonObject parcels = component["parcels"].toObject();
@@ -95,33 +93,38 @@ void ComponentVersionFetcher(QJsonObject components, QString name, QString syste
9593
}
9694
}
9795

98-
*url = mirror + path;
99-
10096
qDebug() << "ComponentVersionFetcher: fetched component =" << name;
10197
qDebug() << "ComponentVersionFetcher: fetched system =" << system;
10298
qDebug() << "ComponentVersionFetcher: fetched version =" << *version;
103-
qDebug() << "ComponentVersionFetcher: fetched mirror =" << mirror;
10499
qDebug() << "ComponentVersionFetcher: fetched path =" << path;
105-
qDebug() << "ComponentVersionFetcher: fetched url =" << *url;
100+
101+
for (auto m : mirrors)
102+
{
103+
QString mirror = m.toString();
104+
qDebug() << "ComponentVersionFetcher: fetched mirror =" << mirror;
105+
QString url = mirror + path;
106+
qDebug() << "ComponentVersionFetcher: fetched url =" << url;
107+
urls->push_back(url);
108+
}
106109
}
107110

108111
void CurrentVersionFetcher::reply(QNetworkReply* reply)
109112
{
110113
QString formatVersion;
111114
QString updaterVersion;
112-
QString updaterUrl;
115+
std::vector<QString> updaterUrls;
113116
QString gameVersion;
114-
QString gameUrl;
117+
std::vector<QString> gameUrls;
115118
QString newsVersion;
116-
QString newsUrl;
119+
std::vector<QString> newsUrls;
117120

118121
if (reply->error() != QNetworkReply::NoError) {
119122
qDebug() << "CurrentVersionFetcher: network error";
120123

121124
if (versionMirror) {
122125
fetchCurrentVersion();
123126
} else {
124-
emit onCurrentVersions(updaterVersion, updaterUrl, gameVersion, gameUrl, newsUrl);
127+
emit onCurrentVersions(updaterVersion, updaterUrls, gameVersion, gameUrls, "");
125128
}
126129
return;
127130
}
@@ -130,7 +133,7 @@ void CurrentVersionFetcher::reply(QNetworkReply* reply)
130133
QJsonDocument json = QJsonDocument::fromJson(reply->readAll(), &error);
131134
if (error.error != QJsonParseError::NoError) {
132135
qDebug() << "CurrentVersionFetcher: JSON parsing error";
133-
emit onCurrentVersions(updaterVersion, updaterUrl, gameVersion, gameUrl, newsUrl);
136+
emit onCurrentVersions(updaterVersion, updaterUrls, gameVersion, gameUrls, "");
134137
return;
135138
}
136139

@@ -140,6 +143,8 @@ void CurrentVersionFetcher::reply(QNetworkReply* reply)
140143

141144
if (formatVersionValue == QJsonValue::Undefined) {
142145
qDebug() << "ComponentVersionFetcher: missing “version” value in current.json";
146+
emit onCurrentVersions(updaterVersion, updaterUrls, gameVersion, gameUrls, "");
147+
return;
143148
} else {
144149
formatVersion = formatVersionValue.toString();
145150
}
@@ -148,18 +153,20 @@ void CurrentVersionFetcher::reply(QNetworkReply* reply)
148153

149154
if (componentsValue == QJsonValue::Undefined) {
150155
qDebug() << "ComponentVersionFetcher: missing “components” array in current.json";
156+
emit onCurrentVersions(updaterVersion, updaterUrls, gameVersion, gameUrls, "");
157+
return;
151158
} else {
152159
qDebug() << "ComponentVersionFetcher: fetched format = " << formatVersion;
153160

154161
QJsonObject components = componentsValue.toObject();
155162

156-
ComponentVersionFetcher(components, "updater", Sys::updaterSystem(), &updaterVersion, &updaterUrl);
163+
ComponentVersionFetcher(components, "updater", Sys::updaterSystem(), &updaterVersion, &updaterUrls);
157164

158-
ComponentVersionFetcher(components, "game", "all-all", &gameVersion, &gameUrl);
165+
ComponentVersionFetcher(components, "game", "all-all", &gameVersion, &gameUrls);
159166

160-
ComponentVersionFetcher(components, "news", "all-all", &newsVersion, &newsUrl);
167+
ComponentVersionFetcher(components, "news", "all-all", &newsVersion, &newsUrls);
161168
}
162169

163-
emit onCurrentVersions(updaterVersion, updaterUrl, gameVersion, gameUrl, newsUrl);
170+
emit onCurrentVersions(updaterVersion, updaterUrls, gameVersion, gameUrls, newsUrls.at(0));
164171
}
165172

currentversionfetcher.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class CurrentVersionFetcher : public QObject
3131
void fetchCurrentVersion();
3232

3333
signals:
34-
void onCurrentVersions(QString updaterVersion, QString updaterUrl, QString gameVersion, QString gameUrl, QString newsUrl);
34+
void onCurrentVersions(QString updaterVersion, std::vector<QString> updaterUrls, QString gameVersion, std::vector<QString> gameUrls, QString newsUrl);
3535

3636
private slots:
3737
void reply(QNetworkReply* reply);

downloadworker.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ std::string DownloadWorker::getAriaIndexOut(size_t index, std::string path)
143143
return std::to_string(index) + "=" + oldPath.toStdString();
144144
}
145145

146-
147-
148146
void DownloadWorker::download()
149147
{
150148
auto start = std::chrono::steady_clock::now();

qmldownloader.cpp

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,13 @@ void QmlDownloader::onDownloadEvent(int event)
122122
break;
123123

124124
case aria2::EVENT_ON_DOWNLOAD_ERROR:
125-
emit fatalMessage("Error received while downloading");
125+
if (!downloadRestarter_) {
126+
emit fatalMessage("Error: downloadRestarter unset");
127+
}
128+
stopAria();
129+
if (!(this->*downloadRestarter_)()) {
130+
emit fatalMessage("Error received while downloading");
131+
}
126132
break;
127133

128134
case aria2::EVENT_ON_DOWNLOAD_PAUSE:
@@ -143,7 +149,7 @@ void QmlDownloader::onDownloadEvent(int event)
143149
}
144150
}
145151

146-
void QmlDownloader::startUpdate(const QString& selectedInstallPath)
152+
void QmlDownloader::setInstallPath(const QString& selectedInstallPath)
147153
{
148154
qDebug() << "Selected install path:" << selectedInstallPath;
149155
if (!Sys::validateInstallPath(selectedInstallPath)) {
@@ -159,26 +165,38 @@ void QmlDownloader::startUpdate(const QString& selectedInstallPath)
159165
return;
160166
}
161167
}
168+
162169
if (!QFileInfo(selectedInstallPath).isWritable()) {
163170
emit fatalMessage("Install dir not writable. Please select another");
164171
return;
165172
}
166173

167-
QString gameUrl = splashController_.gameUrl();
168-
qDebug() << "Using torrent file:" << gameUrl;
169174
// Persist the install path only now that download has been initiated and we know the path is good
170175
emit statusMessage("Installing to " + dir.canonicalPath());
171176
if (settings_.installPath() != selectedInstallPath) {
172177
qDebug() << "Clearing installed version because path was changed";
173178
settings_.setInstalledVersion("");
174179
}
175180
settings_.setInstallPath(selectedInstallPath);
181+
}
182+
183+
bool QmlDownloader::startUpdate()
184+
{
185+
QString gameUrl = splashController_.gameUrl();
186+
if (gameUrl.isEmpty()) {
187+
return false;
188+
}
189+
190+
qDebug() << "Using torrent URL:" << gameUrl;
191+
192+
QDir dir(settings_.installPath());
176193

177194
setState(DOWNLOADING);
178195
worker_ = new DownloadWorker(ariaLogFilename_);
179196
worker_->setDownloadDirectory(dir.canonicalPath().toStdString());
180197
worker_->addTorrent(gameUrl.toStdString());
181198
worker_->moveToThread(&thread_);
199+
setDownloadRestarter(&QmlDownloader::startUpdate);
182200
connect(&thread_, SIGNAL(finished()), worker_, SLOT(deleteLater()));
183201
connect(worker_, SIGNAL(onDownloadEvent(int)), this, SLOT(onDownloadEvent(int)));
184202
connect(worker_, SIGNAL(downloadSpeedChanged(int)), this, SLOT(setDownloadSpeed(int)));
@@ -187,14 +205,17 @@ void QmlDownloader::startUpdate(const QString& selectedInstallPath)
187205
connect(worker_, SIGNAL(completedSizeChanged(int)), this, SLOT(setCompletedSize(int)));
188206
connect(&thread_, SIGNAL(started()), worker_, SLOT(download()));
189207
thread_.start();
208+
209+
return true;
190210
}
191211

192212
void QmlDownloader::toggleDownload(QString installPath)
193213
{
194214
qDebug() << "QmlDownloader::toggleDownload called";
195215
if (state() == COMPLETED) return;
196216
if (!worker_) {
197-
startUpdate(installPath);
217+
setInstallPath(installPath);
218+
startUpdate();
198219
return;
199220
}
200221
QMetaObject::invokeMethod(worker_, "toggle");
@@ -212,14 +233,22 @@ void QmlDownloader::stopAria()
212233
}
213234
}
214235

215-
void QmlDownloader::startUpdaterUpdate(QString updaterUrl)
236+
bool QmlDownloader::startUpdaterUpdate()
216237
{
238+
QString updaterUrl = splashController_.updaterUrl();
239+
if (updaterUrl.isEmpty()) {
240+
return false;
241+
}
242+
243+
qDebug() << "Using updater URL:" << updaterUrl;
244+
217245
temp_dir_.reset(new QTemporaryDir());
218246
worker_ = new DownloadWorker(ariaLogFilename_);
219247
worker_->setDownloadDirectory(QDir(temp_dir_->path()).canonicalPath().toStdString());
220248
worker_->setConnectUrl(connectUrl_);
221249
worker_->addUpdaterUri(updaterUrl.toStdString());
222250
worker_->moveToThread(&thread_);
251+
setDownloadRestarter(&QmlDownloader::startUpdaterUpdate);
223252
connect(&thread_, SIGNAL(finished()), worker_, SLOT(deleteLater()));
224253
connect(worker_, SIGNAL(onDownloadEvent(int)), this, SLOT(onDownloadEvent(int)));
225254
connect(worker_, SIGNAL(downloadSpeedChanged(int)), this, SLOT(setDownloadSpeed(int)));
@@ -228,6 +257,8 @@ void QmlDownloader::startUpdaterUpdate(QString updaterUrl)
228257
connect(worker_, SIGNAL(completedSizeChanged(int)), this, SLOT(setCompletedSize(int)));
229258
connect(&thread_, SIGNAL(started()), worker_, SLOT(download()));
230259
thread_.start();
260+
261+
return true;
231262
}
232263

233264
QmlDownloader::DownloadState QmlDownloader::state() const
@@ -240,3 +271,8 @@ void QmlDownloader::setState(DownloadState state)
240271
state_ = state;
241272
emit stateChanged(state);
242273
}
274+
275+
void QmlDownloader::setDownloadRestarter(DownloadRestarter downloadRestarter)
276+
{
277+
downloadRestarter_ = downloadRestarter;
278+
}

qmldownloader.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "splashcontroller.h"
3333
#include "settings.h"
3434

35+
3536
class QmlDownloader : public QObject
3637
{
3738
Q_OBJECT
@@ -82,13 +83,17 @@ public slots:
8283
void onDownloadEvent(int event);
8384

8485
Q_INVOKABLE void toggleDownload(QString installPath);
85-
Q_INVOKABLE void startUpdaterUpdate(QString version);
8686

8787
private:
88+
using DownloadRestarter = bool (QmlDownloader::*)();
89+
8890
void stopAria();
8991
void setState(DownloadState state);
92+
void setInstallPath(const QString& selectedInstallPath);
9093
void startDownload(const QUrl& url, const QDir& destination);
91-
void startUpdate(const QString& selectedInstallPath);
94+
void setDownloadRestarter(DownloadRestarter downloadRestarter);
95+
bool startUpdate();
96+
bool startUpdaterUpdate();
9297
void launchGameIfInstalled();
9398

9499
QString ariaLogFilename_;
@@ -102,6 +107,7 @@ public slots:
102107
std::chrono::seconds eta_;
103108
int totalSize_;
104109
int completedSize_;
110+
DownloadRestarter downloadRestarter_ = nullptr;
105111

106112
DownloadWorker* worker_;
107113
DownloadTimeCalculator downloadTime_;

splash.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ ApplicationWindow {
7575
}
7676

7777
function onUpdaterUpdate(version) {
78-
downloader.startUpdaterUpdate(updaterUrl);
78+
downloader.startUpdaterUpdate();
7979
updaterUpdateLabel.visible = true;
8080

8181
// Now allow the window to go behind other windows in the z-order.

splashcontroller.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,33 +45,49 @@ void SplashController::checkForUpdate()
4545
return;
4646
}
4747

48-
connect(&fetcher_, SIGNAL(onCurrentVersions(QString, QString, QString, QString, QString)),
49-
this, SLOT(onCurrentVersions(QString, QString, QString, QString, QString)));
48+
connect(&fetcher_, SIGNAL(onCurrentVersions(QString, std::vector<QString>, QString, std::vector<QString>, QString)),
49+
this, SLOT(onCurrentVersions(QString, std::vector<QString>, QString, std::vector<QString>, QString)));
5050

5151
fetcher_.fetchCurrentVersion();
5252
}
5353

54-
QString SplashController::gameUrl() const {
55-
return latestGameUrl_;
54+
QString SplashController::updaterUrl() {
55+
if (latestUpdaterUrls_.empty()) {
56+
return "";
57+
}
58+
59+
QString url = latestUpdaterUrls_.at(0);
60+
latestUpdaterUrls_.erase(latestUpdaterUrls_.begin());
61+
return url;
62+
}
63+
64+
QString SplashController::gameUrl() {
65+
if (latestUpdaterUrls_.empty()) {
66+
return "";
67+
}
68+
69+
QString url = latestGameUrls_.at(0);
70+
latestGameUrls_.erase(latestGameUrls_.begin());
71+
return url;
5672
}
5773

5874
QString SplashController::newsUrl() const {
5975
return latestNewsUrl_;
6076
}
6177

6278
// Receives the results of the checkForUpdate request.
63-
void SplashController::onCurrentVersions(QString updaterVersion, QString updaterUrl, QString gameVersion, QString gameUrl, QString newsUrl)
79+
void SplashController::onCurrentVersions(QString updaterVersion, std::vector<QString> updaterUrls, QString gameVersion, std::vector<QString> gameUrls, QString newsUrl)
6480
{
6581
latestUpdaterVersion_ = updaterVersion;
66-
latestUpdaterUrl_ = updaterUrl;
82+
latestUpdaterUrls_ = updaterUrls;
6783
latestGameVersion_ = gameVersion;
68-
latestGameUrl_ = gameUrl;
84+
latestGameUrls_ = gameUrls;
6985
latestNewsUrl_ = newsUrl;
7086

7187
emit newsUrlFetched(newsUrl);
7288

7389
if (relaunchCommand_ == RelaunchCommand::UPDATE_UPDATER && updateUpdaterUrl_.isEmpty()) {
74-
updateUpdaterUrl_ = latestUpdaterUrl_;
90+
updateUpdaterUrl_ = latestUpdaterUrls_.at(0);
7591
emit updaterUpdateNeeded();
7692
}
7793
}
@@ -131,14 +147,14 @@ void SplashController::autoLaunchOrUpdate()
131147
// If no relaunch action, detect update needed based on versions.json
132148
if (!latestUpdaterVersion_.isEmpty() && latestUpdaterVersion_ != updaterAppVersion()) {
133149
qDebug() << "Updater update to version" << latestUpdaterVersion_ << "required";
134-
QString updaterArgs = "--splashms 1 --internalcommand updateupdater --updaterurl " + latestUpdaterUrl_;
150+
QString updaterArgs = "--splashms 1 --internalcommand updateupdater --updaterurl " + latestUpdaterUrls_.at(0);
135151
// Remember the URL if we are doing updater update
136152
if (!connectUrl_.isEmpty()) {
137153
updaterArgs += " -- " + connectUrl_;
138154
}
139155
switch (Sys::RelaunchElevated(updaterArgs)) {
140156
case Sys::ElevationResult::UNNEEDED:
141-
emit updaterUpdate(latestUpdaterUrl_);
157+
emit updaterUpdate(latestUpdaterUrls_.at(0));
142158
return;
143159
case Sys::ElevationResult::RELAUNCHED:
144160
QCoreApplication::quit();

0 commit comments

Comments
 (0)