prepared 0.5.13 - greatly improved network support (bad_msg_notification handle, connecting notification, dc full config embed, getting config each launch, dc option notify handle, enum dc for new config

This commit is contained in:
John Preston 2014-08-01 22:49:43 +04:00
parent 0e031f042d
commit 5ce2e2b219
25 changed files with 266 additions and 76 deletions

View File

@ -1,5 +1,5 @@
AppVersionStr=0.5.12 AppVersionStr=0.5.13
AppVersion=5012 AppVersion=5013
if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then
echo "Deploy folder for version $AppVersionStr already exists!" echo "Deploy folder for version $AppVersionStr already exists!"

View File

@ -1,5 +1,5 @@
AppVersionStr=0.5.12 AppVersionStr=0.5.13
AppVersion=5012 AppVersion=5013
if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then
echo "Deploy folder for version $AppVersionStr already exists!" echo "Deploy folder for version $AppVersionStr already exists!"

View File

@ -1,5 +1,5 @@
AppVersionStr=0.5.12 AppVersionStr=0.5.13
AppVersion=5012 AppVersion=5013
if [ -d "./../Mac/Release/deploy/$AppVersionStr" ]; then if [ -d "./../Mac/Release/deploy/$AppVersionStr" ]; then
echo "Deploy folder for version $AppVersionStr already exists!" echo "Deploy folder for version $AppVersionStr already exists!"

View File

@ -3,9 +3,9 @@
#define MyAppShortName "Telegram" #define MyAppShortName "Telegram"
#define MyAppName "Telegram Win (Unofficial)" #define MyAppName "Telegram Win (Unofficial)"
#define MyAppVersion "0.5.12" #define MyAppVersion "0.5.13"
#define MyAppVersionZero "0.5.12" #define MyAppVersionZero "0.5.13"
#define MyAppFullVersion "0.5.12.0" #define MyAppFullVersion "0.5.13.0"
#define MyAppPublisher "Telegram (Unofficial)" #define MyAppPublisher "Telegram (Unofficial)"
#define MyAppURL "https://tdesktop.com" #define MyAppURL "https://tdesktop.com"
#define MyAppExeName "Telegram.exe" #define MyAppExeName "Telegram.exe"

View File

@ -39,6 +39,12 @@ namespace {
} }
} }
void mtpSessionReset(int32 dc) {
if (App::main() && dc == MTP::maindc()) {
App::main()->getDifference();
}
}
class _DebugWaiter : public QObject { class _DebugWaiter : public QObject {
public: public:
@ -569,6 +575,7 @@ void Application::startApp() {
MTP::start(); MTP::start();
MTP::setStateChangedHandler(mtpStateChanged); MTP::setStateChangedHandler(mtpStateChanged);
MTP::setSessionResetHandler(mtpSessionReset);
App::initMedia(); App::initMedia();

View File

@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
*/ */
#pragma once #pragma once
static const int32 AppVersion = 5012; static const int32 AppVersion = 5013;
static const wchar_t *AppVersionStr = L"0.5.12"; static const wchar_t *AppVersionStr = L"0.5.13";
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
static const wchar_t *AppName = L"Telegram Win (Unofficial)"; static const wchar_t *AppName = L"Telegram Win (Unofficial)";
#else #else
@ -42,6 +42,8 @@ enum {
MTPTcpConnectionWaitTimeout = 3000, // 3 seconds waiting for tcp, until we accept http MTPTcpConnectionWaitTimeout = 3000, // 3 seconds waiting for tcp, until we accept http
MTPMillerRabinIterCount = 30, // 30 Miller-Rabin iterations for dh_prime primality check MTPMillerRabinIterCount = 30, // 30 Miller-Rabin iterations for dh_prime primality check
MTPEnumDCTimeout = 4000, // 4 seconds timeout for help_getConfig to work (them move to other dc)
MinReceiveDelay = 1000, // 1 seconds MinReceiveDelay = 1000, // 1 seconds
MaxSelectedItems = 100, MaxSelectedItems = 100,
@ -94,12 +96,30 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB\n\
return keys; return keys;
} }
inline const char *cFirstDCIp() { struct BuiltInDc {
return cTestMode() ? "173.240.5.253" : "173.240.5.1"; int id;
const char *ip;
int port;
};
static const BuiltInDc _builtInDcs[] = {
{ 1, "173.240.5.1", 443 },
{ 2, "149.154.167.50", 443 },
{ 3, "174.140.142.6", 443 },
{ 4, "149.154.167.90", 443 },
{ 5, "116.51.22.2", 443 }
};
static const BuiltInDc _builtInTestDcs[] = {
{ 1, "173.240.5.253", 443 }
};
inline const BuiltInDc *builtInDcs() {
return cTestMode() ? _builtInTestDcs : _builtInDcs;
} }
inline int32 cFirstDCPort() { inline int builtInDcsCount() {
return 443; return (cTestMode() ? sizeof(_builtInTestDcs) : sizeof(_builtInDcs)) / sizeof(BuiltInDc);
} }
static const char *UpdatesPublicKey = "\ static const char *UpdatesPublicKey = "\

View File

@ -906,7 +906,6 @@ DialogsListWidget::SearchResults &DialogsListWidget::searchList() {
} }
DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent) DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent)
, _configLoaded(false)
, _drawShadow(true) , _drawShadow(true)
, dlgOffset(0) , dlgOffset(0)
, dlgCount(-1) , dlgCount(-1)
@ -1070,7 +1069,6 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs) {
} }
} else { } else {
dlgCount = dlgOffset; dlgCount = dlgOffset;
loadConfig();
} }
dlgPreloading = 0; dlgPreloading = 0;
@ -1137,19 +1135,9 @@ void DialogsWidget::onSearchMore(MsgId minMsgId) {
} }
} }
void DialogsWidget::loadConfig() {
if (!_configLoaded) {
mtpConfigLoader()->load();
_configLoaded = true;
}
}
void DialogsWidget::loadDialogs() { void DialogsWidget::loadDialogs() {
if (dlgPreloading) return; if (dlgPreloading) return;
if (dlgCount >= 0 && dlgOffset >= dlgCount) { if (dlgCount >= 0 && dlgOffset >= dlgCount) return;
loadConfig();
return;
}
int32 loadCount = dlgOffset ? DialogsPerPage : DialogsFirstLoad; int32 loadCount = dlgOffset ? DialogsPerPage : DialogsFirstLoad;
dlgPreloading = MTP::send(MTPmessages_GetDialogs(MTP_int(dlgOffset), MTP_int(0), MTP_int(loadCount)), rpcDone(&DialogsWidget::dialogsReceived), rpcFail(&DialogsWidget::dialogsFailed)); dlgPreloading = MTP::send(MTPmessages_GetDialogs(MTP_int(dlgOffset), MTP_int(0), MTP_int(loadCount)), rpcDone(&DialogsWidget::dialogsReceived), rpcFail(&DialogsWidget::dialogsFailed));

View File

@ -195,9 +195,6 @@ public slots:
private: private:
void loadConfig();
bool _configLoaded;
bool _drawShadow; bool _drawShadow;
void unreadCountsReceived(const QVector<MTPDialog> &dialogs); void unreadCountsReceived(const QVector<MTPDialog> &dialogs);

View File

@ -66,9 +66,9 @@ void BoxShadow::paint(QPainter &p, const QRect &box, const QPoint &shift, int32
if (left && bottom) p.drawPixmap(box.left() - _size + minus + shift.x(), box.bottom() - minus + 1 + shift.y(), _corners, 0, _size, _size, _size); if (left && bottom) p.drawPixmap(box.left() - _size + minus + shift.x(), box.bottom() - minus + 1 + shift.y(), _corners, 0, _size, _size, _size);
for (int32 i = 1; i <= count; ++i) { for (int32 i = 1; i <= count; ++i) {
p.setPen(_colors[i - 1]->p); p.setPen(_colors[i - 1]->p);
if (top) p.fillRect(box.left() + (left ? minus : 0) + shift.x(), box.top() - count + i + shift.y(), box.width() - (right ? minus : 0) - (left ? minus : 0), st::lineWidth, _colors[i - 1]->b); if (top) p.fillRect(box.left() + (left ? minus : 0) + shift.x(), box.top() - count + i + shift.y(), box.width() - (right ? minus : 0) - (left ? minus : 0), cIntRetinaFactor(), _colors[i - 1]->b);
if (right) p.fillRect(box.right() + count - i + shift.x(), box.top() + (top ? minus : 0) + shift.y(), st::lineWidth, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _colors[i - 1]->b); if (right) p.fillRect(box.right() + count - i + shift.x(), box.top() + (top ? minus : 0) + shift.y(), cIntRetinaFactor(), box.height() - (bottom ? minus : 0) - (top ? minus : 0), _colors[i - 1]->b);
if (bottom) p.fillRect(box.left() + (left ? minus : 0) + shift.x(), box.bottom() + count - i + shift.y(), box.width() - (right ? minus : 0) - (left ? minus : 0), st::lineWidth, _colors[i - 1]->b); if (bottom) p.fillRect(box.left() + (left ? minus : 0) + shift.x(), box.bottom() + count - i + shift.y(), box.width() - (right ? minus : 0) - (left ? minus : 0), cIntRetinaFactor(), _colors[i - 1]->b);
if (left) p.fillRect(box.left() - count + i + shift.x(), box.top() + (top ? minus : 0) + shift.y(), st::lineWidth, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _colors[i - 1]->b); if (left) p.fillRect(box.left() - count + i + shift.x(), box.top() + (top ? minus : 0) + shift.y(), cIntRetinaFactor(), box.height() - (bottom ? minus : 0) - (top ? minus : 0), _colors[i - 1]->b);
} }
} }

View File

@ -1734,5 +1734,10 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
const MTPDupdateNotifySettings &d(update.c_updateNotifySettings()); const MTPDupdateNotifySettings &d(update.c_updateNotifySettings());
applyNotifySetting(d.vpeer, d.vnotify_settings); applyNotifySetting(d.vpeer, d.vnotify_settings);
} break; } break;
case mtpc_updateDcOptions: {
const MTPDupdateDcOptions &d(update.c_updateDcOptions());
MTP::updateDcOptions(d.vdc_options.c_vector().v);
} break;
} }
} }

View File

@ -53,6 +53,7 @@ namespace {
RPCResponseHandler globalHandler; RPCResponseHandler globalHandler;
MTPStateChangedHandler stateChangedHandler = 0; MTPStateChangedHandler stateChangedHandler = 0;
MTPSessionResetHandler sessionResetHandler = 0;
_mtp_internal::RequestResender *resender = 0; _mtp_internal::RequestResender *resender = 0;
mtpAuthKey _localKey; mtpAuthKey _localKey;
@ -342,6 +343,9 @@ namespace _mtp_internal {
void execCallback(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) { void execCallback(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) {
ParserMap::iterator i = parserMap.find(requestId); ParserMap::iterator i = parserMap.find(requestId);
if (i != parserMap.cend()) { if (i != parserMap.cend()) {
RPCResponseHandler h(i.value());
parserMap.erase(i);
DEBUG_LOG(("RPC Info: found parser for request %1, trying to parse response..").arg(requestId)); DEBUG_LOG(("RPC Info: found parser for request %1, trying to parse response..").arg(requestId));
try { try {
if (from >= end) throw mtpErrorInsufficient(); if (from >= end) throw mtpErrorInsufficient();
@ -349,18 +353,17 @@ namespace _mtp_internal {
if (*from == mtpc_rpc_error) { if (*from == mtpc_rpc_error) {
RPCError err(MTPRpcError(from, end)); RPCError err(MTPRpcError(from, end));
DEBUG_LOG(("RPC Info: error received, code %1, type %2, description: %3").arg(err.code()).arg(err.type()).arg(err.description())); DEBUG_LOG(("RPC Info: error received, code %1, type %2, description: %3").arg(err.code()).arg(err.type()).arg(err.description()));
if (!rpcErrorOccured(requestId, i.value(), err)) { if (!rpcErrorOccured(requestId, h, err)) {
return; return;
} }
} else { } else {
if (i.value().onDone) (*i.value().onDone)(requestId, from, end); if (h.onDone) (*h.onDone)(requestId, from, end);
} }
} catch (Exception &e) { } catch (Exception &e) {
if (!rpcErrorOccured(requestId, i.value(), rpcClientError("RESPONSE_PARSE_FAILED", QString("exception text: ") + e.what()))) { if (!rpcErrorOccured(requestId, h, rpcClientError("RESPONSE_PARSE_FAILED", QString("exception text: ") + e.what()))) {
return; return;
} }
} }
parserMap.erase(i);
requestMap.remove(requestId); requestMap.remove(requestId);
} else { } else {
DEBUG_LOG(("RPC Info: parser not found for %1").arg(requestId)); DEBUG_LOG(("RPC Info: parser not found for %1").arg(requestId));
@ -376,6 +379,10 @@ namespace _mtp_internal {
if (stateChangedHandler) stateChangedHandler(dc, state); if (stateChangedHandler) stateChangedHandler(dc, state);
} }
void onSessionReset(int32 dc) {
if (sessionResetHandler) sessionResetHandler(dc);
}
bool rpcErrorOccured(mtpRequestId requestId, const RPCFailHandlerPtr &onFail, const RPCError &err) { // return true if need to clean request data bool rpcErrorOccured(mtpRequestId requestId, const RPCFailHandlerPtr &onFail, const RPCError &err) { // return true if need to clean request data
if (onErrorDefault(requestId, err)) { if (onErrorDefault(requestId, err)) {
return false; return false;
@ -469,6 +476,15 @@ namespace MTP {
(*i)->restart(); (*i)->restart();
} }
} }
void restart(int32 dcMask) {
if (!started) return;
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
if ((*i)->getDC() % _mtp_internal::dcShift == dcMask % _mtp_internal::dcShift) {
(*i)->restart();
}
}
}
void setLayer(uint32 l) { void setLayer(uint32 l) {
if (l > mtpLayerMax) { if (l > mtpLayerMax) {
@ -538,6 +554,14 @@ namespace MTP {
_mtp_internal::clearCallbacks(requestId); _mtp_internal::clearCallbacks(requestId);
} }
void killSession(int32 dc) {
Sessions::iterator i = sessions.find(dc);
if (i != sessions.end()) {
i.value()->stop();
sessions.erase(i);
}
}
int32 state(mtpRequestId requestId) { int32 state(mtpRequestId requestId) {
if (requestId > 0) { if (requestId > 0) {
QMutexLocker locker(&requestByDCLock); QMutexLocker locker(&requestByDCLock);
@ -556,6 +580,7 @@ namespace MTP {
} }
delete resender; delete resender;
resender = 0; resender = 0;
mtpDestroyConfigLoader();
} }
void authed(int32 uid) { void authed(int32 uid) {
@ -583,10 +608,20 @@ namespace MTP {
stateChangedHandler = handler; stateChangedHandler = handler;
} }
void setSessionResetHandler(MTPSessionResetHandler handler) {
sessionResetHandler = handler;
}
void clearGlobalHandlers() { void clearGlobalHandlers() {
setGlobalDoneHandler(RPCDoneHandlerPtr()); setGlobalDoneHandler(RPCDoneHandlerPtr());
setGlobalFailHandler(RPCFailHandlerPtr()); setGlobalFailHandler(RPCFailHandlerPtr());
setStateChangedHandler(0); setStateChangedHandler(0);
setSessionResetHandler(0);
}
void updateDcOptions(const QVector<MTPDcOption> &options) {
mtpUpdateDcOptions(options);
App::writeUserConfig();
} }
void writeConfig(QDataStream &stream) { void writeConfig(QDataStream &stream) {

View File

@ -38,6 +38,7 @@ namespace _mtp_internal {
void execCallback(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end); void execCallback(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end);
void globalCallback(const mtpPrime *from, const mtpPrime *end); void globalCallback(const mtpPrime *from, const mtpPrime *end);
void onStateChange(int32 dc, int32 state); void onStateChange(int32 dc, int32 state);
void onSessionReset(int32 dc);
bool rpcErrorOccured(mtpRequestId requestId, const RPCFailHandlerPtr &onFail, const RPCError &err); // return true if need to clean request data bool rpcErrorOccured(mtpRequestId requestId, const RPCFailHandlerPtr &onFail, const RPCError &err); // return true if need to clean request data
inline bool rpcErrorOccured(mtpRequestId requestId, const RPCResponseHandler &handler, const RPCError &err) { inline bool rpcErrorOccured(mtpRequestId requestId, const RPCResponseHandler &handler, const RPCError &err) {
return rpcErrorOccured(requestId, handler.onFail, err); return rpcErrorOccured(requestId, handler.onFail, err);
@ -59,9 +60,11 @@ namespace MTP {
static const uint32 dld = 1 * _mtp_internal::dcShift; // send(req, callbacks, MTP::dld + dc) - for download static const uint32 dld = 1 * _mtp_internal::dcShift; // send(req, callbacks, MTP::dld + dc) - for download
static const uint32 upl = 2 * _mtp_internal::dcShift; // send(req, callbacks, MTP::upl + dc) - for upload static const uint32 upl = 2 * _mtp_internal::dcShift; // send(req, callbacks, MTP::upl + dc) - for upload
static const uint32 cfg = 3 * _mtp_internal::dcShift; // send(MTPhelp_GetConfig(), MTP::cfg + dc) - for dc enum
void start(); void start();
void restart(); void restart();
void restart(int32 dcMask);
void setLayer(uint32 layer); void setLayer(uint32 layer);
@ -79,6 +82,7 @@ namespace MTP {
return send(request, RPCResponseHandler(onDone, onFail), dc, msCanWait); return send(request, RPCResponseHandler(onDone, onFail), dc, msCanWait);
} }
void cancel(mtpRequestId req); void cancel(mtpRequestId req);
void killSession(int32 dc);
enum { enum {
RequestSent = 0, RequestSent = 0,
@ -98,8 +102,11 @@ namespace MTP {
void setGlobalDoneHandler(RPCDoneHandlerPtr handler); void setGlobalDoneHandler(RPCDoneHandlerPtr handler);
void setGlobalFailHandler(RPCFailHandlerPtr handler); void setGlobalFailHandler(RPCFailHandlerPtr handler);
void setStateChangedHandler(MTPStateChangedHandler handler); void setStateChangedHandler(MTPStateChangedHandler handler);
void setSessionResetHandler(MTPSessionResetHandler handler);
void clearGlobalHandlers(); void clearGlobalHandlers();
void updateDcOptions(const QVector<MTPDcOption> &options);
template <typename T> template <typename T>
T nonce() { T nonce() {
T result; T result;

View File

@ -1086,6 +1086,7 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne
connect(this, SIGNAL(needToReceive()), sessionData->owner(), SLOT(tryToReceive())); connect(this, SIGNAL(needToReceive()), sessionData->owner(), SLOT(tryToReceive()));
connect(this, SIGNAL(stateChanged(qint32)), sessionData->owner(), SLOT(onConnectionStateChange(qint32))); connect(this, SIGNAL(stateChanged(qint32)), sessionData->owner(), SLOT(onConnectionStateChange(qint32)));
connect(sessionData->owner(), SIGNAL(needToSend()), this, SLOT(tryToSend())); connect(sessionData->owner(), SIGNAL(needToSend()), this, SLOT(tryToSend()));
connect(this, SIGNAL(sessionResetDone()), sessionData->owner(), SLOT(onResetDone()));
oldConnectionTimer.setSingleShot(true); oldConnectionTimer.setSingleShot(true);
connCheckTimer.setSingleShot(true); connCheckTimer.setSingleShot(true);
@ -1247,6 +1248,8 @@ void MTProtoConnectionPrivate::resetSession() { // recreate all msg_id and msg_s
} }
} }
} }
emit sessionResetDone();
} }
mtpMsgId MTProtoConnectionPrivate::prepareToSend(mtpRequest &request, mtpMsgId currentLastId) { mtpMsgId MTProtoConnectionPrivate::prepareToSend(mtpRequest &request, mtpMsgId currentLastId) {

View File

@ -292,6 +292,7 @@ signals:
void needToReceive(); void needToReceive();
void needToRestart(); void needToRestart();
void stateChanged(qint32 newState); void stateChanged(qint32 newState);
void sessionResetDone();
public slots: public slots:

View File

@ -23,7 +23,7 @@ namespace {
MTProtoDCMap gDCs; MTProtoDCMap gDCs;
bool configLoadedOnce = false; bool configLoadedOnce = false;
int32 mainDC = 1; int32 mainDC = 2;
int userId = 0; int userId = 0;
mtpDcOptions gDCOptions; mtpDcOptions gDCOptions;
@ -201,13 +201,15 @@ namespace {
int32 oldFound = readAuthKeys(keysFile); int32 oldFound = readAuthKeys(keysFile);
if (gDCOptions.isEmpty() || (mainDC && gDCOptions.find(mainDC) == gDCOptions.cend())) { // load first dc info if (gDCOptions.isEmpty() || (mainDC && gDCOptions.find(mainDC) == gDCOptions.cend())) { // load first dc info
gDCOptions.insert(1, mtpDcOption(1, "", cFirstDCIp(), cFirstDCPort())); const BuiltInDc *bdcs = builtInDcs();
for (int i = 0, l = builtInDcsCount(); i < l; ++i) {
gDCOptions.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, "", bdcs[i].ip, bdcs[i].port));
DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port));
}
userId = 0; userId = 0;
mainDC = 0; mainDC = (gDCOptions.constFind(2) == gDCOptions.cend()) ? gDCOptions.begin().key() : 2;
DEBUG_LOG(("MTP Info: first DC connect options: %1:%2").arg(cFirstDCIp()).arg(cFirstDCPort()));
} else { } else {
configLoadedOnce = true; DEBUG_LOG(("MTP Info: config from local, dc option count: %1").arg(gDCOptions.size()));
DEBUG_LOG(("MTP Info: config loaded, dc option count: %1").arg(gDCOptions.size()));
} }
if (oldFound > 0) { if (oldFound > 0) {
@ -219,8 +221,11 @@ namespace {
} }
} else { } else {
DEBUG_LOG(("MTP Info: could not open keys file for reading")); DEBUG_LOG(("MTP Info: could not open keys file for reading"));
gDCOptions.insert(1, mtpDcOption(1, "", cFirstDCIp(), cFirstDCPort())); const BuiltInDc *bdcs = builtInDcs();
DEBUG_LOG(("MTP Info: first DC connect options: %1:%2").arg(cFirstDCIp()).arg(cFirstDCPort())); for (int i = 0, l = builtInDcsCount(); i < l; ++i) {
gDCOptions.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, "", bdcs[i].ip, bdcs[i].port));
DEBUG_LOG(("MTP Info: adding built in DC %1 connect option: %2:%3").arg(bdcs[i].id).arg(bdcs[i].ip).arg(bdcs[i].port));
}
} }
} }
@ -392,7 +397,7 @@ void MTProtoDC::destroyKey() {
} }
namespace { namespace {
MTProtoConfigLoader configLoader; MTProtoConfigLoader *configLoader = 0;
bool loadingConfig = false; bool loadingConfig = false;
void configLoaded(const MTPConfig &result) { void configLoaded(const MTPConfig &result) {
loadingConfig = false; loadingConfig = false;
@ -401,21 +406,13 @@ namespace {
DEBUG_LOG(("MTP Info: got config, chat_size_max: %1, date: %2, test_mode: %3, this_dc: %4, dc_options.length: %5").arg(data.vchat_size_max.v).arg(data.vdate.v).arg(data.vtest_mode.v).arg(data.vthis_dc.v).arg(data.vdc_options.c_vector().v.size())); DEBUG_LOG(("MTP Info: got config, chat_size_max: %1, date: %2, test_mode: %3, this_dc: %4, dc_options.length: %5").arg(data.vchat_size_max.v).arg(data.vdate.v).arg(data.vtest_mode.v).arg(data.vthis_dc.v).arg(data.vdc_options.c_vector().v.size()));
QSet<int32> already; mtpUpdateDcOptions(data.vdc_options.c_vector().v);
const QVector<MTPDcOption> &options(data.vdc_options.c_vector().v);
for (QVector<MTPDcOption>::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) {
const MTPDdcOption &optData(i->c_dcOption());
if (already.constFind(optData.vid.v) == already.cend()) {
already.insert(optData.vid.v);
gDCOptions.insert(optData.vid.v, mtpDcOption(optData.vid.v, optData.vhostname.c_string().v, optData.vip_address.c_string().v, optData.vport.v));
}
}
cSetMaxGroupCount(data.vchat_size_max.v); cSetMaxGroupCount(data.vchat_size_max.v);
configLoadedOnce = true; configLoadedOnce = true;
App::writeUserConfig(); App::writeUserConfig();
emit mtpConfigLoader()->loaded(); mtpConfigLoader()->done();
} }
bool configFailed(const RPCError &err) { bool configFailed(const RPCError &err) {
loadingConfig = false; loadingConfig = false;
@ -424,16 +421,77 @@ namespace {
} }
}; };
void mtpUpdateDcOptions(const QVector<MTPDcOption> &options) {
QSet<int32> already, restart;
for (QVector<MTPDcOption>::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) {
const MTPDdcOption &optData(i->c_dcOption());
if (already.constFind(optData.vid.v) == already.cend()) {
already.insert(optData.vid.v);
mtpDcOptions::const_iterator a = gDCOptions.constFind(optData.vid.v);
if (a != gDCOptions.cend()) {
if (a.value().ip != optData.vip_address.c_string().v || a.value().port != optData.vport.v) {
restart.insert(optData.vid.v);
}
}
gDCOptions.insert(optData.vid.v, mtpDcOption(optData.vid.v, optData.vhostname.c_string().v, optData.vip_address.c_string().v, optData.vport.v));
}
}
for (QSet<int32>::const_iterator i = restart.cbegin(), e = restart.cend(); i != e; ++i) {
MTP::restart(*i);
}
}
MTProtoConfigLoader::MTProtoConfigLoader() : _enumCurrent(0), _enumRequest(0) {
connect(&_enumDCTimer, SIGNAL(timeout()), this, SLOT(enumDC()));
_enumDCTimer.setSingleShot(true);
}
void MTProtoConfigLoader::load() { void MTProtoConfigLoader::load() {
if (loadingConfig) return; if (loadingConfig) return;
loadingConfig = true; loadingConfig = true;
MTPhelp_GetConfig request; MTP::send(MTPhelp_GetConfig(), rpcDone(configLoaded), rpcFail(configFailed));
MTP::send(request, rpcDone(configLoaded), rpcFail(configFailed));
_enumDCTimer.start(MTPEnumDCTimeout);
}
void MTProtoConfigLoader::done() {
_enumDCTimer.stop();
if (_enumRequest) MTP::cancel(_enumRequest);
if (_enumCurrent) MTP::killSession(_enumCurrent);
emit loaded();
}
void MTProtoConfigLoader::enumDC() {
if (!loadingConfig) return;
if (_enumRequest) MTP::cancel(_enumRequest);
if (!_enumCurrent) {
_enumCurrent = mainDC;
} else {
MTP::killSession(MTP::cfg + _enumCurrent);
}
for (mtpDcOptions::const_iterator i = gDCOptions.cbegin(), e = gDCOptions.cend(); i != e; ++i) {
if (i.key() == _enumCurrent) {
_enumCurrent = (++i == e) ? gDCOptions.cbegin().key() : i.key();
break;
}
}
_enumRequest = MTP::send(MTPhelp_GetConfig(), rpcDone(configLoaded), rpcFail(configFailed), MTP::cfg + _enumCurrent);
_enumDCTimer.start(MTPEnumDCTimeout);
} }
MTProtoConfigLoader *mtpConfigLoader() { MTProtoConfigLoader *mtpConfigLoader() {
return &configLoader; if (!configLoader) configLoader = new MTProtoConfigLoader();
return configLoader;
}
void mtpDestroyConfigLoader() {
delete configLoader;
configLoader = 0;
} }
void mtpWriteConfig(QDataStream &stream) { void mtpWriteConfig(QDataStream &stream) {

View File

@ -83,15 +83,28 @@ class MTProtoConfigLoader : public QObject {
public: public:
MTProtoConfigLoader();
void load(); void load();
void done();
public slots:
void enumDC();
signals: signals:
void loaded(); void loaded();
private:
QTimer _enumDCTimer;
int32 _enumCurrent;
mtpRequestId _enumRequest;
}; };
MTProtoConfigLoader *mtpConfigLoader(); MTProtoConfigLoader *mtpConfigLoader();
void mtpDestroyConfigLoader();
const mtpDcOptions &mtpDCOptions(); const mtpDcOptions &mtpDCOptions();
MTProtoDCMap &mtpDCMap(); MTProtoDCMap &mtpDCMap();
@ -108,3 +121,5 @@ void mtpAuthed(int32 uid);
void mtpWriteConfig(QDataStream &stream); void mtpWriteConfig(QDataStream &stream);
bool mtpReadConfigElem(int32 blockId, QDataStream &stream); bool mtpReadConfigElem(int32 blockId, QDataStream &stream);
void mtpUpdateDcOptions(const QVector<MTPDcOption> &options);

View File

@ -797,3 +797,4 @@ public:
}; };
typedef void (*MTPStateChangedHandler)(int32 dcId, int32 state); typedef void (*MTPStateChangedHandler)(int32 dcId, int32 state);
typedef void(*MTPSessionResetHandler)(int32 dcId);

View File

@ -197,6 +197,10 @@ void MTProtoSession::onConnectionStateChange(qint32 newState) {
_mtp_internal::onStateChange(dcId, newState); _mtp_internal::onStateChange(dcId, newState);
} }
void MTProtoSession::onResetDone() {
_mtp_internal::onSessionReset(dcId);
}
void MTProtoSession::cancel(mtpRequestId requestId) { void MTProtoSession::cancel(mtpRequestId requestId) {
QWriteLocker locker(data.toSendMutex()); QWriteLocker locker(data.toSendMutex());
mtpPreRequestMap &toSend(data.toSendMap()); mtpPreRequestMap &toSend(data.toSendMap());

View File

@ -239,6 +239,7 @@ public slots:
void tryToReceive(); void tryToReceive();
void checkRequestsByTimer(); void checkRequestsByTimer();
void onConnectionStateChange(qint32 newState); void onConnectionStateChange(qint32 newState);
void onResetDone();
private: private:

View File

@ -866,6 +866,7 @@ PsMainWindow::PsMainWindow(QWidget *parent) : QMainWindow(parent), ps_hWnd(0), p
tbCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated"); tbCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated");
icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation); icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation);
icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation); icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation);
icon64 = icon256.scaledToWidth(64, Qt::SmoothTransformation);
connect(&psIdleTimer, SIGNAL(timeout()), this, SLOT(psIdleTimeout())); connect(&psIdleTimer, SIGNAL(timeout()), this, SLOT(psIdleTimeout()));
psIdleTimer.setSingleShot(false); psIdleTimer.setSingleShot(false);
} }
@ -986,9 +987,9 @@ void PsMainWindow::psUpdateCounter() {
int32 counter = App::histories().unreadFull; int32 counter = App::histories().unreadFull;
style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG; style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG;
QIcon icon; QIcon icon;
QImage cicon16(icon16), cicon32(icon32); QImage cicon16(icon16), cicon32(icon32), cicon64(icon64);
if (counter > 0) { if (counter > 0) {
{ if (!tbListInterface) {
QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0'));
QPainter p16(&cicon16); QPainter p16(&cicon16);
p16.setBrush(bg->b); p16.setBrush(bg->b);
@ -1017,12 +1018,26 @@ void PsMainWindow::psUpdateCounter() {
p32.setFont(f->f); p32.setFont(f->f);
p32.drawText(32 - w - d, f->ascent - 1, cnt); p32.drawText(32 - w - d, f->ascent - 1, cnt);
} }
if (!tbListInterface) {
QString cnt = (counter < 10000) ? QString("%1").arg(counter) : ((counter < 1000000) ? QString("%1K").arg(counter / 1000) : QString("%1M").arg(counter / 1000000));
QPainter p64(&cicon64);
style::font f(18);
int32 w = f->m.width(cnt), d = 6, r = 12;
p64.setBrush(bg->b);
p64.setPen(Qt::NoPen);
p64.setRenderHint(QPainter::Antialiasing);
p64.drawRoundedRect(QRect(64 - w - d * 2, 0, w + d * 2, f->height - 1), r, r);
p64.setPen(st::counterColor->p);
p64.setFont(f->f);
p64.drawText(64 - w - d, f->ascent - 1, cnt);
}
} }
icon.addPixmap(QPixmap::fromImage(cicon16)); icon.addPixmap(QPixmap::fromImage(cicon16));
icon.addPixmap(QPixmap::fromImage(cicon32)); icon.addPixmap(QPixmap::fromImage(cicon32));
icon.addPixmap(QPixmap::fromImage(cicon64));
if (trayIcon) { if (trayIcon) {
QIcon ticon; QIcon ticon;
QImage ticon16(icon16); QImage ticon16(icon16), ticon32(icon32);
if (counter > 0) { if (counter > 0) {
QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0'));
{ {
@ -1040,9 +1055,22 @@ void PsMainWindow::psUpdateCounter() {
p16.drawText(16 - w - d, 16 - f->height + f->ascent, cnt); p16.drawText(16 - w - d, 16 - f->height + f->ascent, cnt);
} }
{
QString cnt = (counter < 10000) ? QString("%1").arg(counter) : ((counter < 1000000) ? QString("%1K").arg(counter / 1000) : QString("%1M").arg(counter / 1000000));
QPainter p32(&ticon32);
style::font f(10);
int32 w = f->m.width(cnt), d = 3, r = 6;
p32.setBrush(bg->b);
p32.setPen(Qt::NoPen);
p32.setRenderHint(QPainter::Antialiasing);
p32.drawRoundedRect(QRect(32 - w - d * 2, 0, w + d * 2, f->height - 1), r, r);
p32.setPen(st::counterColor->p);
p32.setFont(f->f);
p32.drawText(32 - w - d, f->ascent - 1, cnt);
}
} }
ticon.addPixmap(QPixmap::fromImage(ticon16)); ticon.addPixmap(QPixmap::fromImage(ticon16));
ticon.addPixmap(QPixmap::fromImage(cicon32)); ticon.addPixmap(QPixmap::fromImage(ticon32));
trayIcon->setIcon(ticon); trayIcon->setIcon(ticon);
} }
@ -1055,9 +1083,10 @@ void PsMainWindow::psUpdateCounter() {
if (tbListInterface) { if (tbListInterface) {
if (counter > 0) { if (counter > 0) {
QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0')); QString cnt = (counter < 1000) ? QString("%1").arg(counter) : QString("..%1").arg(counter % 100, 2, 10, QChar('0'));
QImage oicon16(16, 16, QImage::Format_ARGB32); QImage oicon16(16, 16, QImage::Format_ARGB32), oicon32(32, 32, QImage::Format_ARGB32);
int32 cntSize = cnt.size(); int32 cntSize = cnt.size();
oicon16.fill(st::transparent->c); oicon16.fill(st::transparent->c);
oicon32.fill(st::transparent->c);
{ {
QPainter p16(&oicon16); QPainter p16(&oicon16);
p16.setBrush(bg->b); p16.setBrush(bg->b);
@ -1073,7 +1102,24 @@ void PsMainWindow::psUpdateCounter() {
p16.drawText(16 - w - d, 16 - f->height + f->ascent, cnt); p16.drawText(16 - w - d, 16 - f->height + f->ascent, cnt);
} }
QIcon oicon(QPixmap::fromImage(oicon16)); {
QPainter p32(&oicon32);
p32.setBrush(bg->b);
p32.setPen(Qt::NoPen);
p32.setRenderHint(QPainter::Antialiasing);
int32 fontSize = (cntSize < 2) ? 22 : ((cntSize < 3) ? 20 : 16);
style::font f(fontSize);
int32 w = f->m.width(cnt), d = (cntSize < 2) ? 9 : ((cntSize < 3) ? 4 : 4), r = (cntSize < 2) ? 16 : ((cntSize < 3) ? 14 : 6);
p32.drawRoundedRect(QRect(32 - w - d * 2, 32 - f->height, w + d * 2, f->height), r, r);
p32.setFont(f->f);
p32.setPen(st::counterColor->p);
p32.drawText(32 - w - d, 32 - f->height + f->ascent, cnt);
}
QIcon oicon;
oicon.addPixmap(QPixmap::fromImage(oicon16));
oicon.addPixmap(QPixmap::fromImage(oicon32));
ps_iconOverlay = _qt_createHIcon(oicon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); ps_iconOverlay = _qt_createHIcon(oicon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
} }
QString description = counter > 0 ? QString("%1 unread messages").arg(counter) : qsl("No unread messages"); QString description = counter > 0 ? QString("%1 unread messages").arg(counter) : qsl("No unread messages");

View File

@ -86,7 +86,7 @@ protected:
bool posInited; bool posInited;
QSystemTrayIcon *trayIcon; QSystemTrayIcon *trayIcon;
QMenu *trayIconMenu; QMenu *trayIconMenu;
QImage icon16, icon32, icon256; QImage icon16, icon32, icon64, icon256;
virtual void setupTrayIcon() { virtual void setupTrayIcon() {
} }

View File

@ -573,7 +573,9 @@ void Window::showConnecting(const QString &text, const QString &reconnect) {
_connecting->set(text, reconnect); _connecting->set(text, reconnect);
} else { } else {
_connecting = new ConnectingWidget(this, text, reconnect); _connecting = new ConnectingWidget(this, text, reconnect);
_connecting->show();
resizeEvent(0); resizeEvent(0);
fixOrder();
} }
} }

View File

@ -11,7 +11,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.5.12</string> <string>0.5.13</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>NOTE</key> <key>NOTE</key>

Binary file not shown.

View File

@ -1453,7 +1453,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.5.12; CURRENT_PROJECT_VERSION = 0.5.13;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
@ -1471,7 +1471,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 0.5.12; CURRENT_PROJECT_VERSION = 0.5.13;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = fast; GCC_OPTIMIZATION_LEVEL = fast;
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
@ -1495,9 +1495,9 @@
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 0.5.12; CURRENT_PROJECT_VERSION = 0.5.13;
DYLIB_COMPATIBILITY_VERSION = 0.5; DYLIB_COMPATIBILITY_VERSION = 0.5;
DYLIB_CURRENT_VERSION = 0.5.12; DYLIB_CURRENT_VERSION = 0.5.13;
FRAMEWORK_SEARCH_PATHS = ""; FRAMEWORK_SEARCH_PATHS = "";
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = fast; GCC_OPTIMIZATION_LEVEL = fast;
@ -1620,10 +1620,10 @@
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.5.12; CURRENT_PROJECT_VERSION = 0.5.13;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 0.5; DYLIB_COMPATIBILITY_VERSION = 0.5;
DYLIB_CURRENT_VERSION = 0.5.12; DYLIB_CURRENT_VERSION = 0.5.13;
FRAMEWORK_SEARCH_PATHS = ""; FRAMEWORK_SEARCH_PATHS = "";
GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;