mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-23 11:47:57 +00:00
Use static version map for autoupdates.
This commit is contained in:
parent
993cb987a6
commit
48e913bf2c
Telegram/SourceFiles
@ -109,7 +109,6 @@ void Launcher::prepareSettings() {
|
||||
|
||||
switch (cPlatform()) {
|
||||
case dbipWindows:
|
||||
gUpdateURL = QUrl(qsl("http://tdesktop.com/win/tupdates/current"));
|
||||
#ifndef OS_WIN_STORE
|
||||
gPlatformString = qsl("Windows");
|
||||
#else // OS_WIN_STORE
|
||||
@ -117,7 +116,6 @@ void Launcher::prepareSettings() {
|
||||
#endif // OS_WIN_STORE
|
||||
break;
|
||||
case dbipMac:
|
||||
gUpdateURL = QUrl(qsl("http://tdesktop.com/mac/tupdates/current"));
|
||||
#ifndef OS_MAC_STORE
|
||||
gPlatformString = qsl("MacOS");
|
||||
#else // OS_MAC_STORE
|
||||
@ -125,15 +123,12 @@ void Launcher::prepareSettings() {
|
||||
#endif // OS_MAC_STORE
|
||||
break;
|
||||
case dbipMacOld:
|
||||
gUpdateURL = QUrl(qsl("http://tdesktop.com/mac32/tupdates/current"));
|
||||
gPlatformString = qsl("MacOSold");
|
||||
break;
|
||||
case dbipLinux64:
|
||||
gUpdateURL = QUrl(qsl("http://tdesktop.com/linux/tupdates/current"));
|
||||
gPlatformString = qsl("Linux64bit");
|
||||
break;
|
||||
case dbipLinux32:
|
||||
gUpdateURL = QUrl(qsl("http://tdesktop.com/linux32/tupdates/current"));
|
||||
gPlatformString = qsl("Linux32bit");
|
||||
break;
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ namespace Core {
|
||||
namespace {
|
||||
|
||||
constexpr auto kCheckTimeout = TimeMs(10000);
|
||||
constexpr auto kMaxResponseSize = 1024 * 1024;
|
||||
const auto kUpdateUrl = "http://updates.tdesktop.com";
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
using VersionInt = DWORD;
|
||||
@ -97,6 +99,7 @@ public:
|
||||
|
||||
void start(bool forceWait);
|
||||
void stop();
|
||||
void test();
|
||||
|
||||
State state() const;
|
||||
int already() const;
|
||||
@ -119,7 +122,14 @@ private:
|
||||
void gotFailure(QNetworkReply::NetworkError e);
|
||||
void clearSentRequest();
|
||||
void requestTimeout();
|
||||
void startDownloadThread(
|
||||
uint64 availableVersion,
|
||||
bool isAvailableBeta,
|
||||
QString url);
|
||||
bool checkOldResponse(const QByteArray &response);
|
||||
bool checkResponse(const QByteArray &response);
|
||||
|
||||
bool _testing = false;
|
||||
bool _isReady = false;
|
||||
base::Timer _timer;
|
||||
base::Timer _retryTimer;
|
||||
@ -233,21 +243,19 @@ void Updater::gotResponse() {
|
||||
}
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
const auto m = QRegularExpression(qsl("^\\s*(\\d+)\\s*:\\s*([\\x21-\\x7f]+)\\s*$")).match(QString::fromLatin1(_reply->readAll()));
|
||||
if (m.hasMatch()) {
|
||||
uint64 currentVersion = m.captured(1).toULongLong();
|
||||
QString url = m.captured(2);
|
||||
bool betaVersion = false;
|
||||
if (url.startsWith(qstr("beta_"))) {
|
||||
betaVersion = true;
|
||||
url = url.mid(5) + '_' + Core::countBetaVersionSignature(currentVersion);
|
||||
}
|
||||
if ((!betaVersion || cBetaVersion()) && currentVersion > (betaVersion ? cBetaVersion() : uint64(AppVersion))) {
|
||||
_thread = std::make_unique<QThread>();
|
||||
_private = new Private(this, _thread.get(), url);
|
||||
_thread->start();
|
||||
const auto response = _reply->readAll();
|
||||
if (response.size() >= kMaxResponseSize) {
|
||||
LOG(("App Error: Bad update map size: %1").arg(response.size()));
|
||||
gotFailure(QNetworkReply::UnknownContentError);
|
||||
return;
|
||||
}
|
||||
if (!checkOldResponse(response)) {
|
||||
if (!checkResponse(response)) {
|
||||
gotFailure(QNetworkReply::UnknownContentError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
clearSentRequest();
|
||||
if (!_thread) {
|
||||
if (const auto update = FindUpdateFile(); !update.isEmpty()) {
|
||||
@ -269,6 +277,157 @@ void Updater::gotFailure(QNetworkReply::NetworkError e) {
|
||||
start(true);
|
||||
}
|
||||
|
||||
bool Updater::checkOldResponse(const QByteArray &response) {
|
||||
const auto string = QString::fromLatin1(response);
|
||||
const auto old = QRegularExpression(
|
||||
qsl("^\\s*(\\d+)\\s*:\\s*([\\x21-\\x7f]+)\\s*$")
|
||||
).match(string);
|
||||
if (!old.hasMatch()) {
|
||||
return false;
|
||||
}
|
||||
const auto availableVersion = old.captured(1).toULongLong();
|
||||
const auto url = old.captured(2);
|
||||
const auto isAvailableBeta = url.startsWith(qstr("beta_"));
|
||||
startDownloadThread(
|
||||
availableVersion,
|
||||
isAvailableBeta,
|
||||
isAvailableBeta ? url.mid(5) + "_{signature}" : url);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Updater::checkResponse(const QByteArray &response) {
|
||||
auto error = QJsonParseError{ 0, QJsonParseError::NoError };
|
||||
const auto document = QJsonDocument::fromJson(response, &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
LOG(("Update Error: Failed to parse response JSON, error: %1"
|
||||
).arg(error.errorString()));
|
||||
return false;
|
||||
} else if (!document.isObject()) {
|
||||
LOG(("Update Error: Not an object received in response JSON."));
|
||||
return false;
|
||||
}
|
||||
const auto platforms = document.object();
|
||||
const auto platform = [&] {
|
||||
switch (cPlatform()) {
|
||||
case dbipWindows: return "win";
|
||||
case dbipMac: return "mac";
|
||||
case dbipMacOld: return "mac32";
|
||||
case dbipLinux64: return "linux";
|
||||
case dbipLinux32: return "linux32";
|
||||
}
|
||||
Unexpected("Platform in Updater::checkResponse.");
|
||||
}();
|
||||
const auto it = platforms.constFind(platform);
|
||||
if (it == platforms.constEnd()) {
|
||||
LOG(("Update Error: Platform '%1' not found in response."
|
||||
).arg(platform));
|
||||
return false;
|
||||
} else if (!it->isObject()) {
|
||||
LOG(("Update Error: Not an object found for platform '%1'."
|
||||
).arg(platform));
|
||||
return false;
|
||||
}
|
||||
const auto types = it->toObject();
|
||||
const auto list = [&]() -> std::vector<QString> {
|
||||
if (cBetaVersion()) {
|
||||
return { "alpha", "beta", "stable" };
|
||||
} else if (cAlphaVersion()) {
|
||||
return { "beta", "stable" };
|
||||
}
|
||||
return { "stable" };
|
||||
}();
|
||||
auto bestIsAvailableBeta = false;
|
||||
auto bestAvailableVersion = 0ULL;
|
||||
auto bestLink = QString();
|
||||
for (const auto &type : list) {
|
||||
const auto it = types.constFind(type);
|
||||
if (it == types.constEnd()) {
|
||||
continue;
|
||||
} else if (!it->isObject()) {
|
||||
LOG(("Update Error: Not an object found for '%1:%2'."
|
||||
).arg(platform).arg(type));
|
||||
return false;
|
||||
}
|
||||
const auto map = it->toObject();
|
||||
const auto key = _testing ? "testing" : "released";
|
||||
const auto version = map.constFind(key);
|
||||
const auto link = map.constFind("link");
|
||||
if (version == map.constEnd()) {
|
||||
continue;
|
||||
} else if (link == map.constEnd()) {
|
||||
LOG(("Update Error: Link not found for '%1:%2'."
|
||||
).arg(platform).arg(type));
|
||||
return false;
|
||||
} else if (!link->isString()) {
|
||||
LOG(("Update Error: Link is not a string for '%1:%2'."
|
||||
).arg(platform).arg(type));
|
||||
return false;
|
||||
}
|
||||
const auto isAvailableBeta = (type == "alpha");
|
||||
const auto availableVersion = [&] {
|
||||
if (version->isString()) {
|
||||
return version->toString().toULongLong();
|
||||
} else if (version->isDouble()) {
|
||||
return uint64(std::round(version->toDouble()));
|
||||
}
|
||||
return 0ULL;
|
||||
}();
|
||||
if (!availableVersion) {
|
||||
LOG(("Update Error: Version is not valid for '%1:%2:%3'."
|
||||
).arg(platform).arg(type).arg(key));
|
||||
return false;
|
||||
}
|
||||
const auto compare = isAvailableBeta
|
||||
? availableVersion
|
||||
: availableVersion * 1000;
|
||||
const auto bestCompare = bestIsAvailableBeta
|
||||
? bestAvailableVersion
|
||||
: bestAvailableVersion * 1000;
|
||||
if (compare > bestCompare) {
|
||||
bestAvailableVersion = availableVersion;
|
||||
bestIsAvailableBeta = isAvailableBeta;
|
||||
bestLink = link->toString();
|
||||
}
|
||||
}
|
||||
if (!bestAvailableVersion) {
|
||||
LOG(("Update Error: No valid entry found for platform '%1'."
|
||||
).arg(platform));
|
||||
return false;
|
||||
}
|
||||
startDownloadThread(
|
||||
bestAvailableVersion,
|
||||
bestIsAvailableBeta,
|
||||
kUpdateUrl + bestLink);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Updater::startDownloadThread(
|
||||
uint64 availableVersion,
|
||||
bool isAvailableBeta,
|
||||
QString url) {
|
||||
const auto myVersion = isAvailableBeta
|
||||
? cBetaVersion()
|
||||
: uint64(AppVersion);
|
||||
const auto validVersion = (cBetaVersion() || !isAvailableBeta);
|
||||
if (!validVersion || availableVersion <= myVersion) {
|
||||
return;
|
||||
}
|
||||
const auto versionUrl = url.replace(
|
||||
"{version}",
|
||||
QString::number(availableVersion));
|
||||
const auto finalUrl = isAvailableBeta
|
||||
? QString(versionUrl).replace(
|
||||
"{signature}",
|
||||
countBetaVersionSignature(availableVersion))
|
||||
: versionUrl;
|
||||
_thread = std::make_unique<QThread>();
|
||||
_private = new Private(
|
||||
this,
|
||||
_thread.get(),
|
||||
finalUrl);
|
||||
_thread->start();
|
||||
}
|
||||
|
||||
void Updater::handleReady() {
|
||||
_isReady = true;
|
||||
stop();
|
||||
@ -356,17 +515,8 @@ void Updater::start(bool forceWait) {
|
||||
if (sendRequest) {
|
||||
clearSentRequest();
|
||||
|
||||
auto url = QUrl(cUpdateURL());
|
||||
if (cBetaVersion()) {
|
||||
url.setQuery(qsl("version=%1&beta=%2"
|
||||
).arg(AppVersion
|
||||
).arg(cBetaVersion()));
|
||||
} else if (cAlphaVersion()) {
|
||||
url.setQuery(qsl("version=%1&alpha=1").arg(AppVersion));
|
||||
} else {
|
||||
url.setQuery(qsl("version=%1").arg(AppVersion));
|
||||
}
|
||||
DEBUG_LOG(("App Info: requesting update state from '%1'"
|
||||
auto url = QUrl(kUpdateUrl + QString("/current"));
|
||||
DEBUG_LOG(("Update Info: requesting update state from '%1'"
|
||||
).arg(url.toDisplayString()));
|
||||
const auto request = QNetworkRequest(url);
|
||||
_manager = std::make_unique<QNetworkAccessManager>();
|
||||
@ -384,6 +534,12 @@ void Updater::start(bool forceWait) {
|
||||
}
|
||||
}
|
||||
|
||||
void Updater::test() {
|
||||
_testing = true;
|
||||
cSetLastUpdateCheck(0);
|
||||
start(false);
|
||||
}
|
||||
|
||||
void Updater::requestTimeout() {
|
||||
if (_reply) {
|
||||
stop();
|
||||
@ -426,6 +582,10 @@ void UpdateChecker::start(bool forceWait) {
|
||||
_updater->start(forceWait);
|
||||
}
|
||||
|
||||
void UpdateChecker::test() {
|
||||
_updater->test();
|
||||
}
|
||||
|
||||
void UpdateChecker::stop() {
|
||||
_updater->stop();
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
|
||||
void start(bool forceWait = false);
|
||||
void stop();
|
||||
void test();
|
||||
|
||||
State state() const;
|
||||
int already() const;
|
||||
|
@ -397,7 +397,7 @@ bool CheckBetaVersionDir() {
|
||||
QByteArray k;
|
||||
dataStream >> v >> k;
|
||||
if (dataStream.status() == QDataStream::Ok && !k.isEmpty()) {
|
||||
cSetBetaVersion(qMax(v, AppVersion * 1000ULL));
|
||||
cSetBetaVersion(AppVersion * 1000ULL);
|
||||
cSetBetaPrivateKey(k);
|
||||
cSetRealBetaVersion(v);
|
||||
} else {
|
||||
|
@ -87,7 +87,6 @@ DBIPlatform gPlatform = dbipLinux32;
|
||||
#error Unknown platform
|
||||
#endif
|
||||
QString gPlatformString;
|
||||
QUrl gUpdateURL;
|
||||
bool gIsElCapitan = false;
|
||||
bool gIsSnowLeopard = false;
|
||||
|
||||
|
@ -194,7 +194,6 @@ DeclareReadSetting(DBIPlatform, Platform);
|
||||
DeclareReadSetting(QString, PlatformString);
|
||||
DeclareReadSetting(bool, IsElCapitan);
|
||||
DeclareReadSetting(bool, IsSnowLeopard);
|
||||
DeclareReadSetting(QUrl, UpdateURL);
|
||||
|
||||
DeclareSetting(int, OtherOnline);
|
||||
|
||||
|
@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mtproto/mtp_instance.h"
|
||||
#include "mtproto/dc_options.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "core/update_checker.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "window/themes/window_theme_editor.h"
|
||||
#include "media/media_audio_track.h"
|
||||
@ -47,6 +48,9 @@ void fillCodes() {
|
||||
Messenger::Instance().onSwitchTestMode();
|
||||
}));
|
||||
});
|
||||
Codes.insert(qsl("testupdate"), [] {
|
||||
Core::UpdateChecker().test();
|
||||
});
|
||||
Codes.insert(qsl("loadlang"), [] {
|
||||
Lang::CurrentCloudManager().switchToLanguage(qsl("custom"));
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user