mirror of https://github.com/procxx/kepka.git
improved bad_msg_notification handle and local time shifts
This commit is contained in:
parent
22e1a7b730
commit
0e031f042d
|
@ -95,7 +95,7 @@ namespace App {
|
||||||
return w ? w->mainWidget() : 0;
|
return w ? w->mainWidget() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings *settings() {
|
SettingsWidget *settings() {
|
||||||
Window *w(wnd());
|
Window *w(wnd());
|
||||||
return w ? w->settingsWidget() : 0;
|
return w ? w->settingsWidget() : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||||
class Application;
|
class Application;
|
||||||
class Window;
|
class Window;
|
||||||
class MainWidget;
|
class MainWidget;
|
||||||
class Settings;
|
class SettingsWidget;
|
||||||
class Font;
|
class Font;
|
||||||
class Color;
|
class Color;
|
||||||
class FileUploader;
|
class FileUploader;
|
||||||
|
@ -38,7 +38,7 @@ namespace App {
|
||||||
Application *app();
|
Application *app();
|
||||||
Window *wnd();
|
Window *wnd();
|
||||||
MainWidget *main();
|
MainWidget *main();
|
||||||
Settings *settings();
|
SettingsWidget *settings();
|
||||||
FileUploader *uploader();
|
FileUploader *uploader();
|
||||||
|
|
||||||
void showSettings();
|
void showSettings();
|
||||||
|
|
|
@ -230,6 +230,7 @@ bool StorageImage::check() const {
|
||||||
h = data.height();
|
h = data.height();
|
||||||
invalidateSizeCache();
|
invalidateSizeCache();
|
||||||
loader->deleteLater();
|
loader->deleteLater();
|
||||||
|
loader->rpcInvalidate();
|
||||||
loader = 0;
|
loader = 0;
|
||||||
|
|
||||||
saved = bytes;
|
saved = bytes;
|
||||||
|
@ -256,6 +257,7 @@ void StorageImage::setData(QByteArray &bytes, const QByteArray &format) {
|
||||||
invalidateSizeCache();
|
invalidateSizeCache();
|
||||||
if (loader) {
|
if (loader) {
|
||||||
loader->deleteLater();
|
loader->deleteLater();
|
||||||
|
loader->rpcInvalidate();
|
||||||
loader = 0;
|
loader = 0;
|
||||||
}
|
}
|
||||||
this->saved = bytes;
|
this->saved = bytes;
|
||||||
|
@ -269,6 +271,7 @@ StorageImage::~StorageImage() {
|
||||||
}
|
}
|
||||||
if (loader) {
|
if (loader) {
|
||||||
loader->deleteLater();
|
loader->deleteLater();
|
||||||
|
loader->rpcInvalidate();
|
||||||
loader = 0;
|
loader = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,6 +227,7 @@ struct VideoData {
|
||||||
if (l) {
|
if (l) {
|
||||||
l->cancel();
|
l->cancel();
|
||||||
l->deleteLater();
|
l->deleteLater();
|
||||||
|
l->rpcInvalidate();
|
||||||
}
|
}
|
||||||
fileName = QString();
|
fileName = QString();
|
||||||
modDate = QDateTime();
|
modDate = QDateTime();
|
||||||
|
@ -241,6 +242,7 @@ struct VideoData {
|
||||||
modDate = fileName.isEmpty() ? QDateTime() : QFileInfo(fileName).lastModified();
|
modDate = fileName.isEmpty() ? QDateTime() : QFileInfo(fileName).lastModified();
|
||||||
}
|
}
|
||||||
loader->deleteLater();
|
loader->deleteLater();
|
||||||
|
loader->rpcInvalidate();
|
||||||
loader = 0;
|
loader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,6 +330,7 @@ struct AudioData {
|
||||||
if (l) {
|
if (l) {
|
||||||
l->cancel();
|
l->cancel();
|
||||||
l->deleteLater();
|
l->deleteLater();
|
||||||
|
l->rpcInvalidate();
|
||||||
}
|
}
|
||||||
fileName = QString();
|
fileName = QString();
|
||||||
modDate = QDateTime();
|
modDate = QDateTime();
|
||||||
|
@ -342,6 +345,7 @@ struct AudioData {
|
||||||
modDate = fileName.isEmpty() ? QDateTime() : QFileInfo(fileName).lastModified();
|
modDate = fileName.isEmpty() ? QDateTime() : QFileInfo(fileName).lastModified();
|
||||||
}
|
}
|
||||||
loader->deleteLater();
|
loader->deleteLater();
|
||||||
|
loader->rpcInvalidate();
|
||||||
loader = 0;
|
loader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,6 +431,7 @@ struct DocumentData {
|
||||||
if (l) {
|
if (l) {
|
||||||
l->cancel();
|
l->cancel();
|
||||||
l->deleteLater();
|
l->deleteLater();
|
||||||
|
l->rpcInvalidate();
|
||||||
}
|
}
|
||||||
fileName = QString();
|
fileName = QString();
|
||||||
modDate = QDateTime();
|
modDate = QDateTime();
|
||||||
|
@ -441,6 +446,7 @@ struct DocumentData {
|
||||||
modDate = fileName.isEmpty() ? QDateTime() : QFileInfo(fileName).lastModified();
|
modDate = fileName.isEmpty() ? QDateTime() : QFileInfo(fileName).lastModified();
|
||||||
}
|
}
|
||||||
loader->deleteLater();
|
loader->deleteLater();
|
||||||
|
loader->rpcInvalidate();
|
||||||
loader = 0;
|
loader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -288,6 +288,12 @@ void IntroWidget::keyPressEvent(QKeyEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntroWidget::rpcInvalidate() {
|
||||||
|
if (phone) phone->rpcInvalidate();
|
||||||
|
if (code) code->rpcInvalidate();
|
||||||
|
if (signup) signup->rpcInvalidate();
|
||||||
|
}
|
||||||
|
|
||||||
IntroWidget::~IntroWidget() {
|
IntroWidget::~IntroWidget() {
|
||||||
delete steps;
|
delete steps;
|
||||||
delete phone;
|
delete phone;
|
||||||
|
|
|
@ -57,6 +57,8 @@ public:
|
||||||
|
|
||||||
void finish(const MTPUser &user, const QImage &photo = QImage());
|
void finish(const MTPUser &user, const QImage &photo = QImage());
|
||||||
|
|
||||||
|
void rpcInvalidate();
|
||||||
|
|
||||||
~IntroWidget();
|
~IntroWidget();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -756,7 +756,10 @@ void MainWidget::showPeer(const PeerId &peerId, MsgId msgId, bool back, bool for
|
||||||
history.showPeer(peerId, msgId, force);
|
history.showPeer(peerId, msgId, force);
|
||||||
if (force || !selectingPeer()) {
|
if (force || !selectingPeer()) {
|
||||||
if (profile) {
|
if (profile) {
|
||||||
if (profile) profile->deleteLater();
|
if (profile) {
|
||||||
|
profile->deleteLater();
|
||||||
|
profile->rpcInvalidate();
|
||||||
|
}
|
||||||
profile = 0;
|
profile = 0;
|
||||||
profileStack.clear();
|
profileStack.clear();
|
||||||
if (!history.peer() || !history.peer()->id) {
|
if (!history.peer() || !history.peer()->id) {
|
||||||
|
@ -811,7 +814,10 @@ void MainWidget::showPeerProfile(const PeerData *peer, bool back) {
|
||||||
profileStack.push_back(history.peer());
|
profileStack.push_back(history.peer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (profile) profile->deleteLater();
|
if (profile) {
|
||||||
|
profile->deleteLater();
|
||||||
|
profile->rpcInvalidate();
|
||||||
|
}
|
||||||
profile = new ProfileWidget(this, peer);
|
profile = new ProfileWidget(this, peer);
|
||||||
_topBar.show();
|
_topBar.show();
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
|
|
|
@ -1034,7 +1034,8 @@ void MTProtoConnectionPrivate::createConn() {
|
||||||
MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConnection *owner, MTPSessionData *data, uint32 _dc)
|
MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConnection *owner, MTPSessionData *data, uint32 _dc)
|
||||||
: QObject(0)
|
: QObject(0)
|
||||||
, _state(MTProtoConnection::Disconnected)
|
, _state(MTProtoConnection::Disconnected)
|
||||||
, dc(_dc)
|
, _needSessionReset(false)
|
||||||
|
, dc(_dc)
|
||||||
, _owner(owner)
|
, _owner(owner)
|
||||||
, conn(0)
|
, conn(0)
|
||||||
, retryTimeout(1)
|
, retryTimeout(1)
|
||||||
|
@ -1137,7 +1138,118 @@ bool MTProtoConnectionPrivate::setState(int32 state, int32 ifState) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtpMsgId MTProtoConnectionPrivate::prepareToSend(mtpRequest &request) {
|
void MTProtoConnectionPrivate::resetSession() { // recreate all msg_id and msg_seqno
|
||||||
|
_needSessionReset = false;
|
||||||
|
|
||||||
|
QWriteLocker locker1(sessionData->haveSentMutex());
|
||||||
|
QWriteLocker locker2(sessionData->toResendMutex());
|
||||||
|
QWriteLocker locker3(sessionData->toSendMutex());
|
||||||
|
QWriteLocker locker4(sessionData->wereAckedMutex());
|
||||||
|
mtpRequestMap &haveSent(sessionData->haveSentMap());
|
||||||
|
mtpRequestIdsMap &toResend(sessionData->toResendMap());
|
||||||
|
mtpPreRequestMap &toSend(sessionData->toSendMap());
|
||||||
|
mtpRequestIdsMap &wereAcked(sessionData->wereAckedMap());
|
||||||
|
|
||||||
|
mtpMsgId newId = msgid();
|
||||||
|
mtpRequestMap setSeqNumbers;
|
||||||
|
typedef QMap<mtpMsgId, mtpMsgId> Replaces;
|
||||||
|
Replaces replaces;
|
||||||
|
for (mtpRequestMap::const_iterator i = haveSent.cbegin(), e = haveSent.cend(); i != e; ++i) {
|
||||||
|
if (!mtpRequestData::isSentContainer(i.value())) {
|
||||||
|
if (!*(mtpMsgId*)(i.value()->constData() + 4)) continue;
|
||||||
|
|
||||||
|
mtpMsgId id = i.key();
|
||||||
|
if (id > newId) {
|
||||||
|
while (true) {
|
||||||
|
if (toResend.constFind(newId) == toResend.cend() && wereAcked.constFind(newId) == wereAcked.cend() && haveSent.constFind(newId) == haveSent.cend()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mtpMsgId m = msgid();
|
||||||
|
if (m <= newId) break; // wtf
|
||||||
|
|
||||||
|
newId = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTP_LOG(dc, ("Replacing msgId %1 to %2!").arg(id).arg(newId));
|
||||||
|
replaces.insert(id, newId);
|
||||||
|
id = newId;
|
||||||
|
*(mtpMsgId*)(i.value()->data() + 4) = id;
|
||||||
|
}
|
||||||
|
setSeqNumbers.insert(id, i.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (mtpRequestIdsMap::const_iterator i = toResend.cbegin(), e = toResend.cend(); i != e; ++i) { // collect all non-container requests
|
||||||
|
mtpPreRequestMap::const_iterator j = toSend.constFind(i.value());
|
||||||
|
if (j == toSend.cend()) continue;
|
||||||
|
|
||||||
|
if (!mtpRequestData::isSentContainer(j.value())) {
|
||||||
|
if (!*(mtpMsgId*)(j.value()->constData() + 4)) continue;
|
||||||
|
|
||||||
|
mtpMsgId id = i.key();
|
||||||
|
if (id > newId) {
|
||||||
|
while (true) {
|
||||||
|
if (toResend.constFind(newId) == toResend.cend() && wereAcked.constFind(newId) == wereAcked.cend() && haveSent.constFind(newId) == haveSent.cend()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mtpMsgId m = msgid();
|
||||||
|
if (m <= newId) break; // wtf
|
||||||
|
|
||||||
|
newId = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTP_LOG(dc, ("Replacing msgId %1 to %2!").arg(id).arg(newId));
|
||||||
|
replaces.insert(id, newId);
|
||||||
|
id = newId;
|
||||||
|
*(mtpMsgId*)(j.value()->data() + 4) = id;
|
||||||
|
}
|
||||||
|
setSeqNumbers.insert(id, j.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 session = MTP::nonce<uint64>();
|
||||||
|
DEBUG_LOG(("MTP Info: creating new session after bad_msg_notification, setting random server_session %1").arg(session));
|
||||||
|
sessionData->setSession(session);
|
||||||
|
|
||||||
|
for (mtpRequestMap::const_iterator i = setSeqNumbers.cbegin(), e = setSeqNumbers.cend(); i != e; ++i) { // generate new seq_numbers
|
||||||
|
bool wasNeedAck = (*(i.value()->data() + 6) & 1);
|
||||||
|
*(i.value()->data() + 6) = sessionData->nextRequestSeqNumber(wasNeedAck);
|
||||||
|
}
|
||||||
|
if (!replaces.isEmpty()) {
|
||||||
|
for (Replaces::const_iterator i = replaces.cbegin(), e = replaces.cend(); i != e; ++i) { // replace msgIds keys in all data structs
|
||||||
|
mtpRequestMap::iterator j = haveSent.find(i.key());
|
||||||
|
if (j != haveSent.cend()) {
|
||||||
|
mtpRequest req = j.value();
|
||||||
|
haveSent.erase(j);
|
||||||
|
haveSent.insert(i.value(), req);
|
||||||
|
}
|
||||||
|
mtpRequestIdsMap::iterator k = toResend.find(i.key());
|
||||||
|
if (k != toResend.cend()) {
|
||||||
|
mtpRequestId req = k.value();
|
||||||
|
toResend.erase(k);
|
||||||
|
toResend.insert(i.value(), req);
|
||||||
|
}
|
||||||
|
k = wereAcked.find(i.key());
|
||||||
|
if (k != wereAcked.cend()) {
|
||||||
|
mtpRequestId req = k.value();
|
||||||
|
wereAcked.erase(k);
|
||||||
|
wereAcked.insert(i.value(), req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (mtpRequestMap::const_iterator i = haveSent.cbegin(), e = haveSent.cend(); i != e; ++i) { // replace msgIds in saved containers
|
||||||
|
if (mtpRequestData::isSentContainer(i.value())) {
|
||||||
|
mtpMsgId *ids = (mtpMsgId *)(i.value()->data() + 8);
|
||||||
|
for (uint32 j = 0, l = (i.value()->size() - 8) >> 1; j < l; ++j) {
|
||||||
|
Replaces::const_iterator k = replaces.constFind(ids[j]);
|
||||||
|
if (k != replaces.cend()) {
|
||||||
|
ids[j] = k.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mtpMsgId MTProtoConnectionPrivate::prepareToSend(mtpRequest &request, mtpMsgId currentLastId) {
|
||||||
if (request->size() < 9) return 0;
|
if (request->size() < 9) return 0;
|
||||||
mtpMsgId msgId = *(mtpMsgId*)(request->constData() + 4);
|
mtpMsgId msgId = *(mtpMsgId*)(request->constData() + 4);
|
||||||
if (msgId) { // resending this request
|
if (msgId) { // resending this request
|
||||||
|
@ -1148,12 +1260,75 @@ mtpMsgId MTProtoConnectionPrivate::prepareToSend(mtpRequest &request) {
|
||||||
toResend.erase(i);
|
toResend.erase(i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msgId = *(mtpMsgId*)(request->data() + 4) = msgid();
|
msgId = *(mtpMsgId*)(request->data() + 4) = currentLastId;
|
||||||
*(request->data() + 6) = sessionData->nextRequestSeqNumber(mtpRequestData::needAck(request));
|
*(request->data() + 6) = sessionData->nextRequestSeqNumber(mtpRequestData::needAck(request));
|
||||||
}
|
}
|
||||||
return msgId;
|
return msgId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mtpMsgId MTProtoConnectionPrivate::replaceMsgId(mtpRequest &request, mtpMsgId newId) {
|
||||||
|
if (request->size() < 9) return 0;
|
||||||
|
|
||||||
|
mtpMsgId oldMsgId = *(mtpMsgId*)(request->constData() + 4);
|
||||||
|
if (oldMsgId != newId) {
|
||||||
|
if (oldMsgId) {
|
||||||
|
QWriteLocker locker(sessionData->toResendMutex());
|
||||||
|
// haveSentMutex() and wereAckedMutex() were locked in tryToSend()
|
||||||
|
|
||||||
|
mtpRequestIdsMap &toResend(sessionData->toResendMap());
|
||||||
|
mtpRequestIdsMap &wereAcked(sessionData->wereAckedMap());
|
||||||
|
mtpRequestMap &haveSent(sessionData->haveSentMap());
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (toResend.constFind(newId) == toResend.cend() && wereAcked.constFind(newId) == wereAcked.cend() && haveSent.constFind(newId) == haveSent.cend()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mtpMsgId m = msgid();
|
||||||
|
if (m <= newId) break; // wtf
|
||||||
|
|
||||||
|
newId = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
mtpRequestIdsMap::iterator i = toResend.find(oldMsgId);
|
||||||
|
if (i != toResend.cend()) {
|
||||||
|
mtpRequestId req = i.value();
|
||||||
|
toResend.erase(i);
|
||||||
|
toResend.insert(newId, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
mtpRequestIdsMap::iterator j = wereAcked.find(oldMsgId);
|
||||||
|
if (j != wereAcked.cend()) {
|
||||||
|
mtpRequestId req = j.value();
|
||||||
|
wereAcked.erase(j);
|
||||||
|
wereAcked.insert(newId, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
mtpRequestMap::iterator k = haveSent.find(oldMsgId);
|
||||||
|
if (k != haveSent.cend()) {
|
||||||
|
mtpRequest req = k.value();
|
||||||
|
haveSent.erase(k);
|
||||||
|
haveSent.insert(newId, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = haveSent.begin(); k != haveSent.cend(); ++k) {
|
||||||
|
mtpRequest req(k.value());
|
||||||
|
if (mtpRequestData::isSentContainer(req)) {
|
||||||
|
mtpMsgId *ids = (mtpMsgId *)(req->data() + 8);
|
||||||
|
for (uint32 i = 0, l = (req->size() - 8) >> 1; i < l; ++i) {
|
||||||
|
if (ids[i] == oldMsgId) {
|
||||||
|
ids[i] = newId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*(request->data() + 6) = sessionData->nextRequestSeqNumber(mtpRequestData::needAck(request));
|
||||||
|
}
|
||||||
|
*(mtpMsgId*)(request->data() + 4) = newId;
|
||||||
|
}
|
||||||
|
return newId;
|
||||||
|
}
|
||||||
|
|
||||||
void MTProtoConnectionPrivate::tryToSend() {
|
void MTProtoConnectionPrivate::tryToSend() {
|
||||||
if (!conn) return;
|
if (!conn) return;
|
||||||
|
|
||||||
|
@ -1211,7 +1386,7 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||||
locker1.unlock();
|
locker1.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
mtpMsgId msgId = prepareToSend(toSendRequest);
|
mtpMsgId msgId = prepareToSend(toSendRequest, msgid());
|
||||||
if (havePrepend) pingMsgId = msgId;
|
if (havePrepend) pingMsgId = msgId;
|
||||||
|
|
||||||
if (toSendRequest->requestId) {
|
if (toSendRequest->requestId) {
|
||||||
|
@ -1237,10 +1412,12 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||||
toSendRequest->push_back(mtpc_msg_container);
|
toSendRequest->push_back(mtpc_msg_container);
|
||||||
toSendRequest->push_back(toSendCount);
|
toSendRequest->push_back(toSendCount);
|
||||||
|
|
||||||
QWriteLocker locker2(sessionData->haveSentMutex());
|
mtpMsgId bigMsgId = msgid(); // check for a valid container
|
||||||
|
|
||||||
|
QWriteLocker locker2(sessionData->haveSentMutex()); // the fact of this lock is used in replaceMsgId()
|
||||||
mtpRequestMap &haveSent(sessionData->haveSentMap());
|
mtpRequestMap &haveSent(sessionData->haveSentMap());
|
||||||
|
|
||||||
QWriteLocker locker3(sessionData->wereAckedMutex());
|
QWriteLocker locker3(sessionData->wereAckedMutex()); // the fact of this lock is used in replaceMsgId()
|
||||||
mtpRequestIdsMap &wereAcked(sessionData->wereAckedMap());
|
mtpRequestIdsMap &wereAcked(sessionData->wereAckedMap());
|
||||||
|
|
||||||
mtpRequest haveSentIdsWrap(mtpRequestData::prepare(idsWrapSize)); // prepare "request-like" wrap for msgId vector
|
mtpRequest haveSentIdsWrap(mtpRequestData::prepare(idsWrapSize)); // prepare "request-like" wrap for msgId vector
|
||||||
|
@ -1249,7 +1426,9 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||||
mtpMsgId *haveSentArr = (mtpMsgId*)(haveSentIdsWrap->data() + 8);
|
mtpMsgId *haveSentArr = (mtpMsgId*)(haveSentIdsWrap->data() + 8);
|
||||||
|
|
||||||
if (havePrepend) {
|
if (havePrepend) {
|
||||||
mtpMsgId msgId = prepareToSend(prepend);
|
mtpMsgId msgId = prepareToSend(prepend, bigMsgId);
|
||||||
|
if (msgId > bigMsgId) msgId = replaceMsgId(prepend, bigMsgId);
|
||||||
|
if (msgId >= bigMsgId) bigMsgId = msgid();
|
||||||
*(haveSentArr++) = msgId;
|
*(haveSentArr++) = msgId;
|
||||||
if (havePrepend) pingMsgId = msgId;
|
if (havePrepend) pingMsgId = msgId;
|
||||||
|
|
||||||
|
@ -1261,8 +1440,10 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||||
}
|
}
|
||||||
for (mtpPreRequestMap::iterator i = toSend.begin(), e = toSend.end(); i != e; ++i) {
|
for (mtpPreRequestMap::iterator i = toSend.begin(), e = toSend.end(); i != e; ++i) {
|
||||||
mtpRequest &req(i.value());
|
mtpRequest &req(i.value());
|
||||||
mtpMsgId msgId = prepareToSend(req);
|
mtpMsgId msgId = prepareToSend(req, bigMsgId);
|
||||||
*(haveSentArr++) = msgId;
|
if (msgId > bigMsgId) msgId = replaceMsgId(req, bigMsgId);
|
||||||
|
if (msgId >= bigMsgId) bigMsgId = msgid();
|
||||||
|
*(haveSentArr++) = msgId;
|
||||||
|
|
||||||
if (req->requestId) {
|
if (req->requestId) {
|
||||||
if (mtpRequestData::needAck(req)) {
|
if (mtpRequestData::needAck(req)) {
|
||||||
|
@ -1279,7 +1460,7 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||||
memcpy(toSendRequest->data() + from, req->constData() + 4, len * sizeof(mtpPrime));
|
memcpy(toSendRequest->data() + from, req->constData() + 4, len * sizeof(mtpPrime));
|
||||||
}
|
}
|
||||||
|
|
||||||
mtpMsgId contMsgId = prepareToSend(toSendRequest);
|
mtpMsgId contMsgId = prepareToSend(toSendRequest, bigMsgId);
|
||||||
*(mtpMsgId*)(haveSentIdsWrap->data() + 4) = contMsgId;
|
*(mtpMsgId*)(haveSentIdsWrap->data() + 4) = contMsgId;
|
||||||
(*haveSentIdsWrap)[6] = 0; // for container, msDate = 0, seqNo = 0
|
(*haveSentIdsWrap)[6] = 0; // for container, msDate = 0, seqNo = 0
|
||||||
haveSent.insert(contMsgId, haveSentIdsWrap);
|
haveSent.insert(contMsgId, haveSentIdsWrap);
|
||||||
|
@ -1372,6 +1553,9 @@ void MTProtoConnectionPrivate::restart(bool maybeBadKey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
doDisconnect();
|
doDisconnect();
|
||||||
|
if (_needSessionReset) {
|
||||||
|
resetSession();
|
||||||
|
}
|
||||||
restarted = true;
|
restarted = true;
|
||||||
if (retryTimer.isActive()) return;
|
if (retryTimer.isActive()) return;
|
||||||
|
|
||||||
|
@ -1564,7 +1748,9 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||||
int32 res = 1; // if no need to handle, then succeed
|
int32 res = 1; // if no need to handle, then succeed
|
||||||
end = data + 8 + (msgLen >> 2);
|
end = data + 8 + (msgLen >> 2);
|
||||||
const mtpPrime *sfrom(data + 4);
|
const mtpPrime *sfrom(data + 4);
|
||||||
MTP_LOG(dc, ("Recv: ") + mtpTextSerialize(sfrom, end, mtpc_core_message));
|
if (cDebug()) {
|
||||||
|
MTP_LOG(dc, ("Recv: ") + mtpTextSerialize(sfrom, end, mtpc_core_message));
|
||||||
|
}
|
||||||
|
|
||||||
bool needToHandle = false;
|
bool needToHandle = false;
|
||||||
{
|
{
|
||||||
|
@ -1606,6 +1792,7 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
_needSessionReset = (res < -1);
|
||||||
return restart();
|
return restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1714,29 +1901,71 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt
|
||||||
const MTPDbad_msg_notification &data(msg.c_bad_msg_notification());
|
const MTPDbad_msg_notification &data(msg.c_bad_msg_notification());
|
||||||
LOG(("Message Info: bad message notification received (error_code %3) for msg_id = %1, seq_no = %2").arg(data.vbad_msg_id.v).arg(data.vbad_msg_seqno.v).arg(data.verror_code.v));
|
LOG(("Message Info: bad message notification received (error_code %3) for msg_id = %1, seq_no = %2").arg(data.vbad_msg_id.v).arg(data.vbad_msg_seqno.v).arg(data.verror_code.v));
|
||||||
|
|
||||||
bool needResend = (data.verror_code.v == 16 || data.verror_code.v == 17); // bad msg_id
|
int32 errorCode = data.verror_code.v;
|
||||||
|
if (errorCode == 16 || errorCode == 17 || errorCode == 32 || errorCode == 33 || errorCode == 64) { // can handle
|
||||||
mtpMsgId resendId = data.vbad_msg_id.v;
|
bool needResend = (errorCode == 16 || errorCode == 17); // bad msg_id
|
||||||
if (!wasSent(resendId)) {
|
if (errorCode == 64) { // bad container!
|
||||||
DEBUG_LOG(("Message Error: such message was not sent recently %1").arg(resendId));
|
needResend = true;
|
||||||
return (badTime ? 0 : 1);
|
if (cDebug()) {
|
||||||
}
|
mtpRequest request;
|
||||||
|
{
|
||||||
|
QWriteLocker locker(sessionData->haveSentMutex());
|
||||||
|
mtpRequestMap &haveSent(sessionData->haveSentMap());
|
||||||
|
|
||||||
if (needResend) { // bad msg_id
|
mtpRequestMap::iterator i = haveSent.find(msgId);
|
||||||
if (serverSalt) sessionData->setSalt(serverSalt);
|
if (i == haveSent.end()) {
|
||||||
unixtimeSet(serverTime, true);
|
LOG(("Message Error: Container not found!"));
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_LOG(("Message Info: unixtime updated, now %1, resending in container..").arg(serverTime));
|
request = i.value();
|
||||||
|
}
|
||||||
resend(resendId, 0, true);
|
if (request) {
|
||||||
} else {
|
if (mtpRequestData::isSentContainer(request)) {
|
||||||
if (badTime) {
|
QStringList lst;
|
||||||
if (serverSalt) sessionData->setSalt(serverSalt);
|
const mtpMsgId *ids = (const mtpMsgId *)(request->constData() + 8);
|
||||||
unixtimeSet(serverTime);
|
for (uint32 i = 0, l = (request->size() - 8) >> 1; i < l; ++i) {
|
||||||
badTime = false;
|
lst.push_back(QString::number(ids[i]));
|
||||||
|
}
|
||||||
|
LOG(("Message Info: bad container received! messages: %1").arg(lst.join(',')));
|
||||||
|
} else {
|
||||||
|
LOG(("Message Error: bad container received, but request is not a container!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LOG(("Message Error: bad message notification received, msgId %1, error_code %2").arg(data.vbad_msg_id.v).arg(data.verror_code.v));
|
|
||||||
return -1;
|
mtpMsgId resendId = data.vbad_msg_id.v;
|
||||||
|
if (!wasSent(resendId)) {
|
||||||
|
DEBUG_LOG(("Message Error: such message was not sent recently %1").arg(resendId));
|
||||||
|
return (badTime ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needResend) { // bad msg_id
|
||||||
|
if (serverSalt) sessionData->setSalt(serverSalt);
|
||||||
|
unixtimeSet(serverTime, true);
|
||||||
|
|
||||||
|
DEBUG_LOG(("Message Info: unixtime updated, now %1, resending in container..").arg(serverTime));
|
||||||
|
|
||||||
|
resend(resendId, 0, true);
|
||||||
|
} else { // must create new session, because msg_id and msg_seqno are inconsistent
|
||||||
|
if (badTime) {
|
||||||
|
if (serverSalt) sessionData->setSalt(serverSalt);
|
||||||
|
unixtimeSet(serverTime);
|
||||||
|
badTime = false;
|
||||||
|
}
|
||||||
|
LOG(("Message Info: bad message notification received, msgId %1, error_code %2").arg(data.vbad_msg_id.v).arg(errorCode));
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
} else { // fatal (except 48, but it must not get here)
|
||||||
|
mtpMsgId resendId = data.vbad_msg_id.v;
|
||||||
|
mtpRequestId requestId = wasSent(resendId);
|
||||||
|
if (requestId) {
|
||||||
|
LOG(("Message Error: bad message notification received, msgId %1, error_code %2, fatal: clearing callbacks").arg(data.vbad_msg_id.v).arg(errorCode));
|
||||||
|
_mtp_internal::clearCallbacksDelayed(RPCCallbackClears(1, RPCCallbackClear(requestId, -errorCode)));
|
||||||
|
} else {
|
||||||
|
DEBUG_LOG(("Message Error: such message was not sent recently %1").arg(resendId));
|
||||||
|
}
|
||||||
|
return (badTime ? 0 : 1);
|
||||||
}
|
}
|
||||||
} return 1;
|
} return 1;
|
||||||
|
|
||||||
|
@ -1855,8 +2084,13 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const mtpPrime *rFrom = requestBuffer->constData() + 8, *rEnd = requestBuffer->constData() + requestBuffer->size();
|
const mtpPrime *rFrom = requestBuffer->constData() + 8, *rEnd = requestBuffer->constData() + requestBuffer->size();
|
||||||
MTPMsgsStateReq request(rFrom, rEnd);
|
if (*rFrom == mtpc_msgs_state_req) {
|
||||||
handleMsgsStates(request.c_msgs_state_req().vmsg_ids.c_vector().v, states, toAck);
|
MTPMsgsStateReq request(rFrom, rEnd);
|
||||||
|
handleMsgsStates(request.c_msgs_state_req().vmsg_ids.c_vector().v, states, toAck);
|
||||||
|
} else {
|
||||||
|
MTPMsgResendReq request(rFrom, rEnd);
|
||||||
|
handleMsgsStates(request.c_msg_resend_req().vmsg_ids.c_vector().v, states, toAck);
|
||||||
|
}
|
||||||
} catch(Exception &e) {
|
} catch(Exception &e) {
|
||||||
LOG(("Message Error: could not parse sent msgs_state_req"));
|
LOG(("Message Error: could not parse sent msgs_state_req"));
|
||||||
throw;
|
throw;
|
||||||
|
@ -2280,7 +2514,6 @@ mtpRequestId MTProtoConnectionPrivate::resend(mtpMsgId msgId, uint64 msCanWait,
|
||||||
return sessionData->owner()->resend(msgId, msCanWait, forceContainer, sendMsgStateInfo);
|
return sessionData->owner()->resend(msgId, msCanWait, forceContainer, sendMsgStateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MTProtoConnectionPrivate::onConnected() {
|
void MTProtoConnectionPrivate::onConnected() {
|
||||||
disconnect(conn, SIGNAL(connected()), this, SLOT(onConnected()));
|
disconnect(conn, SIGNAL(connected()), this, SLOT(onConnected()));
|
||||||
if (!conn->isConnected()) {
|
if (!conn->isConnected()) {
|
||||||
|
@ -2874,7 +3107,9 @@ bool MTProtoConnectionPrivate::sendRequest(mtpRequest &request, bool needAnyResp
|
||||||
memcpy(request->data() + 2, &session, 2 * sizeof(mtpPrime));
|
memcpy(request->data() + 2, &session, 2 * sizeof(mtpPrime));
|
||||||
|
|
||||||
const mtpPrime *from = request->constData() + 4;
|
const mtpPrime *from = request->constData() + 4;
|
||||||
MTP_LOG(dc, ("Send: ") + mtpTextSerialize(from, from + messageSize, mtpc_core_message));
|
if (cDebug()) {
|
||||||
|
MTP_LOG(dc, ("Send: ") + mtpTextSerialize(from, from + messageSize, mtpc_core_message));
|
||||||
|
}
|
||||||
|
|
||||||
uchar encryptedSHA[20];
|
uchar encryptedSHA[20];
|
||||||
MTPint128 &msgKey(*(MTPint128*)(encryptedSHA + 4));
|
MTPint128 &msgKey(*(MTPint128*)(encryptedSHA + 4));
|
||||||
|
|
|
@ -332,7 +332,8 @@ private:
|
||||||
|
|
||||||
void createConn();
|
void createConn();
|
||||||
|
|
||||||
mtpMsgId prepareToSend(mtpRequest &request);
|
mtpMsgId prepareToSend(mtpRequest &request, mtpMsgId currentLastId);
|
||||||
|
mtpMsgId replaceMsgId(mtpRequest &request, mtpMsgId newId);
|
||||||
|
|
||||||
bool sendRequest(mtpRequest &request, bool needAnyResponse);
|
bool sendRequest(mtpRequest &request, bool needAnyResponse);
|
||||||
mtpRequestId wasSent(mtpMsgId msgId) const;
|
mtpRequestId wasSent(mtpMsgId msgId) const;
|
||||||
|
@ -347,6 +348,9 @@ private:
|
||||||
mutable QReadWriteLock stateMutex;
|
mutable QReadWriteLock stateMutex;
|
||||||
int32 _state;
|
int32 _state;
|
||||||
|
|
||||||
|
bool _needSessionReset;
|
||||||
|
void resetSession();
|
||||||
|
|
||||||
uint32 dc;
|
uint32 dc;
|
||||||
MTProtoConnection *_owner;
|
MTProtoConnection *_owner;
|
||||||
MTPabstractConnection *conn;
|
MTPabstractConnection *conn;
|
||||||
|
|
|
@ -19,17 +19,17 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||||
#include "mtproto/mtpRPC.h"
|
#include "mtproto/mtpRPC.h"
|
||||||
|
|
||||||
RPCOwnedDoneHandler::RPCOwnedDoneHandler(RPCSender *owner) : _owner(owner) {
|
RPCOwnedDoneHandler::RPCOwnedDoneHandler(RPCSender *owner) : _owner(owner) {
|
||||||
_owner->regHandler(this);
|
_owner->_rpcRegHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
RPCOwnedDoneHandler::~RPCOwnedDoneHandler() {
|
RPCOwnedDoneHandler::~RPCOwnedDoneHandler() {
|
||||||
if (_owner) _owner->unregHandler(this);
|
if (_owner) _owner->_rpcUnregHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
RPCOwnedFailHandler::RPCOwnedFailHandler(RPCSender *owner) : _owner(owner) {
|
RPCOwnedFailHandler::RPCOwnedFailHandler(RPCSender *owner) : _owner(owner) {
|
||||||
_owner->regHandler(this);
|
_owner->_rpcRegHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
RPCOwnedFailHandler::~RPCOwnedFailHandler() {
|
RPCOwnedFailHandler::~RPCOwnedFailHandler() {
|
||||||
if (_owner) _owner->unregHandler(this);
|
if (_owner) _owner->_rpcUnregHandler(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -654,9 +654,28 @@ private:
|
||||||
|
|
||||||
class RPCSender {
|
class RPCSender {
|
||||||
typedef QSet<RPCOwnedDoneHandler*> DoneHandlers;
|
typedef QSet<RPCOwnedDoneHandler*> DoneHandlers;
|
||||||
DoneHandlers doneHandlers;
|
DoneHandlers _rpcDoneHandlers;
|
||||||
typedef QSet<RPCOwnedFailHandler*> FailHandlers;
|
typedef QSet<RPCOwnedFailHandler*> FailHandlers;
|
||||||
FailHandlers failHandlers;
|
FailHandlers _rpcFailHandlers;
|
||||||
|
|
||||||
|
void _rpcRegHandler(RPCOwnedDoneHandler *handler) {
|
||||||
|
_rpcDoneHandlers.insert(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _rpcUnregHandler(RPCOwnedDoneHandler *handler) {
|
||||||
|
_rpcDoneHandlers.remove(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _rpcRegHandler(RPCOwnedFailHandler *handler) {
|
||||||
|
_rpcFailHandlers.insert(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _rpcUnregHandler(RPCOwnedFailHandler *handler) {
|
||||||
|
_rpcFailHandlers.remove(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class RPCOwnedDoneHandler;
|
||||||
|
friend class RPCOwnedFailHandler;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -760,29 +779,19 @@ public:
|
||||||
return RPCFailHandlerPtr(new RPCBindedFailHandlerOwnedNo<T, TReceiver>(b, static_cast<TReceiver*>(this), onFail));
|
return RPCFailHandlerPtr(new RPCBindedFailHandlerOwnedNo<T, TReceiver>(b, static_cast<TReceiver*>(this), onFail));
|
||||||
}
|
}
|
||||||
|
|
||||||
void regHandler(RPCOwnedDoneHandler *handler) {
|
void rpcInvalidate() {
|
||||||
doneHandlers.insert(handler);
|
for (DoneHandlers::iterator i = _rpcDoneHandlers.begin(), e = _rpcDoneHandlers.end(); i != e; ++i) {
|
||||||
}
|
(*i)->invalidate();
|
||||||
|
}
|
||||||
void unregHandler(RPCOwnedDoneHandler *handler) {
|
_rpcDoneHandlers.clear();
|
||||||
doneHandlers.remove(handler);
|
for (FailHandlers::iterator i = _rpcFailHandlers.begin(), e = _rpcFailHandlers.end(); i != e; ++i) {
|
||||||
}
|
(*i)->invalidate();
|
||||||
|
}
|
||||||
void regHandler(RPCOwnedFailHandler *handler) {
|
_rpcFailHandlers.clear();
|
||||||
failHandlers.insert(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unregHandler(RPCOwnedFailHandler *handler) {
|
|
||||||
failHandlers.remove(handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~RPCSender() {
|
~RPCSender() {
|
||||||
for (DoneHandlers::iterator i = doneHandlers.begin(), e = doneHandlers.end(); i != e; ++i) {
|
rpcInvalidate();
|
||||||
(*i)->invalidate();
|
|
||||||
}
|
|
||||||
for (FailHandlers::iterator i = failHandlers.begin(), e = failHandlers.end(); i != e; ++i) {
|
|
||||||
(*i)->invalidate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -61,8 +61,7 @@ public:
|
||||||
void setKey(const mtpAuthKeyPtr &key) {
|
void setKey(const mtpAuthKeyPtr &key) {
|
||||||
if (authKey != key) {
|
if (authKey != key) {
|
||||||
uint64 session;
|
uint64 session;
|
||||||
memset_rand(&session, sizeof(uint64));
|
memsetrnd(session);
|
||||||
|
|
||||||
authKey = key;
|
authKey = key;
|
||||||
|
|
||||||
DEBUG_LOG(("MTP Info: new auth key set in SessionData, id %1, setting random server_session %2").arg(key ? key->keyId() : 0).arg(session));
|
DEBUG_LOG(("MTP Info: new auth key set in SessionData, id %1, setting random server_session %2").arg(key ? key->keyId() : 0).arg(session));
|
||||||
|
|
|
@ -95,7 +95,7 @@ bool scaleIs(DBIScale scale) {
|
||||||
return cRealScale() == scale || (cRealScale() == dbisAuto && cScreenScale() == scale);
|
return cRealScale() == scale || (cRealScale() == dbisAuto && cScreenScale() == scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsInner::SettingsInner(Settings *parent) : QWidget(parent),
|
SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||||
_self(App::self()),
|
_self(App::self()),
|
||||||
|
|
||||||
// profile
|
// profile
|
||||||
|
@ -1126,7 +1126,7 @@ void SettingsInner::onPhotoUpdateDone(PeerId peer) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::Settings(Window *parent) : QWidget(parent),
|
SettingsWidget::SettingsWidget(Window *parent) : QWidget(parent),
|
||||||
_scroll(this, st::setScroll), _inner(this), _close(this, st::setClose) {
|
_scroll(this, st::setScroll), _inner(this), _close(this, st::setClose) {
|
||||||
_scroll.setWidget(&_inner);
|
_scroll.setWidget(&_inner);
|
||||||
|
|
||||||
|
@ -1138,11 +1138,11 @@ Settings::Settings(Window *parent) : QWidget(parent),
|
||||||
showAll();
|
showAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::onParentResize(const QSize &newSize) {
|
void SettingsWidget::onParentResize(const QSize &newSize) {
|
||||||
resize(newSize);
|
resize(newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::animShow(const QPixmap &bgAnimCache, bool back) {
|
void SettingsWidget::animShow(const QPixmap &bgAnimCache, bool back) {
|
||||||
_bgAnimCache = bgAnimCache;
|
_bgAnimCache = bgAnimCache;
|
||||||
|
|
||||||
anim::stop(this);
|
anim::stop(this);
|
||||||
|
@ -1159,7 +1159,7 @@ void Settings::animShow(const QPixmap &bgAnimCache, bool back) {
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::animStep(float64 ms) {
|
bool SettingsWidget::animStep(float64 ms) {
|
||||||
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration;
|
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration;
|
||||||
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
|
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
|
||||||
bool res = true;
|
bool res = true;
|
||||||
|
@ -1184,7 +1184,7 @@ bool Settings::animStep(float64 ms) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::paintEvent(QPaintEvent *e) {
|
void SettingsWidget::paintEvent(QPaintEvent *e) {
|
||||||
QRect r(e->rect());
|
QRect r(e->rect());
|
||||||
bool trivial = (rect() == r);
|
bool trivial = (rect() == r);
|
||||||
|
|
||||||
|
@ -1202,32 +1202,32 @@ void Settings::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::showAll() {
|
void SettingsWidget::showAll() {
|
||||||
_scroll.show();
|
_scroll.show();
|
||||||
_inner.show();
|
_inner.show();
|
||||||
_inner.showAll();
|
_inner.showAll();
|
||||||
_close.show();
|
_close.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::hideAll() {
|
void SettingsWidget::hideAll() {
|
||||||
_scroll.hide();
|
_scroll.hide();
|
||||||
_close.hide();
|
_close.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::resizeEvent(QResizeEvent *e) {
|
void SettingsWidget::resizeEvent(QResizeEvent *e) {
|
||||||
_scroll.resize(size());
|
_scroll.resize(size());
|
||||||
_inner.updateSize(width());
|
_inner.updateSize(width());
|
||||||
_close.move(st::setClosePos.x(), st::setClosePos.y());
|
_close.move(st::setClosePos.x(), st::setClosePos.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::dragEnterEvent(QDragEnterEvent *e) {
|
void SettingsWidget::dragEnterEvent(QDragEnterEvent *e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::dropEvent(QDropEvent *e) {
|
void SettingsWidget::dropEvent(QDropEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::getPhotoCoords(PhotoData *photo, int32 &x, int32 &y, int32 &w) const {
|
bool SettingsWidget::getPhotoCoords(PhotoData *photo, int32 &x, int32 &y, int32 &w) const {
|
||||||
if (_inner.getPhotoCoords(photo, x, y, w)) {
|
if (_inner.getPhotoCoords(photo, x, y, w)) {
|
||||||
x += _inner.x();
|
x += _inner.x();
|
||||||
y += _inner.y();
|
y += _inner.y();
|
||||||
|
@ -1236,14 +1236,18 @@ bool Settings::getPhotoCoords(PhotoData *photo, int32 &x, int32 &y, int32 &w) co
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::updateOnlineDisplay() {
|
void SettingsWidget::updateOnlineDisplay() {
|
||||||
_inner.updateOnlineDisplay();
|
_inner.updateOnlineDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::updateConnectionType() {
|
void SettingsWidget::updateConnectionType() {
|
||||||
_inner.updateConnectionType();
|
_inner.updateConnectionType();
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::~Settings() {
|
void SettingsWidget::rpcInvalidate() {
|
||||||
|
_inner.rpcInvalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsWidget::~SettingsWidget() {
|
||||||
if (App::wnd()) App::wnd()->noSettings(this);
|
if (App::wnd()) App::wnd()->noSettings(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class SettingsInner : public QWidget, public RPCSender, public Animated {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SettingsInner(Settings *parent);
|
SettingsInner(SettingsWidget *parent);
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e);
|
||||||
void resizeEvent(QResizeEvent *e);
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
@ -218,12 +218,12 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Settings : public QWidget, public Animated {
|
class SettingsWidget : public QWidget, public Animated {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Settings(Window *parent);
|
SettingsWidget(Window *parent);
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e);
|
||||||
void resizeEvent(QResizeEvent *e);
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
@ -238,7 +238,9 @@ public:
|
||||||
void updateOnlineDisplay();
|
void updateOnlineDisplay();
|
||||||
void updateConnectionType();
|
void updateConnectionType();
|
||||||
|
|
||||||
~Settings();
|
void rpcInvalidate();
|
||||||
|
|
||||||
|
~SettingsWidget();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,11 @@ inline char *hashMd5Hex(const void *data, uint32 len, void *dest) { // dest = pt
|
||||||
|
|
||||||
void memset_rand(void *data, uint32 len);
|
void memset_rand(void *data, uint32 len);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void memsetrnd(T &value) {
|
||||||
|
memset_rand(&value, sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
class ReadLockerAttempt {
|
class ReadLockerAttempt {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -395,18 +395,21 @@ void Window::clearWidgets() {
|
||||||
anim::stop(settings);
|
anim::stop(settings);
|
||||||
settings->hide();
|
settings->hide();
|
||||||
settings->deleteLater();
|
settings->deleteLater();
|
||||||
|
settings->rpcInvalidate();
|
||||||
settings = 0;
|
settings = 0;
|
||||||
}
|
}
|
||||||
if (main) {
|
if (main) {
|
||||||
anim::stop(main);
|
anim::stop(main);
|
||||||
main->hide();
|
main->hide();
|
||||||
main->deleteLater();
|
main->deleteLater();
|
||||||
|
main->rpcInvalidate();
|
||||||
main = 0;
|
main = 0;
|
||||||
}
|
}
|
||||||
if (intro) {
|
if (intro) {
|
||||||
anim::stop(intro);
|
anim::stop(intro);
|
||||||
intro->hide();
|
intro->hide();
|
||||||
intro->deleteLater();
|
intro->deleteLater();
|
||||||
|
intro->rpcInvalidate();
|
||||||
intro = 0;
|
intro = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +466,7 @@ void Window::showSettings() {
|
||||||
anim::stop(main);
|
anim::stop(main);
|
||||||
main->hide();
|
main->hide();
|
||||||
}
|
}
|
||||||
settings = new Settings(this);
|
settings = new SettingsWidget(this);
|
||||||
settings->animShow(bg);
|
settings->animShow(bg);
|
||||||
|
|
||||||
fixOrder();
|
fixOrder();
|
||||||
|
@ -476,6 +479,7 @@ void Window::hideSettings(bool fast) {
|
||||||
anim::stop(settings);
|
anim::stop(settings);
|
||||||
settings->hide();
|
settings->hide();
|
||||||
settings->deleteLater();
|
settings->deleteLater();
|
||||||
|
settings->rpcInvalidate();
|
||||||
settings = 0;
|
settings = 0;
|
||||||
if (intro) {
|
if (intro) {
|
||||||
intro->show();
|
intro->show();
|
||||||
|
@ -488,6 +492,7 @@ void Window::hideSettings(bool fast) {
|
||||||
anim::stop(settings);
|
anim::stop(settings);
|
||||||
settings->hide();
|
settings->hide();
|
||||||
settings->deleteLater();
|
settings->deleteLater();
|
||||||
|
settings->rpcInvalidate();
|
||||||
settings = 0;
|
settings = 0;
|
||||||
if (intro) {
|
if (intro) {
|
||||||
intro->animShow(bg, true);
|
intro->animShow(bg, true);
|
||||||
|
@ -533,7 +538,7 @@ MainWidget *Window::mainWidget() {
|
||||||
return main;
|
return main;
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings *Window::settingsWidget() {
|
SettingsWidget *Window::settingsWidget() {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +803,7 @@ void Window::noIntro(IntroWidget *was) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::noSettings(Settings *was) {
|
void Window::noSettings(SettingsWidget *was) {
|
||||||
if (was == settings) {
|
if (was == settings) {
|
||||||
settings = 0;
|
settings = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||||
class TitleWidget;
|
class TitleWidget;
|
||||||
class IntroWidget;
|
class IntroWidget;
|
||||||
class MainWidget;
|
class MainWidget;
|
||||||
class Settings;
|
class SettingsWidget;
|
||||||
class LayerWidget;
|
class LayerWidget;
|
||||||
class BackgroundWidget;
|
class BackgroundWidget;
|
||||||
class LayeredWidget;
|
class LayeredWidget;
|
||||||
|
@ -165,7 +165,7 @@ public:
|
||||||
|
|
||||||
IntroWidget *introWidget();
|
IntroWidget *introWidget();
|
||||||
MainWidget *mainWidget();
|
MainWidget *mainWidget();
|
||||||
Settings *settingsWidget();
|
SettingsWidget *settingsWidget();
|
||||||
|
|
||||||
void showConnecting(const QString &text, const QString &reconnect = QString());
|
void showConnecting(const QString &text, const QString &reconnect = QString());
|
||||||
void hideConnecting();
|
void hideConnecting();
|
||||||
|
@ -191,7 +191,7 @@ public:
|
||||||
void activate();
|
void activate();
|
||||||
|
|
||||||
void noIntro(IntroWidget *was);
|
void noIntro(IntroWidget *was);
|
||||||
void noSettings(Settings *was);
|
void noSettings(SettingsWidget *was);
|
||||||
void noMain(MainWidget *was);
|
void noMain(MainWidget *was);
|
||||||
void noLayer(LayerWidget *was);
|
void noLayer(LayerWidget *was);
|
||||||
void noBox(BackgroundWidget *was);
|
void noBox(BackgroundWidget *was);
|
||||||
|
@ -259,7 +259,7 @@ private:
|
||||||
TitleWidget *title;
|
TitleWidget *title;
|
||||||
IntroWidget *intro;
|
IntroWidget *intro;
|
||||||
MainWidget *main;
|
MainWidget *main;
|
||||||
Settings *settings;
|
SettingsWidget *settings;
|
||||||
LayerWidget *layer;
|
LayerWidget *layer;
|
||||||
BackgroundWidget *layerBG;
|
BackgroundWidget *layerBG;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue