Skip to content

Commit de3af4a

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

File tree

8 files changed

+112
-44
lines changed

8 files changed

+112
-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: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,17 @@ 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+
setState(COMPLETED);
129+
setDownloadSpeed(0);
130+
setUploadSpeed(0);
131+
setCompletedSize(0);
132+
stopAria();
133+
if (!(this->*downloadRestarter_)()) {
134+
emit fatalMessage("Error received while downloading");
135+
}
126136
break;
127137

128138
case aria2::EVENT_ON_DOWNLOAD_PAUSE:
@@ -143,7 +153,7 @@ void QmlDownloader::onDownloadEvent(int event)
143153
}
144154
}
145155

146-
void QmlDownloader::startUpdate(const QString& selectedInstallPath)
156+
void QmlDownloader::setInstallPath(const QString& selectedInstallPath)
147157
{
148158
qDebug() << "Selected install path:" << selectedInstallPath;
149159
if (!Sys::validateInstallPath(selectedInstallPath)) {
@@ -159,26 +169,38 @@ void QmlDownloader::startUpdate(const QString& selectedInstallPath)
159169
return;
160170
}
161171
}
172+
162173
if (!QFileInfo(selectedInstallPath).isWritable()) {
163174
emit fatalMessage("Install dir not writable. Please select another");
164175
return;
165176
}
166177

167-
QString gameUrl = splashController_.gameUrl();
168-
qDebug() << "Using torrent file:" << gameUrl;
169178
// Persist the install path only now that download has been initiated and we know the path is good
170179
emit statusMessage("Installing to " + dir.canonicalPath());
171180
if (settings_.installPath() != selectedInstallPath) {
172181
qDebug() << "Clearing installed version because path was changed";
173182
settings_.setInstalledVersion("");
174183
}
175184
settings_.setInstallPath(selectedInstallPath);
185+
}
186+
187+
bool QmlDownloader::startUpdate()
188+
{
189+
QString gameUrl = splashController_.gameUrl();
190+
if (gameUrl.isEmpty()) {
191+
return false;
192+
}
193+
194+
qDebug() << "Using torrent URL:" << gameUrl;
195+
196+
QDir dir(settings_.installPath());
176197

177198
setState(DOWNLOADING);
178199
worker_ = new DownloadWorker(ariaLogFilename_);
179200
worker_->setDownloadDirectory(dir.canonicalPath().toStdString());
180201
worker_->addTorrent(gameUrl.toStdString());
181202
worker_->moveToThread(&thread_);
203+
setDownloadRestarter(&QmlDownloader::startUpdate);
182204
connect(&thread_, SIGNAL(finished()), worker_, SLOT(deleteLater()));
183205
connect(worker_, SIGNAL(onDownloadEvent(int)), this, SLOT(onDownloadEvent(int)));
184206
connect(worker_, SIGNAL(downloadSpeedChanged(int)), this, SLOT(setDownloadSpeed(int)));
@@ -187,14 +209,17 @@ void QmlDownloader::startUpdate(const QString& selectedInstallPath)
187209
connect(worker_, SIGNAL(completedSizeChanged(int)), this, SLOT(setCompletedSize(int)));
188210
connect(&thread_, SIGNAL(started()), worker_, SLOT(download()));
189211
thread_.start();
212+
213+
return true;
190214
}
191215

192216
void QmlDownloader::toggleDownload(QString installPath)
193217
{
194218
qDebug() << "QmlDownloader::toggleDownload called";
195219
if (state() == COMPLETED) return;
196220
if (!worker_) {
197-
startUpdate(installPath);
221+
setInstallPath(installPath);
222+
startUpdate();
198223
return;
199224
}
200225
QMetaObject::invokeMethod(worker_, "toggle");
@@ -212,14 +237,22 @@ void QmlDownloader::stopAria()
212237
}
213238
}
214239

215-
void QmlDownloader::startUpdaterUpdate(QString updaterUrl)
240+
bool QmlDownloader::startUpdaterUpdate()
216241
{
242+
QString updaterUrl = splashController_.updaterUrl();
243+
if (updaterUrl.isEmpty()) {
244+
return false;
245+
}
246+
247+
qDebug() << "Using updater URL:" << updaterUrl;
248+
217249
temp_dir_.reset(new QTemporaryDir());
218250
worker_ = new DownloadWorker(ariaLogFilename_);
219251
worker_->setDownloadDirectory(QDir(temp_dir_->path()).canonicalPath().toStdString());
220252
worker_->setConnectUrl(connectUrl_);
221253
worker_->addUpdaterUri(updaterUrl.toStdString());
222254
worker_->moveToThread(&thread_);
255+
setDownloadRestarter(&QmlDownloader::startUpdaterUpdate);
223256
connect(&thread_, SIGNAL(finished()), worker_, SLOT(deleteLater()));
224257
connect(worker_, SIGNAL(onDownloadEvent(int)), this, SLOT(onDownloadEvent(int)));
225258
connect(worker_, SIGNAL(downloadSpeedChanged(int)), this, SLOT(setDownloadSpeed(int)));
@@ -228,6 +261,8 @@ void QmlDownloader::startUpdaterUpdate(QString updaterUrl)
228261
connect(worker_, SIGNAL(completedSizeChanged(int)), this, SLOT(setCompletedSize(int)));
229262
connect(&thread_, SIGNAL(started()), worker_, SLOT(download()));
230263
thread_.start();
264+
265+
return true;
231266
}
232267

233268
QmlDownloader::DownloadState QmlDownloader::state() const
@@ -240,3 +275,8 @@ void QmlDownloader::setState(DownloadState state)
240275
state_ = state;
241276
emit stateChanged(state);
242277
}
278+
279+
void QmlDownloader::setDownloadRestarter(DownloadRestarter downloadRestarter)
280+
{
281+
downloadRestarter_ = downloadRestarter;
282+
}

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 (latestGameUrls_.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)