moved MTProtoSession and MTProtoConnection to MTP::internal:: namespace

This commit is contained in:
John Preston 2016-03-24 11:57:11 +03:00
parent 26e2918841
commit d9ef8217e5
15 changed files with 1247 additions and 1180 deletions

View File

@ -910,7 +910,7 @@ void AppClass::killDownloadSessions() {
for (QMap<int32, uint64>::iterator i = killDownloadSessionTimes.begin(); i != killDownloadSessionTimes.end(); ) { for (QMap<int32, uint64>::iterator i = killDownloadSessionTimes.begin(); i != killDownloadSessionTimes.end(); ) {
if (i.value() <= ms) { if (i.value() <= ms) {
for (int j = 0; j < MTPDownloadSessionsCount; ++j) { for (int j = 0; j < MTPDownloadSessionsCount; ++j) {
MTP::stopSession(MTP::dld(j) + i.key()); MTP::stopSession(MTP::dldDcId(i.key(), j));
} }
i = killDownloadSessionTimes.erase(i); i = killDownloadSessionTimes.erase(i);
} else { } else {

View File

@ -103,7 +103,7 @@ void FileUploader::currentFailed() {
void FileUploader::killSessions() { void FileUploader::killSessions() {
for (int i = 0; i < MTPUploadSessionsCount; ++i) { for (int i = 0; i < MTPUploadSessionsCount; ++i) {
MTP::stopSession(MTP::upl(i)); MTP::stopSession(MTP::uplDcId(i));
} }
} }
@ -187,9 +187,9 @@ void FileUploader::sendNext() {
} }
mtpRequestId requestId; mtpRequestId requestId;
if (i->docSize > UseBigFilesFrom) { if (i->docSize > UseBigFilesFrom) {
requestId = MTP::send(MTPupload_SaveBigFilePart(MTP_long(i->id()), MTP_int(i->docSentParts), MTP_int(i->docPartsCount), MTP_string(toSend)), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::upl(todc)); requestId = MTP::send(MTPupload_SaveBigFilePart(MTP_long(i->id()), MTP_int(i->docSentParts), MTP_int(i->docPartsCount), MTP_string(toSend)), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::uplDcId(todc));
} else { } else {
requestId = MTP::send(MTPupload_SaveFilePart(MTP_long(i->id()), MTP_int(i->docSentParts), MTP_string(toSend)), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::upl(todc)); requestId = MTP::send(MTPupload_SaveFilePart(MTP_long(i->id()), MTP_int(i->docSentParts), MTP_string(toSend)), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::uplDcId(todc));
} }
docRequestsSent.insert(requestId, i->docSentParts); docRequestsSent.insert(requestId, i->docSentParts);
dcMap.insert(requestId, todc); dcMap.insert(requestId, todc);
@ -200,7 +200,7 @@ void FileUploader::sendNext() {
} else { } else {
UploadFileParts::iterator part = parts.begin(); UploadFileParts::iterator part = parts.begin();
mtpRequestId requestId = MTP::send(MTPupload_SaveFilePart(MTP_long(partsOfId), MTP_int(part.key()), MTP_string(part.value())), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::upl(todc)); mtpRequestId requestId = MTP::send(MTPupload_SaveFilePart(MTP_long(partsOfId), MTP_int(part.key()), MTP_string(part.value())), rpcDone(&FileUploader::partLoaded), rpcFail(&FileUploader::partFailed), MTP::uplDcId(todc));
requestsSent.insert(requestId, part.value()); requestsSent.insert(requestId, part.value());
dcMap.insert(requestId, todc); dcMap.insert(requestId, todc);
sentSize += part.value().size(); sentSize += part.value().size();
@ -246,7 +246,7 @@ void FileUploader::clear() {
dcMap.clear(); dcMap.clear();
sentSize = 0; sentSize = 0;
for (int32 i = 0; i < MTPUploadSessionsCount; ++i) { for (int32 i = 0; i < MTPUploadSessionsCount; ++i) {
MTP::stopSession(MTP::upl(i)); MTP::stopSession(MTP::uplDcId(i));
sentSizes[i] = 0; sentSizes[i] = 0;
} }
killSessionsTimer.stop(); killSessionsTimer.stop();

View File

@ -886,7 +886,7 @@ namespace {
stream >> dcIdWithShift >> flags >> ip >> port; stream >> dcIdWithShift >> flags >> ip >> port;
if (!_checkStreamStatus(stream)) return false; if (!_checkStreamStatus(stream)) return false;
if (_dcOpts) _dcOpts->insert(dcIdWithShift, MTP::DcOption(dcIdWithShift % _mtp_internal::dcShift, MTPDdcOption::Flags(flags), ip.toUtf8().constData(), port)); if (_dcOpts) _dcOpts->insert(dcIdWithShift, MTP::DcOption(MTP::bareDcId(dcIdWithShift), MTPDdcOption::Flags(flags), ip.toUtf8().constData(), port));
} break; } break;
case dbiChatSizeMax: { case dbiChatSizeMax: {
@ -931,7 +931,7 @@ namespace {
if (!_checkStreamStatus(stream)) return false; if (!_checkStreamStatus(stream)) return false;
DEBUG_LOG(("MTP Info: key found, dc %1, key: %2").arg(dcId).arg(Logs::mb(key, 256).str())); DEBUG_LOG(("MTP Info: key found, dc %1, key: %2").arg(dcId).arg(Logs::mb(key, 256).str()));
dcId = dcId % _mtp_internal::dcShift; dcId = MTP::bareDcId(dcId);
mtpAuthKeyPtr keyPtr(new mtpAuthKey()); mtpAuthKeyPtr keyPtr(new mtpAuthKey());
keyPtr->setKey(key); keyPtr->setKey(key);
keyPtr->setDC(dcId); keyPtr->setDC(dcId);
@ -2142,7 +2142,7 @@ namespace Local {
const BuiltInDc *bdcs = builtInDcs(); const BuiltInDc *bdcs = builtInDcs();
for (int i = 0, l = builtInDcsCount(); i < l; ++i) { for (int i = 0, l = builtInDcsCount(); i < l; ++i) {
MTPDdcOption::Flags flags = 0; MTPDdcOption::Flags flags = 0;
int idWithShift = bdcs[i].id + (flags * _mtp_internal::dcShift); MTP::ShiftedDcId idWithShift = MTP::shiftDcId(bdcs[i].id, flags);
dcOpts.insert(idWithShift, MTP::DcOption(bdcs[i].id, flags, bdcs[i].ip, bdcs[i].port)); dcOpts.insert(idWithShift, MTP::DcOption(bdcs[i].id, flags, 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)); 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));
} }
@ -2150,7 +2150,7 @@ namespace Local {
const BuiltInDc *bdcsipv6 = builtInDcsIPv6(); const BuiltInDc *bdcsipv6 = builtInDcsIPv6();
for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) { for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) {
MTPDdcOption::Flags flags = MTPDdcOption::Flag::f_ipv6; MTPDdcOption::Flags flags = MTPDdcOption::Flag::f_ipv6;
int idWithShift = bdcsipv6[i].id + (flags * _mtp_internal::dcShift); MTP::ShiftedDcId idWithShift = MTP::shiftDcId(bdcsipv6[i].id, flags);
dcOpts.insert(idWithShift, MTP::DcOption(bdcsipv6[i].id, flags, bdcsipv6[i].ip, bdcsipv6[i].port)); dcOpts.insert(idWithShift, MTP::DcOption(bdcsipv6[i].id, flags, bdcsipv6[i].ip, bdcsipv6[i].port));
DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: %2:%3").arg(bdcsipv6[i].id).arg(bdcsipv6[i].ip).arg(bdcsipv6[i].port)); DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: %2:%3").arg(bdcsipv6[i].id).arg(bdcsipv6[i].ip).arg(bdcsipv6[i].port));
} }
@ -2189,7 +2189,7 @@ namespace Local {
const BuiltInDc *bdcs = builtInDcs(); const BuiltInDc *bdcs = builtInDcs();
for (int i = 0, l = builtInDcsCount(); i < l; ++i) { for (int i = 0, l = builtInDcsCount(); i < l; ++i) {
MTPDdcOption::Flags flags = 0; MTPDdcOption::Flags flags = 0;
int idWithShift = bdcs[i].id + (flags * _mtp_internal::dcShift); MTP::ShiftedDcId idWithShift = MTP::shiftDcId(bdcs[i].id, flags);
dcOpts.insert(idWithShift, MTP::DcOption(bdcs[i].id, flags, bdcs[i].ip, bdcs[i].port)); dcOpts.insert(idWithShift, MTP::DcOption(bdcs[i].id, flags, 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)); 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));
} }
@ -2197,7 +2197,7 @@ namespace Local {
const BuiltInDc *bdcsipv6 = builtInDcsIPv6(); const BuiltInDc *bdcsipv6 = builtInDcsIPv6();
for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) { for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) {
MTPDdcOption::Flags flags = MTPDdcOption::Flag::f_ipv6; MTPDdcOption::Flags flags = MTPDdcOption::Flag::f_ipv6;
int idWithShift = bdcsipv6[i].id + (flags * _mtp_internal::dcShift); MTP::ShiftedDcId idWithShift = MTP::shiftDcId(bdcsipv6[i].id, flags);
dcOpts.insert(idWithShift, MTP::DcOption(bdcsipv6[i].id, flags, bdcsipv6[i].ip, bdcsipv6[i].port)); dcOpts.insert(idWithShift, MTP::DcOption(bdcsipv6[i].id, flags, bdcsipv6[i].ip, bdcsipv6[i].port));
DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: %2:%3").arg(bdcsipv6[i].id).arg(bdcsipv6[i].ip).arg(bdcsipv6[i].port)); DEBUG_LOG(("MTP Info: adding built in DC %1 IPv6 connect option: %2:%3").arg(bdcsipv6[i].id).arg(bdcsipv6[i].ip).arg(bdcsipv6[i].port));
} }

View File

@ -83,7 +83,7 @@ QString _logsEntryStart() {
QDateTime tm(QDateTime::currentDateTime()); QDateTime tm(QDateTime::currentDateTime());
QThread *thread = QThread::currentThread(); QThread *thread = QThread::currentThread();
MTPThread *mtpThread = qobject_cast<MTPThread*>(thread); MTP::internal::Thread *mtpThread = qobject_cast<MTP::internal::Thread*>(thread);
uint threadId = mtpThread ? mtpThread->getThreadId() : 0; uint threadId = mtpThread ? mtpThread->getThreadId() : 0;
return QString("[%1 %2-%3]").arg(tm.toString("hh:mm:ss.zzz")).arg(QString("%1").arg(threadId, 2, 10, QChar('0'))).arg(++index, 7, 10, QChar('0')); return QString("[%1 %2-%3]").arg(tm.toString("hh:mm:ss.zzz")).arg(QString("%1").arg(threadId, 2, 10, QChar('0'))).arg(++index, 7, 10, QChar('0'));

File diff suppressed because it is too large Load Diff

View File

@ -23,50 +23,26 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "mtproto/core_types.h" #include "mtproto/core_types.h"
#include "mtproto/auth_key.h" #include "mtproto/auth_key.h"
inline bool mtpRequestData::isSentContainer(const mtpRequest &request) { // "request-like" wrap for msgIds vector namespace MTP {
if (request->size() < 9) return false; namespace internal {
return (!request->msDate && !(*request)[6]); // msDate = 0, seqNo = 0
}
inline bool mtpRequestData::isStateRequest(const mtpRequest &request) {
if (request->size() < 9) return false;
return (mtpTypeId((*request)[8]) == mtpc_msgs_state_req);
}
inline bool mtpRequestData::needAck(const mtpRequest &request) {
if (request->size() < 9) return false;
return mtpRequestData::needAckByType((*request)[8]);
}
inline bool mtpRequestData::needAckByType(mtpTypeId type) {
switch (type) {
case mtpc_msg_container:
case mtpc_msgs_ack:
case mtpc_http_wait:
case mtpc_bad_msg_notification:
case mtpc_msgs_all_info:
case mtpc_msgs_state_info:
case mtpc_msg_detailed_info:
case mtpc_msg_new_detailed_info:
return false;
}
return true;
}
class MTProtoConnectionPrivate; class ConnectionPrivate;
class MTPSessionData; class SessionData;
class MTPThread : public QThread { class Thread : public QThread {
Q_OBJECT Q_OBJECT
public: public:
MTPThread(); Thread();
uint32 getThreadId() const; uint32 getThreadId() const;
~MTPThread(); ~Thread();
private: private:
uint32 _threadId; uint32 _threadId;
}; };
class MTProtoConnection { class Connection {
public: public:
enum ConnectionType { enum ConnectionType {
@ -74,19 +50,13 @@ public:
HttpConnection HttpConnection
}; };
MTProtoConnection(); Connection();
int32 start(MTPSessionData *data, int32 dc = 0); // return dc int32 start(SessionData *data, int32 dc = 0); // return dc
void kill(); void kill();
void waitTillFinish(); void waitTillFinish();
~MTProtoConnection(); ~Connection();
enum { static const int UpdateAlways = 666;
Disconnected = 0,
Connecting = 1,
Connected = 2,
UpdateAlways = 666
};
int32 state() const; int32 state() const;
QString transport() const; QString transport() const;
@ -94,18 +64,22 @@ public:
private: private:
QThread *thread; QThread *thread;
MTProtoConnectionPrivate *data; ConnectionPrivate *data;
}; };
class MTPabstractConnection : public QObject { class AbstractConnection : public QObject {
Q_OBJECT Q_OBJECT
typedef QList<mtpBuffer> BuffersQueue; typedef QList<mtpBuffer> BuffersQueue;
public: public:
MTPabstractConnection() : _sentEncrypted(false) { AbstractConnection() : _sentEncrypted(false) {
}
AbstractConnection(const AbstractConnection &other) = delete;
AbstractConnection &operator=(const AbstractConnection &other) = delete;
virtual ~AbstractConnection() = 0{
} }
void setSentEncrypted() { void setSentEncrypted() {
@ -149,12 +123,14 @@ protected:
}; };
class MTPabstractTcpConnection : public MTPabstractConnection { class AbstractTcpConnection : public AbstractConnection {
Q_OBJECT Q_OBJECT
public: public:
MTPabstractTcpConnection(); AbstractTcpConnection();
virtual ~AbstractTcpConnection() = 0 {
}
public slots: public slots:
@ -174,12 +150,12 @@ protected:
}; };
class MTPautoConnection : public MTPabstractTcpConnection { class AutoConnection : public AbstractTcpConnection {
Q_OBJECT Q_OBJECT
public: public:
MTPautoConnection(QThread *thread); AutoConnection(QThread *thread);
void sendData(mtpBuffer &buffer) override; void sendData(mtpBuffer &buffer) override;
void disconnectFromServer() override; void disconnectFromServer() override;
@ -239,12 +215,12 @@ private:
}; };
class MTPtcpConnection : public MTPabstractTcpConnection { class TCPConnection : public AbstractTcpConnection {
Q_OBJECT Q_OBJECT
public: public:
MTPtcpConnection(QThread *thread); TCPConnection(QThread *thread);
void sendData(mtpBuffer &buffer) override; void sendData(mtpBuffer &buffer) override;
void disconnectFromServer() override; void disconnectFromServer() override;
@ -287,12 +263,12 @@ private:
}; };
class MTPhttpConnection : public MTPabstractConnection { class HTTPConnection : public AbstractConnection {
Q_OBJECT Q_OBJECT
public: public:
MTPhttpConnection(QThread *thread); HTTPConnection(QThread *thread);
void sendData(mtpBuffer &buffer) override; void sendData(mtpBuffer &buffer) override;
void disconnectFromServer() override; void disconnectFromServer() override;
@ -330,13 +306,13 @@ private:
}; };
class MTProtoConnectionPrivate : public QObject { class ConnectionPrivate : public QObject {
Q_OBJECT Q_OBJECT
public: public:
MTProtoConnectionPrivate(QThread *thread, MTProtoConnection *owner, MTPSessionData *data, uint32 dc); ConnectionPrivate(QThread *thread, Connection *owner, SessionData *data, uint32 dc);
~MTProtoConnectionPrivate(); ~ConnectionPrivate();
void stop(); void stop();
@ -361,7 +337,7 @@ signals:
void resendManyAsync(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo); void resendManyAsync(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo);
void resendAllAsync(); void resendAllAsync();
void finished(MTProtoConnection *connection); void finished(Connection *connection);
public slots: public slots:
@ -412,7 +388,7 @@ private:
void doDisconnect(); void doDisconnect();
void createConn(bool createIPv4, bool createIPv6); void createConn(bool createIPv4, bool createIPv6);
void destroyConn(MTPabstractConnection **conn = 0); // 0 - destory all void destroyConn(AbstractConnection **conn = 0); // 0 - destory all
mtpMsgId placeToContainer(mtpRequest &toSendRequest, mtpMsgId &bigMsgId, mtpMsgId *&haveSentArr, mtpRequest &req); mtpMsgId placeToContainer(mtpRequest &toSendRequest, mtpMsgId &bigMsgId, mtpMsgId *&haveSentArr, mtpRequest &req);
mtpMsgId prepareToSend(mtpRequest &request, mtpMsgId currentLastId); mtpMsgId prepareToSend(mtpRequest &request, mtpMsgId currentLastId);
@ -427,7 +403,7 @@ private:
void clearMessages(); void clearMessages();
bool setState(int32 state, int32 ifState = MTProtoConnection::UpdateAlways); bool setState(int32 state, int32 ifState = Connection::UpdateAlways);
mutable QReadWriteLock stateConnMutex; mutable QReadWriteLock stateConnMutex;
int32 _state; int32 _state;
@ -435,8 +411,8 @@ private:
void resetSession(); void resetSession();
uint32 dc; uint32 dc;
MTProtoConnection *_owner; Connection *_owner;
MTPabstractConnection *_conn, *_conn4, *_conn6; AbstractConnection *_conn, *_conn4, *_conn6;
SingleTimer retryTimer; // exp retry timer SingleTimer retryTimer; // exp retry timer
int retryTimeout; int retryTimeout;
@ -475,7 +451,8 @@ private:
uint64 keyId; uint64 keyId;
QReadWriteLock sessionDataMutex; QReadWriteLock sessionDataMutex;
MTPSessionData *sessionData; SessionData *sessionData;
bool myKeyLock; bool myKeyLock;
void lockKey(); void lockKey();
void unlockKey(); void unlockKey();
@ -523,3 +500,6 @@ private:
void clearAuthKeyData(); void clearAuthKeyData();
}; };
} // namespace internal
} // namespace MTP

View File

@ -22,35 +22,16 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "types.h" #include "types.h"
#undef min namespace MTP {
#undef max
//#define DEBUG_MTPPRIME // type DcId represents actual data center id, while in most cases
// we use some shifted ids, like DcId() + X * DCShift
typedef int32 DcId;
typedef int32 ShiftedDcId;
}
#ifdef DEBUG_MTPPRIME
class mtpPrime { // for debug visualization, not like int32 :( in default constructor
public:
explicit mtpPrime() : _v(0) {
}
mtpPrime(int32 v) : _v(v) {
}
mtpPrime &operator=(int32 v) {
_v = v;
return (*this);
}
operator int32&() {
return _v;
}
operator const int32 &() const {
return _v;
}
private:
int32 _v;
};
#else
typedef int32 mtpPrime; typedef int32 mtpPrime;
#endif
typedef int32 mtpRequestId; typedef int32 mtpRequestId;
typedef uint64 mtpMsgId; typedef uint64 mtpMsgId;
typedef uint64 mtpPingId; typedef uint64 mtpPingId;
@ -1072,3 +1053,30 @@ extern const MTPVector<MTPMessageEntity> MTPnullEntities;
extern const MTPMessageFwdHeader MTPnullFwdHeader; extern const MTPMessageFwdHeader MTPnullFwdHeader;
QString stickerSetTitle(const MTPDstickerSet &s); QString stickerSetTitle(const MTPDstickerSet &s);
inline bool mtpRequestData::isSentContainer(const mtpRequest &request) { // "request-like" wrap for msgIds vector
if (request->size() < 9) return false;
return (!request->msDate && !(*request)[6]); // msDate = 0, seqNo = 0
}
inline bool mtpRequestData::isStateRequest(const mtpRequest &request) {
if (request->size() < 9) return false;
return (mtpTypeId((*request)[8]) == mtpc_msgs_state_req);
}
inline bool mtpRequestData::needAck(const mtpRequest &request) {
if (request->size() < 9) return false;
return mtpRequestData::needAckByType((*request)[8]);
}
inline bool mtpRequestData::needAckByType(mtpTypeId type) {
switch (type) {
case mtpc_msg_container:
case mtpc_msgs_ack:
case mtpc_http_wait:
case mtpc_bad_msg_notification:
case mtpc_msgs_all_info:
case mtpc_msgs_state_info:
case mtpc_msg_detailed_info:
case mtpc_msg_new_detailed_info:
return false;
}
return true;
}

View File

@ -82,7 +82,7 @@ void mtpLogoutOtherDCs() {
} }
for (int32 i = 0, cnt = dcs.size(); i != cnt; ++i) { for (int32 i = 0, cnt = dcs.size(); i != cnt; ++i) {
if (dcs[i] != MTP::maindc()) { if (dcs[i] != MTP::maindc()) {
logoutGuestMap.insert(MTP::lgt + dcs[i], MTP::send(MTPauth_LogOut(), rpcDone(&logoutDone), rpcFail(&logoutDone), MTP::lgt + dcs[i])); logoutGuestMap.insert(MTP::lgtDcId(dcs[i]), MTP::send(MTPauth_LogOut(), rpcDone(&logoutDone), rpcFail(&logoutDone), MTP::lgtDcId(dcs[i])));
} }
} }
} }
@ -193,7 +193,7 @@ void mtpUpdateDcOptions(const QVector<MTPDcOption> &options) {
} }
for (QVector<MTPDcOption>::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) { for (QVector<MTPDcOption>::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) {
const MTPDdcOption &optData(i->c_dcOption()); const MTPDdcOption &optData(i->c_dcOption());
int32 id = optData.vid.v, idWithShift = id + (optData.vflags.v * _mtp_internal::dcShift); int32 id = optData.vid.v, idWithShift = MTP::shiftDcId(id, optData.vflags.v);
if (already.constFind(idWithShift) == already.cend()) { if (already.constFind(idWithShift) == already.cend()) {
already.insert(idWithShift); already.insert(idWithShift);
auto a = opts.constFind(idWithShift); auto a = opts.constFind(idWithShift);
@ -243,7 +243,7 @@ void MTProtoConfigLoader::done() {
_enumRequest = 0; _enumRequest = 0;
} }
if (_enumCurrent) { if (_enumCurrent) {
MTP::killSession(MTP::cfg + _enumCurrent); MTP::killSession(MTP::cfgDcId(_enumCurrent));
_enumCurrent = 0; _enumCurrent = 0;
} }
emit loaded(); emit loaded();
@ -257,14 +257,14 @@ void MTProtoConfigLoader::enumDC() {
if (!_enumCurrent) { if (!_enumCurrent) {
_enumCurrent = mainDC; _enumCurrent = mainDC;
} else { } else {
MTP::killSession(MTP::cfg + _enumCurrent); MTP::killSession(MTP::cfgDcId(_enumCurrent));
} }
OrderedSet<int32> dcs; OrderedSet<int32> dcs;
{ {
QReadLocker lock(mtpDcOptionsMutex()); QReadLocker lock(mtpDcOptionsMutex());
const MTP::DcOptions &options(Global::DcOptions()); const MTP::DcOptions &options(Global::DcOptions());
for (auto i = options.cbegin(), e = options.cend(); i != e; ++i) { for (auto i = options.cbegin(), e = options.cend(); i != e; ++i) {
dcs.insert(i.key() % _mtp_internal::dcShift); dcs.insert(MTP::bareDcId(i.key()));
} }
} }
OrderedSet<int32>::const_iterator i = dcs.constFind(_enumCurrent); OrderedSet<int32>::const_iterator i = dcs.constFind(_enumCurrent);
@ -273,7 +273,7 @@ void MTProtoConfigLoader::enumDC() {
} else { } else {
_enumCurrent = i.key(); _enumCurrent = i.key();
} }
_enumRequest = MTP::send(MTPhelp_GetConfig(), rpcDone(configLoaded), rpcFail(configFailed), MTP::cfg + _enumCurrent); _enumRequest = MTP::send(MTPhelp_GetConfig(), rpcDone(configLoaded), rpcFail(configFailed), MTP::cfgDcId(_enumCurrent));
_enumDCTimer.start(MTPEnumDCTimeout); _enumDCTimer.start(MTPEnumDCTimeout);
} }

View File

@ -24,10 +24,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "localstorage.h" #include "localstorage.h"
namespace MTP {
namespace { namespace {
typedef QMap<int32, MTProtoSession*> Sessions;
typedef QMap<int32, internal::Session*> Sessions;
Sessions sessions; Sessions sessions;
MTProtoSession *mainSession; internal::Session *mainSession;
typedef QMap<mtpRequestId, int32> RequestsByDC; // holds dcWithShift for request to this dc or -dc for request to main dc typedef QMap<mtpRequestId, int32> RequestsByDC; // holds dcWithShift for request to this dc or -dc for request to main dc
RequestsByDC requestsByDC; RequestsByDC requestsByDC;
@ -62,7 +65,7 @@ namespace {
typedef QMap<int32, DCAuthWaiters> AuthWaiters; // holds request ids waiting for auth import to specific dc typedef QMap<int32, DCAuthWaiters> AuthWaiters; // holds request ids waiting for auth import to specific dc
AuthWaiters authWaiters; AuthWaiters authWaiters;
typedef OrderedSet<MTProtoConnection*> MTPQuittingConnections; typedef OrderedSet<internal::Connection*> MTPQuittingConnections;
MTPQuittingConnections quittingConnections; MTPQuittingConnections quittingConnections;
QMutex toClearLock; QMutex toClearLock;
@ -71,7 +74,7 @@ namespace {
RPCResponseHandler globalHandler; RPCResponseHandler globalHandler;
MTPStateChangedHandler stateChangedHandler = 0; MTPStateChangedHandler stateChangedHandler = 0;
MTPSessionResetHandler sessionResetHandler = 0; MTPSessionResetHandler sessionResetHandler = 0;
_mtp_internal::GlobalSlotCarrier *_globalSlotCarrier = 0; internal::GlobalSlotCarrier *_globalSlotCarrier = 0;
void importDone(const MTPauth_Authorization &result, mtpRequestId req) { void importDone(const MTPauth_Authorization &result, mtpRequestId req) {
QMutexLocker locker1(&requestByDCLock); QMutexLocker locker1(&requestByDCLock);
@ -79,11 +82,11 @@ namespace {
RequestsByDC::iterator i = requestsByDC.find(req); RequestsByDC::iterator i = requestsByDC.find(req);
if (i == requestsByDC.end()) { if (i == requestsByDC.end()) {
LOG(("MTP Error: auth import request not found in requestsByDC, requestId: %1").arg(req)); LOG(("MTP Error: auth import request not found in requestsByDC, requestId: %1").arg(req));
RPCError error(rpcClientError("AUTH_IMPORT_FAIL", QString("did not find import request in requestsByDC, request %1").arg(req))); RPCError error(internal::rpcClientError("AUTH_IMPORT_FAIL", QString("did not find import request in requestsByDC, request %1").arg(req)));
if (globalHandler.onFail && MTP::authedId()) (*globalHandler.onFail)(req, error); // auth failed in main dc if (globalHandler.onFail && authedId()) (*globalHandler.onFail)(req, error); // auth failed in main dc
return; return;
} }
int32 newdc = i.value() % _mtp_internal::dcShift; DcId newdc = bareDcId(i.value());
DEBUG_LOG(("MTP Info: auth import to dc %1 succeeded").arg(newdc)); DEBUG_LOG(("MTP Info: auth import to dc %1 succeeded").arg(newdc));
@ -105,16 +108,15 @@ namespace {
continue; continue;
} }
if (k.value() < 0) { if (k.value() < 0) {
MTP::setdc(newdc); setdc(newdc);
k.value() = -newdc; k.value() = -newdc;
} else { } else {
int32 shift = k.value() - (k.value() % _mtp_internal::dcShift); dcWithShift += getDcIdShift(k.value());
dcWithShift += shift;
k.value() = dcWithShift; k.value() = dcWithShift;
} }
DEBUG_LOG(("MTP Info: resending request %1 to dc %2 after import auth").arg(requestId).arg(k.value())); DEBUG_LOG(("MTP Info: resending request %1 to dc %2 after import auth").arg(requestId).arg(k.value()));
} }
if (MTProtoSession *session = _mtp_internal::getSession(dcWithShift)) { if (internal::Session *session = internal::getSession(dcWithShift)) {
session->sendPrepared(j.value()); session->sendPrepared(j.value());
} }
} }
@ -125,7 +127,7 @@ namespace {
bool importFail(const RPCError &error, mtpRequestId req) { bool importFail(const RPCError &error, mtpRequestId req) {
if (mtpIsFlood(error)) return false; if (mtpIsFlood(error)) return false;
if (globalHandler.onFail && MTP::authedId()) (*globalHandler.onFail)(req, error); // auth import failed if (globalHandler.onFail && authedId()) (*globalHandler.onFail)(req, error); // auth import failed
return true; return true;
} }
@ -133,13 +135,13 @@ namespace {
AuthExportRequests::const_iterator i = authExportRequests.constFind(req); AuthExportRequests::const_iterator i = authExportRequests.constFind(req);
if (i == authExportRequests.cend()) { if (i == authExportRequests.cend()) {
LOG(("MTP Error: auth export request target dcWithShift not found, requestId: %1").arg(req)); LOG(("MTP Error: auth export request target dcWithShift not found, requestId: %1").arg(req));
RPCError error(rpcClientError("AUTH_IMPORT_FAIL", QString("did not find target dcWithShift, request %1").arg(req))); RPCError error(internal::rpcClientError("AUTH_IMPORT_FAIL", QString("did not find target dcWithShift, request %1").arg(req)));
if (globalHandler.onFail && MTP::authedId()) (*globalHandler.onFail)(req, error); // auth failed in main dc if (globalHandler.onFail && authedId()) (*globalHandler.onFail)(req, error); // auth failed in main dc
return; return;
} }
const MTPDauth_exportedAuthorization &data(result.c_auth_exportedAuthorization()); const MTPDauth_exportedAuthorization &data(result.c_auth_exportedAuthorization());
MTP::send(MTPauth_ImportAuthorization(data.vid, data.vbytes), rpcDone(importDone), rpcFail(importFail), i.value()); send(MTPauth_ImportAuthorization(data.vid, data.vbytes), rpcDone(importDone), rpcFail(importFail), i.value());
authExportRequests.remove(req); authExportRequests.remove(req);
} }
@ -148,9 +150,9 @@ namespace {
AuthExportRequests::const_iterator i = authExportRequests.constFind(req); AuthExportRequests::const_iterator i = authExportRequests.constFind(req);
if (i != authExportRequests.cend()) { if (i != authExportRequests.cend()) {
authWaiters[i.value() % _mtp_internal::dcShift].clear(); authWaiters[bareDcId(i.value())].clear();
} }
if (globalHandler.onFail && MTP::authedId()) (*globalHandler.onFail)(req, error); // auth failed in main dc if (globalHandler.onFail && authedId()) (*globalHandler.onFail)(req, error); // auth failed in main dc
return true; return true;
} }
@ -179,11 +181,11 @@ namespace {
DEBUG_LOG(("MTP Info: changing request %1 from dcWithShift%2 to dc%3").arg(requestId).arg(dcWithShift).arg(newdcWithShift)); DEBUG_LOG(("MTP Info: changing request %1 from dcWithShift%2 to dc%3").arg(requestId).arg(dcWithShift).arg(newdcWithShift));
if (dcWithShift < 0) { // newdc shift = 0 if (dcWithShift < 0) { // newdc shift = 0
if (false && MTP::authedId() && !authExportRequests.contains(requestId)) { // migrate not supported at this moment if (false && authedId() && !authExportRequests.contains(requestId)) { // migrate not supported at this moment
DEBUG_LOG(("MTP Info: importing auth to dc %1").arg(newdcWithShift)); DEBUG_LOG(("MTP Info: importing auth to dc %1").arg(newdcWithShift));
DCAuthWaiters &waiters(authWaiters[newdcWithShift]); DCAuthWaiters &waiters(authWaiters[newdcWithShift]);
if (!waiters.size()) { if (!waiters.size()) {
authExportRequests.insert(MTP::send(MTPauth_ExportAuthorization(MTP_int(newdcWithShift)), rpcDone(exportDone), rpcFail(exportFail)), newdcWithShift); authExportRequests.insert(send(MTPauth_ExportAuthorization(MTP_int(newdcWithShift)), rpcDone(exportDone), rpcFail(exportFail)), newdcWithShift);
} }
waiters.push_back(requestId); waiters.push_back(requestId);
return true; return true;
@ -191,8 +193,7 @@ namespace {
MTP::setdc(newdcWithShift); MTP::setdc(newdcWithShift);
} }
} else { } else {
int32 shift = dcWithShift - (dcWithShift % _mtp_internal::dcShift); newdcWithShift += MTP::getDcIdShift(dcWithShift);
newdcWithShift += shift;
} }
mtpRequest req; mtpRequest req;
@ -205,8 +206,8 @@ namespace {
} }
req = i.value(); req = i.value();
} }
if (MTProtoSession *session = _mtp_internal::getSession(newdcWithShift)) { if (internal::Session *session = internal::getSession(newdcWithShift)) {
_mtp_internal::registerRequest(requestId, (dcWithShift < 0) ? -newdcWithShift : newdcWithShift); internal::registerRequest(requestId, (dcWithShift < 0) ? -newdcWithShift : newdcWithShift);
session->sendPrepared(req); session->sendPrepared(req);
} }
return true; return true;
@ -247,8 +248,8 @@ namespace {
LOG(("MTP Error: unauthorized request without dc info, requestId %1").arg(requestId)); LOG(("MTP Error: unauthorized request without dc info, requestId %1").arg(requestId));
} }
} }
int32 newdc = abs(dcWithShift) % _mtp_internal::dcShift; int32 newdc = bareDcId(qAbs(dcWithShift));
if (!newdc || newdc == mtpMainDC() || !MTP::authedId()) { if (!newdc || newdc == mtpMainDC() || !authedId()) {
if (!badGuestDC && globalHandler.onFail) (*globalHandler.onFail)(requestId, error); // auth failed in main dc if (!badGuestDC && globalHandler.onFail) (*globalHandler.onFail)(requestId, error); // auth failed in main dc
return false; return false;
} }
@ -256,7 +257,7 @@ namespace {
DEBUG_LOG(("MTP Info: importing auth to dcWithShift %1").arg(dcWithShift)); DEBUG_LOG(("MTP Info: importing auth to dcWithShift %1").arg(dcWithShift));
DCAuthWaiters &waiters(authWaiters[newdc]); DCAuthWaiters &waiters(authWaiters[newdc]);
if (!waiters.size()) { if (!waiters.size()) {
authExportRequests.insert(MTP::send(MTPauth_ExportAuthorization(MTP_int(newdc)), rpcDone(exportDone), rpcFail(exportFail)), abs(dcWithShift)); authExportRequests.insert(send(MTPauth_ExportAuthorization(MTP_int(newdc)), rpcDone(exportDone), rpcFail(exportFail)), abs(dcWithShift));
} }
waiters.push_back(requestId); waiters.push_back(requestId);
if (badGuestDC) badGuestDCRequests.insert(requestId); if (badGuestDC) badGuestDCRequests.insert(requestId);
@ -284,7 +285,7 @@ namespace {
} }
if (!dcWithShift) return false; if (!dcWithShift) return false;
if (MTProtoSession *session = _mtp_internal::getSession(dcWithShift < 0 ? (-dcWithShift) : dcWithShift)) { if (internal::Session *session = internal::getSession(qAbs(dcWithShift))) {
req->needsLayer = true; req->needsLayer = true;
session->sendPrepared(req); session->sendPrepared(req);
} }
@ -322,12 +323,12 @@ namespace {
if (!dcWithShift) return false; if (!dcWithShift) return false;
if (!req->after) { if (!req->after) {
if (MTProtoSession *session = _mtp_internal::getSession(dcWithShift < 0 ? (-dcWithShift) : dcWithShift)) { if (internal::Session *session = internal::getSession(qAbs(dcWithShift))) {
req->needsLayer = true; req->needsLayer = true;
session->sendPrepared(req); session->sendPrepared(req);
} }
} else { } else {
int32 newdc = abs(dcWithShift) % _mtp_internal::dcShift; int32 newdc = bareDcId(qAbs(dcWithShift));
DCAuthWaiters &waiters(authWaiters[newdc]); DCAuthWaiters &waiters(authWaiters[newdc]);
if (waiters.indexOf(req->after->requestId) >= 0) { if (waiters.indexOf(req->after->requestId) >= 0) {
if (waiters.indexOf(requestId) < 0) { if (waiters.indexOf(requestId) < 0) {
@ -360,36 +361,37 @@ namespace {
bool _paused = false; bool _paused = false;
} } // namespace
namespace _mtp_internal { namespace internal {
MTProtoSession *getSession(int32 dcWithShift) {
if (!_started) return 0; Session *getSession(ShiftedDcId shiftedDcId) {
if (!dcWithShift) return mainSession; if (!_started) return nullptr;
if (!(dcWithShift % _mtp_internal::dcShift)) { if (!shiftedDcId) return mainSession;
dcWithShift += (mainSession->getDcWithShift() % _mtp_internal::dcShift); if (!bareDcId(shiftedDcId)) {
shiftedDcId += bareDcId(mainSession->getDcWithShift());
} }
Sessions::const_iterator i = sessions.constFind(dcWithShift); Sessions::const_iterator i = sessions.constFind(shiftedDcId);
if (i == sessions.cend()) { if (i == sessions.cend()) {
i = sessions.insert(dcWithShift, new MTProtoSession(dcWithShift)); i = sessions.insert(shiftedDcId, new Session(shiftedDcId));
} }
return i.value(); return i.value();
} }
bool paused() { bool paused() {
return _paused; return _paused;
} }
void registerRequest(mtpRequestId requestId, int32 dcWithShift) { void registerRequest(mtpRequestId requestId, int32 dcWithShift) {
{ {
QMutexLocker locker(&requestByDCLock); QMutexLocker locker(&requestByDCLock);
requestsByDC.insert(requestId, dcWithShift); requestsByDC.insert(requestId, dcWithShift);
} }
_mtp_internal::performDelayedClear(); // need to do it somewhere.. internal::performDelayedClear(); // need to do it somewhere..
} }
void unregisterRequest(mtpRequestId requestId) { void unregisterRequest(mtpRequestId requestId) {
requestsDelays.remove(requestId); requestsDelays.remove(requestId);
{ {
@ -399,9 +401,9 @@ namespace _mtp_internal {
QMutexLocker locker(&requestByDCLock); QMutexLocker locker(&requestByDCLock);
requestsByDC.remove(requestId); requestsByDC.remove(requestId);
} }
mtpRequestId storeRequest(mtpRequest &request, const RPCResponseHandler &parser) { mtpRequestId storeRequest(mtpRequest &request, const RPCResponseHandler &parser) {
mtpRequestId res = reqid(); mtpRequestId res = reqid();
request->requestId = res; request->requestId = res;
if (parser.onDone || parser.onFail) { if (parser.onDone || parser.onFail) {
@ -413,9 +415,9 @@ namespace _mtp_internal {
requestMap.insert(res, request); requestMap.insert(res, request);
} }
return res; return res;
} }
mtpRequest getRequest(mtpRequestId reqId) { mtpRequest getRequest(mtpRequestId reqId) {
static mtpRequest zero; static mtpRequest zero;
mtpRequest req; mtpRequest req;
{ {
@ -424,9 +426,9 @@ namespace _mtp_internal {
req = (i == requestMap.cend()) ? zero : i.value(); req = (i == requestMap.cend()) ? zero : i.value();
} }
return req; return req;
} }
void wrapInvokeAfter(mtpRequest &to, const mtpRequest &from, const mtpRequestMap &haveSent, int32 skipBeforeRequest) { void wrapInvokeAfter(mtpRequest &to, const mtpRequest &from, const mtpRequestMap &haveSent, int32 skipBeforeRequest) {
mtpMsgId afterId(*(mtpMsgId*)(from->after->data() + 4)); mtpMsgId afterId(*(mtpMsgId*)(from->after->data() + 4));
mtpRequestMap::const_iterator i = afterId ? haveSent.constFind(afterId) : haveSent.cend(); mtpRequestMap::const_iterator i = afterId ? haveSent.constFind(afterId) : haveSent.cend();
int32 size = to->size(), lenInInts = (from.innerLength() >> 2), headlen = 4, fulllen = headlen + lenInInts; int32 size = to->size(), lenInInts = (from.innerLength() >> 2), headlen = 4, fulllen = headlen + lenInInts;
@ -447,9 +449,9 @@ namespace _mtp_internal {
memcpy(to->data() + size + headlen + skipBeforeRequest + 3, from->constData() + 4 + headlen, lenInInts * sizeof(mtpPrime)); memcpy(to->data() + size + headlen + skipBeforeRequest + 3, from->constData() + 4 + headlen, lenInInts * sizeof(mtpPrime));
if (size + 3 != 7) (*to)[7] += 3 * sizeof(mtpPrime); if (size + 3 != 7) (*to)[7] += 3 * sizeof(mtpPrime);
} }
} }
void clearCallbacks(mtpRequestId requestId, int32 errorCode) { void clearCallbacks(mtpRequestId requestId, int32 errorCode) {
RPCResponseHandler h; RPCResponseHandler h;
bool found = false; bool found = false;
{ {
@ -465,9 +467,9 @@ namespace _mtp_internal {
if (errorCode && found) { if (errorCode && found) {
rpcErrorOccured(requestId, h, rpcClientError("CLEAR_CALLBACK", QString("did not handle request %1, error code %2").arg(requestId).arg(errorCode))); rpcErrorOccured(requestId, h, rpcClientError("CLEAR_CALLBACK", QString("did not handle request %1, error code %2").arg(requestId).arg(errorCode)));
} }
} }
void clearCallbacksDelayed(const RPCCallbackClears &requestIds) { void clearCallbacksDelayed(const RPCCallbackClears &requestIds) {
uint32 idsCount = requestIds.size(); uint32 idsCount = requestIds.size();
if (!idsCount) return; if (!idsCount) return;
@ -487,9 +489,9 @@ namespace _mtp_internal {
} else { } else {
toClear = requestIds; toClear = requestIds;
} }
} }
void performDelayedClear() { void performDelayedClear() {
QMutexLocker lock(&toClearLock); QMutexLocker lock(&toClearLock);
if (!toClear.isEmpty()) { if (!toClear.isEmpty()) {
for (RPCCallbackClears::iterator i = toClear.begin(), e = toClear.end(); i != e; ++i) { for (RPCCallbackClears::iterator i = toClear.begin(), e = toClear.end(); i != e; ++i) {
@ -500,13 +502,13 @@ namespace _mtp_internal {
} }
} }
clearCallbacks(i->requestId, i->errorCode); clearCallbacks(i->requestId, i->errorCode);
_mtp_internal::unregisterRequest(i->requestId); internal::unregisterRequest(i->requestId);
} }
toClear.clear(); toClear.clear();
} }
} }
void execCallback(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) { void execCallback(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) {
RPCResponseHandler h; RPCResponseHandler h;
{ {
QMutexLocker locker(&parserMapLock); QMutexLocker locker(&parserMapLock);
@ -547,27 +549,27 @@ namespace _mtp_internal {
DEBUG_LOG(("RPC Info: parser not found for %1").arg(requestId)); DEBUG_LOG(("RPC Info: parser not found for %1").arg(requestId));
} }
unregisterRequest(requestId); unregisterRequest(requestId);
} }
bool hasCallbacks(mtpRequestId requestId) { bool hasCallbacks(mtpRequestId requestId) {
QMutexLocker locker(&parserMapLock); QMutexLocker locker(&parserMapLock);
ParserMap::iterator i = parserMap.find(requestId); ParserMap::iterator i = parserMap.find(requestId);
return (i != parserMap.cend()); return (i != parserMap.cend());
} }
void globalCallback(const mtpPrime *from, const mtpPrime *end) { void globalCallback(const mtpPrime *from, const mtpPrime *end) {
if (globalHandler.onDone) (*globalHandler.onDone)(0, from, end); // some updates were received if (globalHandler.onDone) (*globalHandler.onDone)(0, from, end); // some updates were received
} }
void onStateChange(int32 dcWithShift, int32 state) { void onStateChange(int32 dcWithShift, int32 state) {
if (stateChangedHandler) stateChangedHandler(dcWithShift, state); if (stateChangedHandler) stateChangedHandler(dcWithShift, state);
} }
void onSessionReset(int32 dcWithShift) { void onSessionReset(int32 dcWithShift) {
if (sessionResetHandler) sessionResetHandler(dcWithShift); if (sessionResetHandler) sessionResetHandler(dcWithShift);
} }
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 (mtpIsFlood(err)) { if (mtpIsFlood(err)) {
if (onFail && (*onFail)(requestId, err)) return true; if (onFail && (*onFail)(requestId, err)) return true;
} }
@ -578,13 +580,13 @@ namespace _mtp_internal {
LOG(("RPC Error: request %1 got fail with code %2, error %3%4").arg(requestId).arg(err.code()).arg(err.type()).arg(err.description().isEmpty() ? QString() : QString(": %1").arg(err.description()))); LOG(("RPC Error: request %1 got fail with code %2, error %3%4").arg(requestId).arg(err.code()).arg(err.type()).arg(err.description().isEmpty() ? QString() : QString(": %1").arg(err.description())));
onFail && (*onFail)(requestId, err); onFail && (*onFail)(requestId, err);
return true; return true;
} }
GlobalSlotCarrier::GlobalSlotCarrier() { GlobalSlotCarrier::GlobalSlotCarrier() {
connect(&_timer, SIGNAL(timeout()), this, SLOT(checkDelayed())); connect(&_timer, SIGNAL(timeout()), this, SLOT(checkDelayed()));
} }
void GlobalSlotCarrier::checkDelayed() { void GlobalSlotCarrier::checkDelayed() {
uint64 now = getms(true); uint64 now = getms(true);
while (!delayedRequests.isEmpty() && now >= delayedRequests.front().second) { while (!delayedRequests.isEmpty() && now >= delayedRequests.front().second) {
mtpRequestId requestId = delayedRequests.front().first; mtpRequestId requestId = delayedRequests.front().first;
@ -612,7 +614,7 @@ namespace _mtp_internal {
} }
req = j.value(); req = j.value();
} }
if (MTProtoSession *session = _mtp_internal::getSession(dcWithShift < 0 ? (-dcWithShift) : dcWithShift)) { if (Session *session = getSession(qAbs(dcWithShift))) {
session->sendPrepared(req); session->sendPrepared(req);
} }
} }
@ -620,9 +622,9 @@ namespace _mtp_internal {
if (!delayedRequests.isEmpty()) { if (!delayedRequests.isEmpty()) {
_timer.start(delayedRequests.front().second - now); _timer.start(delayedRequests.front().second - now);
} }
} }
void GlobalSlotCarrier::connectionFinished(MTProtoConnection *connection) { void GlobalSlotCarrier::connectionFinished(Connection *connection) {
MTPQuittingConnections::iterator i = quittingConnections.find(connection); MTPQuittingConnections::iterator i = quittingConnections.find(connection);
if (i != quittingConnections.cend()) { if (i != quittingConnections.cend()) {
quittingConnections.erase(i); quittingConnections.erase(i);
@ -630,35 +632,28 @@ namespace _mtp_internal {
connection->waitTillFinish(); connection->waitTillFinish();
delete connection; delete connection;
} }
GlobalSlotCarrier *globalSlotCarrier() { GlobalSlotCarrier *globalSlotCarrier() {
return _globalSlotCarrier; return _globalSlotCarrier;
} }
void queueQuittingConnection(MTProtoConnection *connection) { void queueQuittingConnection(Connection *connection) {
quittingConnections.insert(connection); quittingConnections.insert(connection);
} }
}; } // namespace internal
namespace MTP { void start() {
const uint32 cfg = 1 * _mtp_internal::dcShift; // send(MTPhelp_GetConfig(), MTP::cfg + dc) - for dc enum
const uint32 lgt = 2 * _mtp_internal::dcShift; // send(MTPauth_LogOut(), MTP::lgt + dc) - for logout of guest dcs enum
const uint32 dldStart = dld(0), dldEnd = dld(MTPDownloadSessionsCount - 1) + _mtp_internal::dcShift;
const uint32 uplStart = upl(0), uplEnd = upl(MTPUploadSessionsCount - 1) + _mtp_internal::dcShift;
void start() {
if (started()) return; if (started()) return;
unixtimeInit(); unixtimeInit();
MTProtoDCMap &dcs(mtpDCMap()); MTProtoDCMap &dcs(mtpDCMap());
_globalSlotCarrier = new _mtp_internal::GlobalSlotCarrier(); _globalSlotCarrier = new internal::GlobalSlotCarrier();
mainSession = new MTProtoSession(mtpMainDC()); mainSession = new internal::Session(mtpMainDC());
sessions.insert(mainSession->getDcWithShift(), mainSession); sessions.insert(mainSession->getDcWithShift(), mainSession);
_started = true; _started = true;
@ -666,51 +661,51 @@ namespace MTP {
if (mtpNeedConfig()) { if (mtpNeedConfig()) {
mtpConfigLoader()->load(); mtpConfigLoader()->load();
} }
} }
bool started() { bool started() {
return _started; return _started;
} }
void restart() { void restart() {
if (!_started) return; if (!_started) return;
for (auto i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
i.value()->restart();
}
}
void restart(int32 dcMask) {
if (!_started) return;
dcMask = bareDcId(dcMask);
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) { for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
if (bareDcId(i.value()->getDcWithShift()) == dcMask) {
i.value()->restart(); i.value()->restart();
} }
} }
}
void restart(int32 dcMask) { void pause() {
if (!_started) return;
dcMask %= _mtp_internal::dcShift;
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
if ((i.value()->getDcWithShift() % int(_mtp_internal::dcShift)) == dcMask) {
i.value()->restart();
}
}
}
void pause() {
if (!_started) return; if (!_started) return;
_paused = true; _paused = true;
} }
void unpause() { void unpause() {
if (!_started) return; if (!_started) return;
_paused = false; _paused = false;
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) { for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
i.value()->unpaused(); i.value()->unpaused();
} }
} }
void configure(int32 dc, int32 user) { void configure(int32 dc, int32 user) {
if (_started) return; if (_started) return;
mtpSetDC(dc); mtpSetDC(dc);
mtpAuthed(user); mtpAuthed(user);
} }
void setdc(int32 dc, bool fromZeroOnly) { void setdc(int32 dc, bool fromZeroOnly) {
if (!dc || !_started) return; if (!dc || !_started) return;
mtpSetDC(dc, fromZeroOnly); mtpSetDC(dc, fromZeroOnly);
int32 oldMainDc = mainSession->getDcWithShift(); int32 oldMainDc = mainSession->getDcWithShift();
@ -718,47 +713,47 @@ namespace MTP {
killSession(oldMainDc); killSession(oldMainDc);
} }
Local::writeMtpData(); Local::writeMtpData();
} }
int32 maindc() { int32 maindc() {
return mtpMainDC(); return mtpMainDC();
} }
int32 dcstate(int32 dc) { int32 dcstate(int32 dc) {
if (!_started) return 0; if (!_started) return 0;
if (!dc) return mainSession->getState(); if (!dc) return mainSession->getState();
if (!(dc % _mtp_internal::dcShift)) { if (!bareDcId(dc)) {
dc += (mainSession->getDcWithShift() % _mtp_internal::dcShift); dc += bareDcId(mainSession->getDcWithShift());
} }
Sessions::const_iterator i = sessions.constFind(dc); Sessions::const_iterator i = sessions.constFind(dc);
if (i != sessions.cend()) return i.value()->getState(); if (i != sessions.cend()) return i.value()->getState();
return MTProtoConnection::Disconnected; return DisconnectedState;
} }
QString dctransport(int32 dc) { QString dctransport(int32 dc) {
if (!_started) return QString(); if (!_started) return QString();
if (!dc) return mainSession->transport(); if (!dc) return mainSession->transport();
if (!(dc % _mtp_internal::dcShift)) { if (!bareDcId(dc)) {
dc += (mainSession->getDcWithShift() % _mtp_internal::dcShift); dc += bareDcId(mainSession->getDcWithShift());
} }
Sessions::const_iterator i = sessions.constFind(dc); Sessions::const_iterator i = sessions.constFind(dc);
if (i != sessions.cend()) return i.value()->transport(); if (i != sessions.cend()) return i.value()->transport();
return QString(); return QString();
} }
void ping() { void ping() {
if (MTProtoSession *session = _mtp_internal::getSession(0)) { if (internal::Session *session = internal::getSession(0)) {
session->ping(); session->ping();
} }
} }
void cancel(mtpRequestId requestId) { void cancel(mtpRequestId requestId) {
if (!_started) return; if (!_started) return;
mtpMsgId msgId = 0; mtpMsgId msgId = 0;
@ -775,16 +770,16 @@ namespace MTP {
QMutexLocker locker(&requestByDCLock); QMutexLocker locker(&requestByDCLock);
RequestsByDC::iterator i = requestsByDC.find(requestId); RequestsByDC::iterator i = requestsByDC.find(requestId);
if (i != requestsByDC.end()) { if (i != requestsByDC.end()) {
if (MTProtoSession *session = _mtp_internal::getSession(abs(i.value()))) { if (internal::Session *session = internal::getSession(qAbs(i.value()))) {
session->cancel(requestId, msgId); session->cancel(requestId, msgId);
} }
requestsByDC.erase(i); requestsByDC.erase(i);
} }
} }
_mtp_internal::clearCallbacks(requestId); internal::clearCallbacks(requestId);
} }
void killSession(int32 dc) { void killSession(int32 dc) {
Sessions::iterator i = sessions.find(dc); Sessions::iterator i = sessions.find(dc);
if (i != sessions.cend()) { if (i != sessions.cend()) {
bool wasMain = (i.value() == mainSession); bool wasMain = (i.value() == mainSession);
@ -794,7 +789,7 @@ namespace MTP {
sessions.erase(i); sessions.erase(i);
if (wasMain) { if (wasMain) {
mainSession = new MTProtoSession(mtpMainDC()); mainSession = new internal::Session(mtpMainDC());
int32 newdc = mainSession->getDcWithShift(); int32 newdc = mainSession->getDcWithShift();
i = sessions.find(newdc); i = sessions.find(newdc);
if (i != sessions.cend()) { if (i != sessions.cend()) {
@ -805,36 +800,36 @@ namespace MTP {
sessions.insert(newdc, mainSession); sessions.insert(newdc, mainSession);
} }
} }
} }
void stopSession(int32 dc) { void stopSession(int32 dc) {
Sessions::iterator i = sessions.find(dc); Sessions::iterator i = sessions.find(dc);
if (i != sessions.end()) { if (i != sessions.end()) {
if (i.value() != mainSession) { // don't stop main session if (i.value() != mainSession) { // don't stop main session
i.value()->stop(); i.value()->stop();
} }
} }
} }
int32 state(mtpRequestId requestId) { int32 state(mtpRequestId requestId) {
if (requestId > 0) { if (requestId > 0) {
QMutexLocker locker(&requestByDCLock); QMutexLocker locker(&requestByDCLock);
RequestsByDC::iterator i = requestsByDC.find(requestId); RequestsByDC::iterator i = requestsByDC.find(requestId);
if (i != requestsByDC.end()) { if (i != requestsByDC.end()) {
if (MTProtoSession *session = _mtp_internal::getSession(abs(i.value()))) { if (internal::Session *session = internal::getSession(qAbs(i.value()))) {
return session->requestState(requestId); return session->requestState(requestId);
} }
return MTP::RequestConnecting; return MTP::RequestConnecting;
} }
return MTP::RequestSent; return MTP::RequestSent;
} }
if (MTProtoSession *session = _mtp_internal::getSession(-requestId)) { if (internal::Session *session = internal::getSession(-requestId)) {
return session->requestState(0); return session->requestState(0);
} }
return MTP::RequestConnecting; return MTP::RequestConnecting;
} }
void finish() { void finish() {
for (Sessions::iterator i = sessions.begin(), e = sessions.end(); i != e; ++i) { for (Sessions::iterator i = sessions.begin(), e = sessions.end(); i != e; ++i) {
i.value()->kill(); i.value()->kill();
delete i.value(); delete i.value();
@ -854,59 +849,59 @@ namespace MTP {
mtpDestroyConfigLoader(); mtpDestroyConfigLoader();
_started = false; _started = false;
} }
void authed(int32 uid) { void authed(int32 uid) {
mtpAuthed(uid); mtpAuthed(uid);
} }
int32 authedId() { int32 authedId() {
return mtpAuthed(); return mtpAuthed();
} }
void logoutKeys(RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail) { void logoutKeys(RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail) {
mtpRequestId req = MTP::send(MTPauth_LogOut(), onDone, onFail); mtpRequestId req = MTP::send(MTPauth_LogOut(), onDone, onFail);
mtpLogoutOtherDCs(); mtpLogoutOtherDCs();
} }
void setGlobalDoneHandler(RPCDoneHandlerPtr handler) { void setGlobalDoneHandler(RPCDoneHandlerPtr handler) {
globalHandler.onDone = handler; globalHandler.onDone = handler;
} }
void setGlobalFailHandler(RPCFailHandlerPtr handler) { void setGlobalFailHandler(RPCFailHandlerPtr handler) {
globalHandler.onFail = handler; globalHandler.onFail = handler;
} }
void setStateChangedHandler(MTPStateChangedHandler handler) { void setStateChangedHandler(MTPStateChangedHandler handler) {
stateChangedHandler = handler; stateChangedHandler = handler;
} }
void setSessionResetHandler(MTPSessionResetHandler handler) { void setSessionResetHandler(MTPSessionResetHandler handler) {
sessionResetHandler = handler; sessionResetHandler = handler;
} }
void clearGlobalHandlers() { void clearGlobalHandlers() {
setGlobalDoneHandler(RPCDoneHandlerPtr()); setGlobalDoneHandler(RPCDoneHandlerPtr());
setGlobalFailHandler(RPCFailHandlerPtr()); setGlobalFailHandler(RPCFailHandlerPtr());
setStateChangedHandler(0); setStateChangedHandler(0);
setSessionResetHandler(0); setSessionResetHandler(0);
} }
void updateDcOptions(const QVector<MTPDcOption> &options) { void updateDcOptions(const QVector<MTPDcOption> &options) {
mtpUpdateDcOptions(options); mtpUpdateDcOptions(options);
Local::writeSettings(); Local::writeSettings();
} }
mtpKeysMap getKeys() { mtpKeysMap getKeys() {
return mtpGetKeys(); return mtpGetKeys();
} }
void setKey(int32 dc, mtpAuthKeyPtr key) { void setKey(int32 dc, mtpAuthKeyPtr key) {
return mtpSetKey(dc, key); return mtpSetKey(dc, key);
} }
QReadWriteLock *dcOptionsMutex() { QReadWriteLock *dcOptionsMutex() {
return mtpDcOptionsMutex(); return mtpDcOptionsMutex();
} }
}; } // namespace MTP

View File

@ -20,145 +20,191 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
#include "mtproto/core_types.h"
#include "mtproto/session.h" #include "mtproto/session.h"
#include "mtproto/file_download.h" #include "mtproto/file_download.h"
namespace _mtp_internal { namespace MTP {
MTProtoSession *getSession(int32 dc); // 0 - current set dc
bool paused(); namespace internal {
void registerRequest(mtpRequestId requestId, int32 dc); Session *getSession(ShiftedDcId shiftedDcId); // 0 - current set dc
void unregisterRequest(mtpRequestId requestId);
static const uint32 dcShift = 10000; bool paused();
mtpRequestId storeRequest(mtpRequest &request, const RPCResponseHandler &parser); void registerRequest(mtpRequestId requestId, int32 dc);
mtpRequest getRequest(mtpRequestId req); void unregisterRequest(mtpRequestId requestId);
void wrapInvokeAfter(mtpRequest &to, const mtpRequest &from, const mtpRequestMap &haveSent, int32 skipBeforeRequest = 0);
void clearCallbacks(mtpRequestId requestId, int32 errorCode = RPCError::NoError); // 0 - do not toggle onError callback mtpRequestId storeRequest(mtpRequest &request, const RPCResponseHandler &parser);
void clearCallbacksDelayed(const RPCCallbackClears &requestIds); mtpRequest getRequest(mtpRequestId req);
void performDelayedClear(); void wrapInvokeAfter(mtpRequest &to, const mtpRequest &from, const mtpRequestMap &haveSent, int32 skipBeforeRequest = 0);
void execCallback(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end); void clearCallbacks(mtpRequestId requestId, int32 errorCode = RPCError::NoError); // 0 - do not toggle onError callback
bool hasCallbacks(mtpRequestId requestId); void clearCallbacksDelayed(const RPCCallbackClears &requestIds);
void globalCallback(const mtpPrime *from, const mtpPrime *end); void performDelayedClear();
void onStateChange(int32 dcWithShift, int32 state); void execCallback(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end);
void onSessionReset(int32 dcWithShift); bool hasCallbacks(mtpRequestId requestId);
bool rpcErrorOccured(mtpRequestId requestId, const RPCFailHandlerPtr &onFail, const RPCError &err); // return true if need to clean request data void globalCallback(const mtpPrime *from, const mtpPrime *end);
inline bool rpcErrorOccured(mtpRequestId requestId, const RPCResponseHandler &handler, const RPCError &err) { void onStateChange(int32 dcWithShift, int32 state);
void onSessionReset(int32 dcWithShift);
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) {
return rpcErrorOccured(requestId, handler.onFail, err); return rpcErrorOccured(requestId, handler.onFail, err);
} }
// used for: // used for:
// - resending requests by timer which were postponed by flood delay // - resending requests by timer which were postponed by flood delay
// - destroying MTProtoConnections whose thread has finished // - destroying MTProtoConnections whose thread has finished
class GlobalSlotCarrier : public QObject { class GlobalSlotCarrier : public QObject {
Q_OBJECT Q_OBJECT
public: public:
GlobalSlotCarrier(); GlobalSlotCarrier();
public slots: public slots:
void checkDelayed(); void checkDelayed();
void connectionFinished(MTProtoConnection *connection); void connectionFinished(Connection *connection);
private: private:
SingleTimer _timer; SingleTimer _timer;
};
GlobalSlotCarrier *globalSlotCarrier();
void queueQuittingConnection(MTProtoConnection *connection);
}; };
namespace MTP { GlobalSlotCarrier *globalSlotCarrier();
void queueQuittingConnection(Connection *connection);
extern const uint32 cfg; // send(MTPhelp_GetConfig(), MTP::cfg + dc) - for dc enum } // namespace internal
extern const uint32 lgt; // send(MTPauth_LogOut(), MTP::lgt + dc) - for logout of guest dcs enum
inline uint32 dld(int32 index) { // send(req, callbacks, MTP::dld(i) + dc) - for download constexpr ShiftedDcId DCShift = 10000;
constexpr DcId bareDcId(ShiftedDcId shiftedDcId) {
return (shiftedDcId % DCShift);
}
constexpr ShiftedDcId shiftDcId(DcId dcId, int value) {
return dcId + DCShift * value;
}
constexpr int getDcIdShift(ShiftedDcId shiftedDcId) {
return (shiftedDcId - bareDcId(shiftedDcId)) / DCShift;
}
// send(MTPhelp_GetConfig(), MTP::cfgDcId(dc)) - for dc enumeration
constexpr ShiftedDcId cfgDcId(DcId dcId) {
return shiftDcId(dcId, 0x01);
}
// send(MTPauth_LogOut(), MTP::lgtDcId(dc)) - for logout of guest dcs enumeration
constexpr ShiftedDcId lgtDcId(DcId dcId) {
return shiftDcId(dcId, 0x02);
}
namespace internal {
constexpr ShiftedDcId downloadDcId(DcId dcId, int index) {
static_assert(MTPDownloadSessionsCount < 0x10, "Too large MTPDownloadSessionsCount!");
return shiftDcId(dcId, 0x10 + index);
};
}
// send(req, callbacks, MTP::dldDcId(dc, index)) - for download shifted dc id
inline ShiftedDcId dldDcId(DcId dcId, int index) {
t_assert(index >= 0 && index < MTPDownloadSessionsCount); t_assert(index >= 0 && index < MTPDownloadSessionsCount);
return (0x10 + index) * _mtp_internal::dcShift; return internal::downloadDcId(dcId, index);
}
constexpr bool isDldDcId(ShiftedDcId shiftedDcId) {
return (shiftedDcId >= internal::downloadDcId(0, 0)) && (shiftedDcId < internal::downloadDcId(0, MTPDownloadSessionsCount - 1) + DCShift);
}
namespace internal {
constexpr ShiftedDcId uploadDcId(DcId dcId, int index) {
static_assert(MTPUploadSessionsCount < 0x10, "Too large MTPUploadSessionsCount!");
return shiftDcId(dcId, 0x20 + index);
}; };
inline uint32 upl(int32 index) { // send(req, callbacks, MTP::upl(i) + dc) - for upload }
t_assert(index >= 0 && index < MTPUploadSessionsCount);
return (0x20 + index) * _mtp_internal::dcShift;
};
extern const uint32 dldStart, dldEnd; // dc >= dldStart && dc < dldEnd => dc in dld
extern const uint32 uplStart, uplEnd; // dc >= uplStart && dc < uplEnd => dc in upl
void start(); // send(req, callbacks, MTP::uplDcId(index)) - for upload shifted dc id
bool started(); // uploading always to the main dc so bareDcId == 0
void restart(); inline ShiftedDcId uplDcId(DcId dcId) {
void restart(int32 dcMask); return internal::uploadDcId(dcId, 0);
};
constexpr bool isUplDcId(ShiftedDcId shiftedDcId) {
return (shiftedDcId >= internal::uploadDcId(0, 0)) && (shiftedDcId < internal::uploadDcId(0, MTPUploadSessionsCount - 1) + DCShift);
}
void pause(); void start();
void unpause(); bool started();
void restart();
void restart(int32 dcMask);
void configure(int32 dc, int32 user); void pause();
void unpause();
void setdc(int32 dc, bool fromZeroOnly = false); void configure(int32 dc, int32 user);
int32 maindc();
int32 dcstate(int32 dc = 0); void setdc(int32 dc, bool fromZeroOnly = false);
QString dctransport(int32 dc = 0); int32 maindc();
template <typename TRequest> enum {
inline mtpRequestId send(const TRequest &request, RPCResponseHandler callbacks = RPCResponseHandler(), int32 dc = 0, uint64 msCanWait = 0, mtpRequestId after = 0) { DisconnectedState = 0,
if (MTProtoSession *session = _mtp_internal::getSession(dc)) { ConnectingState = 1,
ConnectedState = 2,
};
int32 dcstate(int32 dc = 0);
QString dctransport(int32 dc = 0);
template <typename TRequest>
inline mtpRequestId send(const TRequest &request, RPCResponseHandler callbacks = RPCResponseHandler(), int32 dc = 0, uint64 msCanWait = 0, mtpRequestId after = 0) {
if (internal::Session *session = internal::getSession(dc)) {
return session->send(request, callbacks, msCanWait, true, !dc, after); return session->send(request, callbacks, msCanWait, true, !dc, after);
} }
return 0; return 0;
} }
template <typename TRequest> template <typename TRequest>
inline mtpRequestId send(const TRequest &request, RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail = RPCFailHandlerPtr(), int32 dc = 0, uint64 msCanWait = 0, mtpRequestId after = 0) { inline mtpRequestId send(const TRequest &request, RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail = RPCFailHandlerPtr(), int32 dc = 0, uint64 msCanWait = 0, mtpRequestId after = 0) {
return send(request, RPCResponseHandler(onDone, onFail), dc, msCanWait, after); return send(request, RPCResponseHandler(onDone, onFail), dc, msCanWait, after);
} }
inline void sendAnything(int32 dc = 0, uint64 msCanWait = 0) { inline void sendAnything(int32 dc = 0, uint64 msCanWait = 0) {
if (MTProtoSession *session = _mtp_internal::getSession(dc)) { if (internal::Session *session = internal::getSession(dc)) {
return session->sendAnything(msCanWait); return session->sendAnything(msCanWait);
} }
} }
void ping(); void ping();
void cancel(mtpRequestId req); void cancel(mtpRequestId req);
void killSession(int32 dc); void killSession(int32 dc);
void stopSession(int32 dc); void stopSession(int32 dc);
enum { enum {
RequestSent = 0, RequestSent = 0,
RequestConnecting = 1, RequestConnecting = 1,
RequestSending = 2 RequestSending = 2
}; };
int32 state(mtpRequestId req); // < 0 means waiting for such count of ms int32 state(mtpRequestId req); // < 0 means waiting for such count of ms
void finish(); void finish();
void authed(int32 uid); void authed(int32 uid);
int32 authedId(); int32 authedId();
void logoutKeys(RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail); void logoutKeys(RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail);
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 setSessionResetHandler(MTPSessionResetHandler handler);
void clearGlobalHandlers(); void clearGlobalHandlers();
void updateDcOptions(const QVector<MTPDcOption> &options); void updateDcOptions(const QVector<MTPDcOption> &options);
template <typename T> template <typename T>
T nonce() { T nonce() {
T result; T result;
memset_rand(&result, sizeof(T)); memset_rand(&result, sizeof(T));
return result; return result;
} }
mtpKeysMap getKeys(); mtpKeysMap getKeys();
void setKey(int32 dc, mtpAuthKeyPtr key); void setKey(int32 dc, mtpAuthKeyPtr key);
QReadWriteLock *dcOptionsMutex(); QReadWriteLock *dcOptionsMutex();
struct DcOption { struct DcOption {
DcOption(int id, MTPDdcOption::Flags flags, const string &ip, int port) : id(id), flags(flags), ip(ip), port(port) { DcOption(int id, MTPDdcOption::Flags flags, const string &ip, int port) : id(id), flags(flags), ip(ip), port(port) {
} }
@ -166,13 +212,13 @@ namespace MTP {
MTPDdcOption::Flags flags; MTPDdcOption::Flags flags;
string ip; string ip;
int port; int port;
};
typedef QMap<int, DcOption> DcOptions;
}; };
typedef QMap<int, DcOption> DcOptions;
template <typename TRequest> namespace internal {
mtpRequestId MTProtoSession::send(const TRequest &request, RPCResponseHandler callbacks, uint64 msCanWait, bool needsLayer, bool toMainDC, mtpRequestId after) {
template <typename TRequest>
mtpRequestId Session::send(const TRequest &request, RPCResponseHandler callbacks, uint64 msCanWait, bool needsLayer, bool toMainDC, mtpRequestId after) {
mtpRequestId requestId = 0; mtpRequestId requestId = 0;
try { try {
uint32 requestSize = request.innerLength() >> 2; uint32 requestSize = request.innerLength() >> 2;
@ -183,14 +229,18 @@ mtpRequestId MTProtoSession::send(const TRequest &request, RPCResponseHandler ca
reqSerialized->msDate = getms(true); // > 0 - can send without container reqSerialized->msDate = getms(true); // > 0 - can send without container
reqSerialized->needsLayer = needsLayer; reqSerialized->needsLayer = needsLayer;
if (after) reqSerialized->after = _mtp_internal::getRequest(after); if (after) reqSerialized->after = MTP::internal::getRequest(after);
requestId = _mtp_internal::storeRequest(reqSerialized, callbacks); requestId = MTP::internal::storeRequest(reqSerialized, callbacks);
sendPrepared(reqSerialized, msCanWait); sendPrepared(reqSerialized, msCanWait);
} catch (Exception &e) { } catch (Exception &e) {
requestId = 0; requestId = 0;
_mtp_internal::rpcErrorOccured(requestId, callbacks, rpcClientError("NO_REQUEST_ID", QString("send() failed to queue request, exception: %1").arg(e.what()))); MTP::internal::rpcErrorOccured(requestId, callbacks, rpcClientError("NO_REQUEST_ID", QString("send() failed to queue request, exception: %1").arg(e.what())));
} }
if (requestId) _mtp_internal::registerRequest(requestId, toMainDC ? -getDcWithShift() : getDcWithShift()); if (requestId) MTP::internal::registerRequest(requestId, toMainDC ? -getDcWithShift() : getDcWithShift());
return requestId; return requestId;
} }
} // namespace internal
} // namespace MTP

View File

@ -352,9 +352,9 @@ mtpFileLoader::mtpFileLoader(const StorageImageLocation *location, int32 size, L
, _location(location) , _location(location)
, _id(0) , _id(0)
, _access(0) { , _access(0) {
LoaderQueues::iterator i = queues.find(MTP::dld(0) + _dc); LoaderQueues::iterator i = queues.find(MTP::dldDcId(_dc, 0));
if (i == queues.cend()) { if (i == queues.cend()) {
i = queues.insert(MTP::dld(0) + _dc, FileLoaderQueue(MaxFileQueries)); i = queues.insert(MTP::dldDcId(_dc, 0), FileLoaderQueue(MaxFileQueries));
} }
_queue = &i.value(); _queue = &i.value();
} }
@ -368,9 +368,9 @@ mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, L
, _location(0) , _location(0)
, _id(id) , _id(id)
, _access(access) { , _access(access) {
LoaderQueues::iterator i = queues.find(MTP::dld(0) + _dc); LoaderQueues::iterator i = queues.find(MTP::dldDcId(_dc, 0));
if (i == queues.cend()) { if (i == queues.cend()) {
i = queues.insert(MTP::dld(0) + _dc, FileLoaderQueue(MaxFileQueries)); i = queues.insert(MTP::dldDcId(_dc, 0), FileLoaderQueue(MaxFileQueries));
} }
_queue = &i.value(); _queue = &i.value();
} }
@ -432,7 +432,7 @@ bool mtpFileLoader::loadPart() {
App::app()->killDownloadSessionsStop(_dc); App::app()->killDownloadSessionsStop(_dc);
mtpRequestId reqId = MTP::send(MTPupload_GetFile(MTPupload_getFile(loc, MTP_int(offset), MTP_int(limit))), rpcDone(&mtpFileLoader::partLoaded, offset), rpcFail(&mtpFileLoader::partFailed), MTP::dld(dcIndex) + _dc, 50); mtpRequestId reqId = MTP::send(MTPupload_GetFile(MTPupload_getFile(loc, MTP_int(offset), MTP_int(limit))), rpcDone(&mtpFileLoader::partLoaded, offset), rpcFail(&mtpFileLoader::partFailed), MTP::dldDcId(_dc, dcIndex), 50);
++_queue->queries; ++_queue->queries;
dr.v[dcIndex] += limit; dr.v[dcIndex] += limit;

View File

@ -22,7 +22,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "mtproto/session.h" #include "mtproto/session.h"
void MTPSessionData::clear() { namespace MTP {
namespace internal {
void SessionData::clear() {
RPCCallbackClears clearCallbacks; RPCCallbackClears clearCallbacks;
{ {
QReadLocker locker1(haveSentMutex()), locker2(toResendMutex()), locker3(haveReceivedMutex()), locker4(wereAckedMutex()); QReadLocker locker1(haveSentMutex()), locker2(toResendMutex()), locker3(haveReceivedMutex()), locker4(wereAckedMutex());
@ -63,11 +66,11 @@ void MTPSessionData::clear() {
QWriteLocker locker(receivedIdsMutex()); QWriteLocker locker(receivedIdsMutex());
receivedIds.clear(); receivedIds.clear();
} }
_mtp_internal::clearCallbacksDelayed(clearCallbacks); clearCallbacksDelayed(clearCallbacks);
} }
MTProtoSession::MTProtoSession(int32 dcenter) : QObject() Session::Session(int32 dcenter) : QObject()
, _connection(0) , _connection(0)
, _killed(false) , _killed(false)
, _needToReceive(false) , _needToReceive(false)
@ -95,7 +98,7 @@ MTProtoSession::MTProtoSession(int32 dcenter) : QObject()
MTProtoDCMap &dcs(mtpDCMap()); MTProtoDCMap &dcs(mtpDCMap());
_connection = new MTProtoConnection(); _connection = new Connection();
dcWithShift = _connection->start(&data, dcenter); dcWithShift = _connection->start(&data, dcenter);
if (!dcWithShift) { if (!dcWithShift) {
delete _connection; delete _connection;
@ -105,11 +108,11 @@ MTProtoSession::MTProtoSession(int32 dcenter) : QObject()
} }
if (!dc) { if (!dc) {
dcenter = dcWithShift; dcenter = dcWithShift;
int32 dcId = dcWithShift % _mtp_internal::dcShift; int32 dcId = bareDcId(dcWithShift);
MTProtoDCMap::const_iterator dcIndex = dcs.constFind(dcId); MTProtoDCMap::const_iterator dcIndex = dcs.constFind(dcId);
if (dcIndex == dcs.cend()) { if (dcIndex == dcs.cend()) {
dc = MTProtoDCPtr(new MTProtoDC(dcId, mtpAuthKeyPtr())); dc = MTProtoDCPtr(new MTProtoDC(dcId, mtpAuthKeyPtr()));
dcs.insert(dcWithShift % _mtp_internal::dcShift, dc); dcs.insert(dcId, dc);
} else { } else {
dc = dcIndex.value(); dc = dcIndex.value();
} }
@ -124,7 +127,7 @@ MTProtoSession::MTProtoSession(int32 dcenter) : QObject()
} }
} }
void MTProtoSession::restart() { void Session::restart() {
if (_killed) { if (_killed) {
DEBUG_LOG(("Session Error: can't restart a killed session")); DEBUG_LOG(("Session Error: can't restart a killed session"));
return; return;
@ -132,7 +135,7 @@ void MTProtoSession::restart() {
emit needToRestart(); emit needToRestart();
} }
void MTProtoSession::stop() { void Session::stop() {
if (_killed) { if (_killed) {
DEBUG_LOG(("Session Error: can't kill a killed session")); DEBUG_LOG(("Session Error: can't kill a killed session"));
return; return;
@ -144,20 +147,20 @@ void MTProtoSession::stop() {
} }
} }
void MTProtoSession::kill() { void Session::kill() {
stop(); stop();
_killed = true; _killed = true;
DEBUG_LOG(("Session Info: marked session dcWithShift %1 as killed").arg(dcWithShift)); DEBUG_LOG(("Session Info: marked session dcWithShift %1 as killed").arg(dcWithShift));
} }
void MTProtoSession::unpaused() { void Session::unpaused() {
if (_needToReceive) { if (_needToReceive) {
_needToReceive = false; _needToReceive = false;
QTimer::singleShot(0, this, SLOT(tryToReceive())); QTimer::singleShot(0, this, SLOT(tryToReceive()));
} }
} }
void MTProtoSession::sendAnything(quint64 msCanWait) { void Session::sendAnything(quint64 msCanWait) {
if (_killed) { if (_killed) {
DEBUG_LOG(("Session Error: can't send anything in a killed session")); DEBUG_LOG(("Session Error: can't send anything in a killed session"));
return; return;
@ -187,7 +190,7 @@ void MTProtoSession::sendAnything(quint64 msCanWait) {
} }
} }
void MTProtoSession::needToResumeAndSend() { void Session::needToResumeAndSend() {
if (_killed) { if (_killed) {
DEBUG_LOG(("Session Info: can't resume a killed session")); DEBUG_LOG(("Session Info: can't resume a killed session"));
return; return;
@ -196,7 +199,7 @@ void MTProtoSession::needToResumeAndSend() {
DEBUG_LOG(("Session Info: resuming session dcWithShift %1").arg(dcWithShift)); DEBUG_LOG(("Session Info: resuming session dcWithShift %1").arg(dcWithShift));
MTProtoDCMap &dcs(mtpDCMap()); MTProtoDCMap &dcs(mtpDCMap());
_connection = new MTProtoConnection(); _connection = new Connection();
if (!_connection->start(&data, dcWithShift)) { if (!_connection->start(&data, dcWithShift)) {
delete _connection; delete _connection;
_connection = 0; _connection = 0;
@ -213,11 +216,11 @@ void MTProtoSession::needToResumeAndSend() {
} }
} }
void MTProtoSession::sendPong(quint64 msgId, quint64 pingId) { void Session::sendPong(quint64 msgId, quint64 pingId) {
send(MTP_pong(MTP_long(msgId), MTP_long(pingId))); send(MTP_pong(MTP_long(msgId), MTP_long(pingId)));
} }
void MTProtoSession::sendMsgsStateInfo(quint64 msgId, QByteArray data) { void Session::sendMsgsStateInfo(quint64 msgId, QByteArray data) {
MTPMsgsStateInfo req(MTP_msgs_state_info(MTP_long(msgId), MTPstring())); MTPMsgsStateInfo req(MTP_msgs_state_info(MTP_long(msgId), MTPstring()));
string &info(req._msgs_state_info().vinfo._string().v); string &info(req._msgs_state_info().vinfo._string().v);
info.resize(data.size()); info.resize(data.size());
@ -227,7 +230,7 @@ void MTProtoSession::sendMsgsStateInfo(quint64 msgId, QByteArray data) {
send(req); send(req);
} }
void MTProtoSession::checkRequestsByTimer() { void Session::checkRequestsByTimer() {
QVector<mtpMsgId> resendingIds; QVector<mtpMsgId> resendingIds;
QVector<mtpMsgId> removingIds; // remove very old (10 minutes) containers and resend requests QVector<mtpMsgId> removingIds; // remove very old (10 minutes) containers and resend requests
QVector<mtpMsgId> stateRequestIds; QVector<mtpMsgId> stateRequestIds;
@ -288,19 +291,19 @@ void MTProtoSession::checkRequestsByTimer() {
} }
} }
} }
_mtp_internal::clearCallbacksDelayed(clearCallbacks); clearCallbacksDelayed(clearCallbacks);
} }
} }
void MTProtoSession::onConnectionStateChange(qint32 newState) { void Session::onConnectionStateChange(qint32 newState) {
_mtp_internal::onStateChange(dcWithShift, newState); onStateChange(dcWithShift, newState);
} }
void MTProtoSession::onResetDone() { void Session::onResetDone() {
_mtp_internal::onSessionReset(dcWithShift); onSessionReset(dcWithShift);
} }
void MTProtoSession::cancel(mtpRequestId requestId, mtpMsgId msgId) { void Session::cancel(mtpRequestId requestId, mtpMsgId msgId) {
if (requestId) { if (requestId) {
QWriteLocker locker(data.toSendMutex()); QWriteLocker locker(data.toSendMutex());
data.toSendMap().remove(requestId); data.toSendMap().remove(requestId);
@ -311,20 +314,20 @@ void MTProtoSession::cancel(mtpRequestId requestId, mtpMsgId msgId) {
} }
} }
void MTProtoSession::ping() { void Session::ping() {
_ping = true; _ping = true;
sendAnything(0); sendAnything(0);
} }
int32 MTProtoSession::requestState(mtpRequestId requestId) const { int32 Session::requestState(mtpRequestId requestId) const {
int32 result = MTP::RequestSent; int32 result = MTP::RequestSent;
bool connected = false; bool connected = false;
if (_connection) { if (_connection) {
int32 s = _connection->state(); int32 s = _connection->state();
if (s == MTProtoConnection::Connected) { if (s == ConnectedState) {
connected = true; connected = true;
} else if (s == MTProtoConnection::Connecting || s == MTProtoConnection::Disconnected) { } else if (s == ConnectingState || s == DisconnectedState) {
if (result < 0 || result == MTP::RequestSent) { if (result < 0 || result == MTP::RequestSent) {
result = MTP::RequestConnecting; result = MTP::RequestConnecting;
} }
@ -349,14 +352,14 @@ int32 MTProtoSession::requestState(mtpRequestId requestId) const {
} }
} }
int32 MTProtoSession::getState() const { int32 Session::getState() const {
int32 result = -86400000; int32 result = -86400000;
if (_connection) { if (_connection) {
int32 s = _connection->state(); int32 s = _connection->state();
if (s == MTProtoConnection::Connected) { if (s == ConnectedState) {
return s; return s;
} else if (s == MTProtoConnection::Connecting || s == MTProtoConnection::Disconnected) { } else if (s == ConnectingState || s == DisconnectedState) {
if (result < 0) { if (result < 0) {
return s; return s;
} }
@ -367,16 +370,16 @@ int32 MTProtoSession::getState() const {
} }
} }
if (result == -86400000) { if (result == -86400000) {
result = MTProtoConnection::Disconnected; result = DisconnectedState;
} }
return result; return result;
} }
QString MTProtoSession::transport() const { QString Session::transport() const {
return _connection ? _connection->transport() : QString(); return _connection ? _connection->transport() : QString();
} }
mtpRequestId MTProtoSession::resend(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) { mtpRequestId Session::resend(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
mtpRequest request; mtpRequest request;
{ {
QWriteLocker locker(data.haveSentMutex()); QWriteLocker locker(data.haveSentMutex());
@ -416,13 +419,13 @@ mtpRequestId MTProtoSession::resend(quint64 msgId, quint64 msCanWait, bool force
} }
} }
void MTProtoSession::resendMany(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) { void Session::resendMany(QVector<quint64> msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) {
for (int32 i = 0, l = msgIds.size(); i < l; ++i) { for (int32 i = 0, l = msgIds.size(); i < l; ++i) {
resend(msgIds.at(i), msCanWait, forceContainer, sendMsgStateInfo); resend(msgIds.at(i), msCanWait, forceContainer, sendMsgStateInfo);
} }
} }
void MTProtoSession::resendAll() { void Session::resendAll() {
QVector<mtpMsgId> toResend; QVector<mtpMsgId> toResend;
{ {
QReadLocker locker(data.haveSentMutex()); QReadLocker locker(data.haveSentMutex());
@ -437,7 +440,7 @@ void MTProtoSession::resendAll() {
} }
} }
void MTProtoSession::sendPrepared(const mtpRequest &request, uint64 msCanWait, bool newRequest) { // returns true, if emit of needToSend() is needed void Session::sendPrepared(const mtpRequest &request, uint64 msCanWait, bool newRequest) { // returns true, if emit of needToSend() is needed
{ {
QWriteLocker locker(data.toSendMutex()); QWriteLocker locker(data.toSendMutex());
data.toSendMap().insert(request->requestId, request); data.toSendMap().insert(request->requestId, request);
@ -453,33 +456,33 @@ void MTProtoSession::sendPrepared(const mtpRequest &request, uint64 msCanWait, b
sendAnything(msCanWait); sendAnything(msCanWait);
} }
QReadWriteLock *MTProtoSession::keyMutex() const { QReadWriteLock *Session::keyMutex() const {
return dc->keyMutex(); return dc->keyMutex();
} }
void MTProtoSession::authKeyCreatedForDC() { void Session::authKeyCreatedForDC() {
DEBUG_LOG(("AuthKey Info: MTProtoSession::authKeyCreatedForDC slot, emitting authKeyCreated(), dcWithShift %1").arg(dcWithShift)); DEBUG_LOG(("AuthKey Info: MTProtoSession::authKeyCreatedForDC slot, emitting authKeyCreated(), dcWithShift %1").arg(dcWithShift));
data.setKey(dc->getKey()); data.setKey(dc->getKey());
emit authKeyCreated(); emit authKeyCreated();
} }
void MTProtoSession::notifyKeyCreated(const mtpAuthKeyPtr &key) { void Session::notifyKeyCreated(const mtpAuthKeyPtr &key) {
DEBUG_LOG(("AuthKey Info: MTProtoSession::keyCreated(), setting, dcWithShift %1").arg(dcWithShift)); DEBUG_LOG(("AuthKey Info: MTProtoSession::keyCreated(), setting, dcWithShift %1").arg(dcWithShift));
dc->setKey(key); dc->setKey(key);
} }
void MTProtoSession::layerWasInitedForDC(bool wasInited) { void Session::layerWasInitedForDC(bool wasInited) {
DEBUG_LOG(("MTP Info: MTProtoSession::layerWasInitedForDC slot, dcWithShift %1").arg(dcWithShift)); DEBUG_LOG(("MTP Info: MTProtoSession::layerWasInitedForDC slot, dcWithShift %1").arg(dcWithShift));
data.setLayerWasInited(wasInited); data.setLayerWasInited(wasInited);
} }
void MTProtoSession::notifyLayerInited(bool wasInited) { void Session::notifyLayerInited(bool wasInited) {
DEBUG_LOG(("MTP Info: emitting MTProtoDC::layerWasInited(%1), dcWithShift %2").arg(Logs::b(wasInited)).arg(dcWithShift)); DEBUG_LOG(("MTP Info: emitting MTProtoDC::layerWasInited(%1), dcWithShift %2").arg(Logs::b(wasInited)).arg(dcWithShift));
dc->setConnectionInited(wasInited); dc->setConnectionInited(wasInited);
emit dc->layerWasInited(wasInited); emit dc->layerWasInited(wasInited);
} }
void MTProtoSession::destroyKey() { void Session::destroyKey() {
if (!dc) return; if (!dc) return;
if (data.getKey()) { if (data.getKey()) {
@ -491,16 +494,16 @@ void MTProtoSession::destroyKey() {
} }
} }
int32 MTProtoSession::getDcWithShift() const { int32 Session::getDcWithShift() const {
return dcWithShift; return dcWithShift;
} }
void MTProtoSession::tryToReceive() { void Session::tryToReceive() {
if (_killed) { if (_killed) {
DEBUG_LOG(("Session Error: can't receive in a killed session")); DEBUG_LOG(("Session Error: can't receive in a killed session"));
return; return;
} }
if (_mtp_internal::paused()) { if (paused()) {
_needToReceive = true; _needToReceive = true;
return; return;
} }
@ -519,20 +522,23 @@ void MTProtoSession::tryToReceive() {
responses.erase(i); responses.erase(i);
} }
if (requestId <= 0) { if (requestId <= 0) {
if (dcWithShift < int(_mtp_internal::dcShift)) { // call globalCallback only in main session if (dcWithShift == bareDcId(dcWithShift)) { // call globalCallback only in main session
_mtp_internal::globalCallback(response.constData(), response.constData() + response.size()); globalCallback(response.constData(), response.constData() + response.size());
} }
} else { } else {
_mtp_internal::execCallback(requestId, response.constData(), response.constData() + response.size()); execCallback(requestId, response.constData(), response.constData() + response.size());
} }
++cnt; ++cnt;
} }
} }
MTProtoSession::~MTProtoSession() { Session::~Session() {
t_assert(_connection == 0); t_assert(_connection == 0);
} }
MTPrpcError rpcClientError(const QString &type, const QString &description) { MTPrpcError rpcClientError(const QString &type, const QString &description) {
return MTP_rpc_error(MTP_int(0), MTP_string(("CLIENT_" + type + (description.length() ? (": " + description) : "")).toUtf8().constData())); return MTP_rpc_error(MTP_int(0), MTP_string(("CLIENT_" + type + (description.length() ? (": " + description) : "")).toUtf8().constData()));
} }
} // namespace internal
} // namespace MTP

View File

@ -24,15 +24,22 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "mtproto/dcenter.h" #include "mtproto/dcenter.h"
#include "mtproto/rpc_sender.h" #include "mtproto/rpc_sender.h"
class MTProtoSession; namespace MTP {
namespace internal {
class MTPSessionData { class Session;
class SessionData {
public: public:
MTPSessionData(MTProtoSession *creator) SessionData(Session *creator)
: _session(0), _salt(0) : _session(0)
, _messagesSent(0), _fakeRequestId(-2000000000) , _salt(0)
, _owner(creator), _keyChecked(false), _layerInited(false) { , _messagesSent(0)
, _fakeRequestId(-2000000000)
, _owner(creator)
, _keyChecked(false)
, _layerInited(false) {
} }
void setSession(uint64 session) { void setSession(uint64 session) {
@ -170,10 +177,10 @@ public:
return _fakeRequestId; return _fakeRequestId;
} }
MTProtoSession *owner() { Session *owner() {
return _owner; return _owner;
} }
const MTProtoSession *owner() const { const Session *owner() const {
return _owner; return _owner;
} }
@ -192,7 +199,7 @@ private:
uint32 _messagesSent; uint32 _messagesSent;
mtpRequestId _fakeRequestId; mtpRequestId _fakeRequestId;
MTProtoSession *_owner; Session *_owner;
mtpAuthKeyPtr _authKey; mtpAuthKeyPtr _authKey;
bool _keyChecked, _layerInited; bool _keyChecked, _layerInited;
@ -217,12 +224,12 @@ private:
}; };
class MTProtoSession : public QObject { class Session : public QObject {
Q_OBJECT Q_OBJECT
public: public:
MTProtoSession(int32 dcenter); Session(int32 dcenter);
void restart(); void restart();
void stop(); void stop();
@ -231,7 +238,7 @@ public:
void unpaused(); void unpaused();
int32 getDcWithShift() const; int32 getDcWithShift() const;
~MTProtoSession(); ~Session();
QReadWriteLock *keyMutex() const; QReadWriteLock *keyMutex() const;
void notifyKeyCreated(const mtpAuthKeyPtr &key); void notifyKeyCreated(const mtpAuthKeyPtr &key);
@ -278,12 +285,12 @@ public slots:
private: private:
MTProtoConnection *_connection; Connection *_connection;
bool _killed; bool _killed;
bool _needToReceive; bool _needToReceive;
MTPSessionData data; SessionData data;
int32 dcWithShift; int32 dcWithShift;
MTProtoDCPtr dc; MTProtoDCPtr dc;
@ -297,8 +304,11 @@ private:
}; };
inline QReadWriteLock *MTPSessionData::keyMutex() const { inline QReadWriteLock *SessionData::keyMutex() const {
return _owner->keyMutex(); return _owner->keyMutex();
} }
MTPrpcError rpcClientError(const QString &type, const QString &description = QString()); MTPrpcError rpcClientError(const QString &type, const QString &description = QString());
} // namespace internal
} // namespace MTP

View File

@ -18,6 +18,9 @@ to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
#define NOMINMAX // no min() and max() macro declarations
#ifdef TDESKTOP_WINRT #ifdef TDESKTOP_WINRT
#include <wrl.h> #include <wrl.h>

View File

@ -765,7 +765,7 @@ void Window::mtpStateChanged(int32 dc, int32 state) {
void Window::updateTitleStatus() { void Window::updateTitleStatus() {
int32 state = MTP::dcstate(); int32 state = MTP::dcstate();
if (state == MTProtoConnection::Connecting || state == MTProtoConnection::Disconnected || (state < 0 && state > -600)) { if (state == MTP::ConnectingState || state == MTP::DisconnectedState || (state < 0 && state > -600)) {
if (main || getms() > 5000 || _connecting) { if (main || getms() > 5000 || _connecting) {
showConnecting(lang(lng_connecting)); showConnecting(lang(lng_connecting));
} }