mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-21 18:57:48 +00:00
31 layer, IPv6 support, bot support started
This commit is contained in:
parent
7afda6dfc3
commit
85635dbefd
@ -69,6 +69,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_reconnecting_try_now" = "Try now";
|
||||
|
||||
"lng_status_service_notifications" = "service notifications";
|
||||
"lng_status_bot" = "bot";
|
||||
"lng_status_offline" = "last seen a long time ago";
|
||||
"lng_status_recently" = "last seen recently";
|
||||
"lng_status_last_week" = "last seen within a week";
|
||||
|
@ -206,7 +206,11 @@ namespace App {
|
||||
return (peer_id & 0x100000000L) ? int32(peer_id & 0xFFFFFFFFL) : 0;
|
||||
}
|
||||
|
||||
int32 onlineForSort(int32 online, int32 now) {
|
||||
int32 onlineForSort(UserData *user, int32 now) {
|
||||
if (isServiceUser(user->id) || user->botInfo) {
|
||||
return now - 1;
|
||||
}
|
||||
int32 online = user->onlineTill;
|
||||
if (online <= 0) {
|
||||
switch (online) {
|
||||
case 0:
|
||||
@ -232,8 +236,12 @@ namespace App {
|
||||
return online;
|
||||
}
|
||||
|
||||
int32 onlineWillChangeIn(int32 online, int32 now) {
|
||||
if (online <= 0) {
|
||||
int32 onlineWillChangeIn(UserData *user, int32 now) {
|
||||
if (isServiceUser(user->id) || user->botInfo) {
|
||||
return 86400;
|
||||
}
|
||||
int32 online = user->onlineTill;
|
||||
if (online <= 0) {
|
||||
if (-online > now) return -online - now;
|
||||
return 86400;
|
||||
}
|
||||
@ -255,6 +263,8 @@ namespace App {
|
||||
QString onlineText(UserData *user, int32 now, bool precise) {
|
||||
if (isServiceUser(user->id)) {
|
||||
return lang(lng_status_service_notifications);
|
||||
} else if (user->botInfo) {
|
||||
return lang(lng_status_bot);
|
||||
}
|
||||
int32 online = user->onlineTill;
|
||||
if (online <= 0) {
|
||||
@ -337,84 +347,48 @@ namespace App {
|
||||
status = &emptyStatus;
|
||||
data->contact = -1;
|
||||
} break;
|
||||
case mtpc_userDeleted: {
|
||||
const MTPDuserDeleted &d(user.c_userDeleted());
|
||||
case mtpc_user: {
|
||||
const MTPDuser &d(user.c_user());
|
||||
|
||||
PeerId peer(peerFromUser(d.vid.v));
|
||||
data = App::user(peer);
|
||||
data->input = MTP_inputPeerContact(d.vid);
|
||||
data->inputUser = MTP_inputUserContact(d.vid);
|
||||
data->setName(lang(lng_deleted), QString(), QString(), QString());
|
||||
// data->setName(textOneLine(qs(d.vfirst_name)), textOneLine(qs(d.vlast_name)), QString(), textOneLine(qs(d.vusername)));
|
||||
data->setPhoto(MTP_userProfilePhotoEmpty());
|
||||
data->access = UserNoAccess;
|
||||
int32 flags = d.vflags.v;
|
||||
if (flags & MTPDuser_flag_self) {
|
||||
data->input = MTP_inputPeerSelf();
|
||||
data->inputUser = MTP_inputUserSelf();
|
||||
} else if ((flags & (MTPDuser_flag_contact | MTPDuser_flag_mutual_contact)) || !d.has_access_hash()) {
|
||||
data->input = MTP_inputPeerContact(d.vid);
|
||||
data->inputUser = MTP_inputUserContact(d.vid);
|
||||
} else {
|
||||
data->input = MTP_inputPeerForeign(d.vid, d.vaccess_hash);
|
||||
data->inputUser = MTP_inputUserForeign(d.vid, d.vaccess_hash);
|
||||
}
|
||||
if (flags & MTPDuser_flag_deleted) {
|
||||
data->setPhone(QString());
|
||||
data->setName(lang(lng_deleted), QString(), QString(), QString());
|
||||
data->setPhoto(MTP_userProfilePhotoEmpty());
|
||||
data->access = UserNoAccess;
|
||||
status = &emptyStatus;
|
||||
} else {
|
||||
data->setPhone(d.has_phone() ? qs(d.vphone) : QString());
|
||||
QString fname = d.has_first_name() ? textOneLine(qs(d.vfirst_name)) : QString();
|
||||
QString lname = d.has_last_name() ? textOneLine(qs(d.vlast_name)) : QString();
|
||||
QString uname = d.has_username() ? textOneLine(qs(d.vusername)) : QString();
|
||||
bool showPhone = !isServiceUser(data->id) && !(flags & (MTPDuser_flag_self | MTPDuser_flag_contact | MTPDuser_flag_mutual_contact));
|
||||
QString pname = (showPhone && !data->phone.isEmpty()) ? formatPhone(data->phone) : QString();
|
||||
data->setName(fname, lname, QString(), uname);
|
||||
data->setPhoto(d.has_photo() ? d.vphoto : MTP_userProfilePhotoEmpty());
|
||||
if (d.has_access_hash()) data->access = d.vaccess_hash.v;
|
||||
status = d.has_status() ? &d.vstatus : &emptyStatus;
|
||||
}
|
||||
wasContact = (data->contact > 0);
|
||||
status = &emptyStatus;
|
||||
data->contact = -1;
|
||||
} break;
|
||||
case mtpc_userSelf: {
|
||||
const MTPDuserSelf &d(user.c_userSelf());
|
||||
|
||||
PeerId peer(peerFromUser(d.vid.v));
|
||||
data = App::user(peer);
|
||||
data->input = MTP_inputPeerSelf();
|
||||
data->inputUser = MTP_inputUserSelf();
|
||||
data->setName(textOneLine(qs(d.vfirst_name)), textOneLine(qs(d.vlast_name)), QString(), textOneLine(qs(d.vusername)));
|
||||
data->setPhoto(d.vphoto);
|
||||
data->setPhone(qs(d.vphone));
|
||||
data->access = 0;
|
||||
wasContact = (data->contact > 0);
|
||||
status = &d.vstatus;
|
||||
|
||||
if (::self != data) {
|
||||
if (d.has_bot_info_version()) data->setBotInfoVersion(d.vbot_info_version.v);
|
||||
data->contact = (flags & (MTPDuser_flag_contact | MTPDuser_flag_mutual_contact)) ? 1 : (data->phone.isEmpty() ? -1 : 0);
|
||||
if ((flags & MTPDuser_flag_self) && ::self != data) {
|
||||
::self = data;
|
||||
if (App::wnd()) App::wnd()->updateGlobalMenu();
|
||||
}
|
||||
} break;
|
||||
case mtpc_userContact: {
|
||||
const MTPDuserContact &d(user.c_userContact());
|
||||
|
||||
PeerId peer(peerFromUser(d.vid.v));
|
||||
data = App::user(peer);
|
||||
data->input = MTP_inputPeerContact(d.vid);
|
||||
data->inputUser = MTP_inputUserContact(d.vid);
|
||||
data->setName(textOneLine(qs(d.vfirst_name)), textOneLine(qs(d.vlast_name)), QString(), textOneLine(qs(d.vusername)));
|
||||
data->setPhoto(d.vphoto);
|
||||
data->setPhone(qs(d.vphone));
|
||||
data->access = d.vaccess_hash.v;
|
||||
wasContact = (data->contact > 0);
|
||||
data->contact = 1;
|
||||
status = &d.vstatus;
|
||||
} break;
|
||||
case mtpc_userRequest: {
|
||||
const MTPDuserRequest &d(user.c_userRequest());
|
||||
|
||||
PeerId peer(peerFromUser(d.vid.v));
|
||||
data = App::user(peer);
|
||||
data->input = MTP_inputPeerForeign(d.vid, d.vaccess_hash);
|
||||
data->inputUser = MTP_inputUserForeign(d.vid, d.vaccess_hash);
|
||||
data->setPhone(qs(d.vphone));
|
||||
data->setName(textOneLine(qs(d.vfirst_name)), textOneLine(qs(d.vlast_name)), (!isServiceUser(data->id) && !data->phone.isEmpty()) ? formatPhone(data->phone) : QString(), textOneLine(qs(d.vusername)));
|
||||
data->setPhoto(d.vphoto);
|
||||
data->access = d.vaccess_hash.v;
|
||||
wasContact = (data->contact > 0);
|
||||
data->contact = 0;
|
||||
status = &d.vstatus;
|
||||
} break;
|
||||
case mtpc_userForeign: {
|
||||
const MTPDuserForeign &d(user.c_userForeign());
|
||||
|
||||
PeerId peer(peerFromUser(d.vid.v));
|
||||
data = App::user(peer);
|
||||
data->input = MTP_inputPeerForeign(d.vid, d.vaccess_hash);
|
||||
data->inputUser = MTP_inputUserForeign(d.vid, d.vaccess_hash);
|
||||
data->setName(textOneLine(qs(d.vfirst_name)), textOneLine(qs(d.vlast_name)), QString(), textOneLine(qs(d.vusername)));
|
||||
data->setPhoto(d.vphoto);
|
||||
data->access = d.vaccess_hash.v;
|
||||
wasContact = (data->contact > 0);
|
||||
data->contact = -1;
|
||||
status = &d.vstatus;
|
||||
} break;
|
||||
}
|
||||
|
||||
if (!data) continue;
|
||||
@ -731,11 +705,7 @@ namespace App {
|
||||
MTPint userId(MTP_int(0));
|
||||
switch (dv.vuser.type()) {
|
||||
case mtpc_userEmpty: userId = dv.vuser.c_userEmpty().vid; break;
|
||||
case mtpc_userDeleted: userId = dv.vuser.c_userDeleted().vid; break;
|
||||
case mtpc_userContact: userId = dv.vuser.c_userContact().vid; break;
|
||||
case mtpc_userSelf: userId = dv.vuser.c_userSelf().vid; break;
|
||||
case mtpc_userRequest: userId = dv.vuser.c_userRequest().vid; break;
|
||||
case mtpc_userForeign: userId = dv.vuser.c_userForeign().vid; break;
|
||||
case mtpc_user: userId = dv.vuser.c_user().vid; break;
|
||||
}
|
||||
if (userId.v) {
|
||||
feedUserLink(userId, dv.vmy_link, dv.vforeign_link);
|
||||
@ -1183,6 +1153,7 @@ namespace App {
|
||||
}
|
||||
|
||||
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation) {
|
||||
bool sentSticker = false;
|
||||
if (convert) {
|
||||
if (convert->id != document) {
|
||||
DocumentsData::iterator i = documentsData.find(convert->id);
|
||||
@ -1191,6 +1162,7 @@ namespace App {
|
||||
}
|
||||
convert->id = document;
|
||||
convert->status = FileReady;
|
||||
sentSticker = !!convert->sticker;
|
||||
}
|
||||
convert->access = access;
|
||||
if (!convert->date && date) {
|
||||
@ -1266,6 +1238,7 @@ namespace App {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sentSticker && App::main()) App::main()->incrementSticker(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -92,8 +92,8 @@ namespace App {
|
||||
int32 userFromPeer(const PeerId &peer_id);
|
||||
int32 chatFromPeer(const PeerId &peer_id);
|
||||
|
||||
int32 onlineForSort(int32 online, int32 now);
|
||||
int32 onlineWillChangeIn(int32 onlineOnServer, int32 nowOnServer);
|
||||
int32 onlineForSort(UserData *user, int32 now);
|
||||
int32 onlineWillChangeIn(UserData *user, int32 nowOnServer);
|
||||
QString onlineText(UserData *user, int32 nowOnServer, bool precise = false);
|
||||
bool onlineColorUse(int32 online, int32 now);
|
||||
|
||||
|
@ -43,7 +43,8 @@ enum {
|
||||
MTPMinConnectDelay = 1000, // tcp connect should take less then 1 second
|
||||
MTPMaxConnectDelay = 8000, // tcp connect should take 8 seconds max
|
||||
MTPConnectionOldTimeout = 192000, // 192 seconds
|
||||
MTPTcpConnectionWaitTimeout = 3000, // 3 seconds waiting for tcp, until we accept http
|
||||
MTPTcpConnectionWaitTimeout = 2000, // 2 seconds waiting for tcp, until we accept http
|
||||
MTPIPv4ConnectionWaitTimeout = 1000, // 1 seconds waiting for ipv4, until we accept ipv6
|
||||
MTPMillerRabinIterCount = 30, // 30 Miller-Rabin iterations for dh_prime primality check
|
||||
|
||||
MTPUploadSessionsCount = 4, // max 4 upload sessions is created
|
||||
@ -125,7 +126,7 @@ enum {
|
||||
SaveDraftTimeout = 1000, // save draft after 1 secs of not changing text
|
||||
SaveDraftAnywayTimeout = 5000, // or save anyway each 5 secs
|
||||
|
||||
HiddenIsOnlineAfterMessage = 30, // user with hidden last seen stays online for such amount of seconds in the interface
|
||||
SetOnlineAfterActivity = 30, // user with hidden last seen stays online for such amount of seconds in the interface
|
||||
|
||||
ServiceUserId = 777000,
|
||||
WebPageUserId = 701000,
|
||||
@ -186,10 +187,24 @@ static const BuiltInDc _builtInDcs[] = {
|
||||
{ 5, "149.154.171.5", 443 }
|
||||
};
|
||||
|
||||
static const BuiltInDc _builtInDcsIPv6[] = {
|
||||
{ 1, "2001:b28:f23d:f001::a", 443 },
|
||||
{ 2, "2001:67c:4e8:f002::a", 443 },
|
||||
{ 3, "2001:b28:f23d:f003::a", 443 },
|
||||
{ 4, "2001:67c:4e8:f004::a", 443 },
|
||||
{ 5, "2001:b28:f23f:f005::a", 443 }
|
||||
};
|
||||
|
||||
static const BuiltInDc _builtInTestDcs[] = {
|
||||
{ 1, "149.154.175.10", 443 },
|
||||
{ 2, "149.154.167.40", 443 },
|
||||
{ 3, "174.140.142.5", 443 }
|
||||
{ 3, "149.154.175.117", 443 }
|
||||
};
|
||||
|
||||
static const BuiltInDc _builtInTestDcsIPv6[] = {
|
||||
{ 1, "2001:b28:f23d:f001::e", 443 },
|
||||
{ 2, "2001:67c:4e8:f002::e", 443 },
|
||||
{ 3, "2001:b28:f23d:f003::e", 443 }
|
||||
};
|
||||
|
||||
inline const BuiltInDc *builtInDcs() {
|
||||
@ -200,6 +215,14 @@ inline int builtInDcsCount() {
|
||||
return (cTestMode() ? sizeof(_builtInTestDcs) : sizeof(_builtInDcs)) / sizeof(BuiltInDc);
|
||||
}
|
||||
|
||||
inline const BuiltInDc *builtInDcsIPv6() {
|
||||
return cTestMode() ? _builtInTestDcsIPv6 : _builtInDcsIPv6;
|
||||
}
|
||||
|
||||
inline int builtInDcsCountIPv6() {
|
||||
return (cTestMode() ? sizeof(_builtInTestDcsIPv6) : sizeof(_builtInDcsIPv6)) / sizeof(BuiltInDc);
|
||||
}
|
||||
|
||||
static const char *UpdatesPublicKey = "\
|
||||
-----BEGIN RSA PUBLIC KEY-----\n\
|
||||
MIGJAoGBAMA4ViQrjkPZ9xj0lrer3r23JvxOnrtE8nI69XLGSr+sRERz9YnUptnU\n\
|
||||
|
@ -2635,7 +2635,7 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||
UserData *user = i.key();
|
||||
if (user->username.isEmpty()) continue;
|
||||
if (_filter.size() > 1 && (!user->username.startsWith(_filter.midRef(1), Qt::CaseInsensitive) || user->username.size() + 1 == _filter.size())) continue;
|
||||
ordered.insertMulti(App::onlineForSort(user->onlineTill, now), user);
|
||||
ordered.insertMulti(App::onlineForSort(user, now), user);
|
||||
}
|
||||
}
|
||||
for (MentionRows::const_iterator i = _chat->lastAuthors.cbegin(), e = _chat->lastAuthors.cend(); i != e; ++i) {
|
||||
@ -2644,7 +2644,7 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||
if (_filter.size() > 1 && (!user->username.startsWith(_filter.midRef(1), Qt::CaseInsensitive) || user->username.size() + 1 == _filter.size())) continue;
|
||||
rows.push_back(user);
|
||||
if (!ordered.isEmpty()) {
|
||||
ordered.remove(App::onlineForSort(user->onlineTill, now), user);
|
||||
ordered.remove(App::onlineForSort(user, now), user);
|
||||
}
|
||||
}
|
||||
if (!ordered.isEmpty()) {
|
||||
|
@ -460,6 +460,8 @@ void Histories::regTyping(History *history, UserData *user) {
|
||||
uint64 ms = getms(true);
|
||||
history->typing[user] = ms + 6000;
|
||||
|
||||
user->madeAction();
|
||||
|
||||
TypingHistories::const_iterator i = typing.find(history);
|
||||
if (i == typing.cend()) {
|
||||
typing.insert(history, ms);
|
||||
@ -802,10 +804,7 @@ void History::newItemAdded(HistoryItem *item) {
|
||||
App::checkImageCacheSize();
|
||||
if (item->from()) {
|
||||
unregTyping(item->from());
|
||||
if (item->from()->onlineTill < 0) {
|
||||
item->from()->onlineTill = -unixtime() - HiddenIsOnlineAfterMessage; // pseudo-online
|
||||
if (App::main()) App::main()->peerUpdated(item->from());
|
||||
}
|
||||
item->from()->madeAction();
|
||||
}
|
||||
if (item->out()) {
|
||||
if (unreadBar) unreadBar->destroy();
|
||||
@ -3083,7 +3082,6 @@ void HistorySticker::updateFrom(const MTPMessageMedia &media) {
|
||||
if (!data->data.isEmpty()) {
|
||||
Local::writeStickerImage(mediaKey(mtpToLocationType(mtpc_inputDocumentFileLocation), data->dc, data->id), data->data);
|
||||
}
|
||||
if (App::main()) App::main()->incrementSticker(data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3417,11 +3415,13 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
|
||||
}
|
||||
QString title(data->title.isEmpty() ? data->author : data->title);
|
||||
if (!title.isEmpty()) {
|
||||
_title.setText(st::webPageTitleFont, textClean(title), _webpageTitleOptions);
|
||||
title = textClean(title);
|
||||
if (!_asArticle && !data->photo && data->description.isEmpty()) title += textcmdSkipBlock(parent->timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y());
|
||||
_title.setText(st::webPageTitleFont, title, _webpageTitleOptions);
|
||||
if (_asArticle) {
|
||||
_maxw = qMax(_maxw, int32(st::webPageLeft + _title.maxWidth() + st::webPagePhotoDelta + st::webPagePhotoSize));
|
||||
} else {
|
||||
_maxw = qMax(_maxw, int32(st::webPageLeft + _title.maxWidth() + (data->photo ? parent->timeWidth(true) : 0)));
|
||||
_maxw = qMax(_maxw, int32(st::webPageLeft + _title.maxWidth()));
|
||||
_minh += qMin(_title.minHeight(), 2 * st::webPageTitleFont->height);
|
||||
}
|
||||
}
|
||||
|
@ -2779,14 +2779,15 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
|
||||
h->loadAround(0);
|
||||
|
||||
PeerData *p = App::peer(peer);
|
||||
int32 flags = (p->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out); // unread, out
|
||||
int32 flags = newMessageFlags(p); // unread, out
|
||||
|
||||
int32 sendFlags = 0;
|
||||
if (replyTo) {
|
||||
flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
|
||||
}
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTPint(), MTPint(), MTP_int(_replyToId), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId))));
|
||||
h->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTPint(), MTPint(), MTP_int(_replyToId), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId)), MTPnullMarkup));
|
||||
h->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
|
||||
App::historyRegRandom(randomId, newId);
|
||||
|
||||
@ -3287,13 +3288,13 @@ void HistoryWidget::updateOnlineDisplayTimer() {
|
||||
if (chat->participants.isEmpty()) return;
|
||||
|
||||
for (ChatData::Participants::const_iterator i = chat->participants.cbegin(), e = chat->participants.cend(); i != e; ++i) {
|
||||
int32 onlineWillChangeIn = App::onlineWillChangeIn(i.key()->onlineTill, t);
|
||||
int32 onlineWillChangeIn = App::onlineWillChangeIn(i.key(), t);
|
||||
if (onlineWillChangeIn < minIn) {
|
||||
minIn = onlineWillChangeIn;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
minIn = App::onlineWillChangeIn(histPeer->asUser()->onlineTill, t);
|
||||
minIn = App::onlineWillChangeIn(histPeer->asUser(), t);
|
||||
}
|
||||
App::main()->updateOnlineDisplayIn(minIn * 1000);
|
||||
}
|
||||
@ -3458,21 +3459,15 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
||||
App::uploader()->uploadMedia(newId, img);
|
||||
|
||||
History *h = App::history(img.peer);
|
||||
h->loadAround(0);
|
||||
int32 flags = newMessageFlags(h->peer); // unread, out
|
||||
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
if (img.type == ToPreparePhoto) {
|
||||
h->loadAround(0);
|
||||
int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out); // unread, out
|
||||
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string(""))));
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string("")), MTPnullMarkup));
|
||||
} else if (img.type == ToPrepareDocument) {
|
||||
h->loadAround(0);
|
||||
int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out); // unread, out
|
||||
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document)));
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document), MTPnullMarkup));
|
||||
} else if (img.type == ToPrepareAudio) {
|
||||
h->loadAround(0);
|
||||
int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out | MTPDmessage_flag_media_unread); // unread, out
|
||||
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio)));
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup));
|
||||
}
|
||||
|
||||
if (hist && histPeer && img.peer == histPeer->id) {
|
||||
@ -3503,7 +3498,7 @@ void HistoryWidget::onPhotoUploaded(MsgId newId, const MTPInputFile &file) {
|
||||
if (replyTo) {
|
||||
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
|
||||
}
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file, MTP_string("")), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendPhotoFailed, randomId), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file, MTP_string("")), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendPhotoFailed, randomId), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3543,7 +3538,7 @@ void HistoryWidget::onDocumentUploaded(MsgId newId, const MTPInputFile &file) {
|
||||
if (replyTo) {
|
||||
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
|
||||
}
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3569,7 +3564,7 @@ void HistoryWidget::onThumbDocumentUploaded(MsgId newId, const MTPInputFile &fil
|
||||
if (replyTo) {
|
||||
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
|
||||
}
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3593,7 +3588,7 @@ void HistoryWidget::onAudioUploaded(MsgId newId, const MTPInputFile &file) {
|
||||
if (replyTo) {
|
||||
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
|
||||
}
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedAudio(file, MTP_int(audio->duration), MTP_string(audio->mime)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedAudio(file, MTP_int(audio->duration), MTP_string(audio->mime)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3895,7 +3890,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
|
||||
hist->loadAround(0);
|
||||
|
||||
bool out = (histPeer->input.type() != mtpc_inputPeerSelf), unread = (histPeer->input.type() != mtpc_inputPeerSelf);
|
||||
int32 flags = (histPeer->input.type() != mtpc_inputPeerSelf) ? (MTPDmessage_flag_out | MTPDmessage_flag_unread) : 0;
|
||||
int32 flags = newMessageFlags(histPeer); // unread, out
|
||||
int32 sendFlags = 0;
|
||||
if (_replyToId) {
|
||||
flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
@ -3903,7 +3898,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
|
||||
}
|
||||
hist->addToBackDocument(newId, flags, _replyToId, date(MTP_int(unixtime())), MTP::authedId(), sticker);
|
||||
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), histPeer->input, MTP_int(_replyToId), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(sticker->id), MTP_long(sticker->access))), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), histPeer->input, MTP_int(_replyToId), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(sticker->id), MTP_long(sticker->access))), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
App::main()->finishForwarding(hist);
|
||||
cancelReply();
|
||||
|
||||
|
@ -202,7 +202,7 @@ void IntroCode::codeSubmitDone(const MTPauth_Authorization &result) {
|
||||
stopCheck();
|
||||
code.setDisabled(false);
|
||||
const MTPDauth_authorization &d(result.c_auth_authorization());
|
||||
if (d.vuser.type() != mtpc_userSelf) { // wtf?
|
||||
if (d.vuser.type() != mtpc_user || !(d.vuser.c_user().vflags.v & MTPDuser_flag_self)) { // wtf?
|
||||
showError(lang(lng_server_error));
|
||||
return;
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ void IntroPwdCheck::pwdSubmitDone(bool recover, const MTPauth_Authorization &res
|
||||
_pwdField.setDisabled(false);
|
||||
_codeField.setDisabled(false);
|
||||
const MTPDauth_authorization &d(result.c_auth_authorization());
|
||||
if (d.vuser.type() != mtpc_userSelf) { // wtf?
|
||||
if (d.vuser.type() != mtpc_user || !(d.vuser.c_user().vflags.v & MTPDuser_flag_self)) { // wtf?
|
||||
showError(lang(lng_server_error));
|
||||
return;
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ void IntroSignup::nameSubmitDone(const MTPauth_Authorization &result) {
|
||||
first.setDisabled(false);
|
||||
last.setDisabled(false);
|
||||
const MTPDauth_authorization &d(result.c_auth_authorization());
|
||||
if (d.vuser.type() != mtpc_userSelf) { // wtf?
|
||||
if (d.vuser.type() != mtpc_user || !(d.vuser.c_user().vflags.v & MTPDuser_flag_self)) { // wtf?
|
||||
showError(lang(lng_server_error));
|
||||
return;
|
||||
}
|
||||
|
@ -609,13 +609,22 @@ namespace {
|
||||
mtpDcOptions *_dcOpts = 0;
|
||||
bool _readSetting(quint32 blockId, QDataStream &stream, int version) {
|
||||
switch (blockId) {
|
||||
case dbiDcOption: {
|
||||
case dbiDcOptionOld: {
|
||||
quint32 dcId, port;
|
||||
QString host, ip;
|
||||
stream >> dcId >> host >> ip >> port;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
if (_dcOpts) _dcOpts->insert(dcId, mtpDcOption(dcId, host.toUtf8().constData(), ip.toUtf8().constData(), port));
|
||||
if (_dcOpts) _dcOpts->insert(dcId, mtpDcOption(dcId, 0, ip.toUtf8().constData(), port));
|
||||
} break;
|
||||
|
||||
case dbiDcOption: {
|
||||
quint32 dcIdWithShift, flags, port;
|
||||
QString ip;
|
||||
stream >> dcIdWithShift >> flags >> ip >> port;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
if (_dcOpts) _dcOpts->insert(dcIdWithShift, mtpDcOption(dcIdWithShift % _mtp_internal::dcShift, flags, ip.toUtf8().constData(), port));
|
||||
} break;
|
||||
|
||||
case dbiMaxGroupCount: {
|
||||
@ -1723,9 +1732,16 @@ namespace Local {
|
||||
if (dcOpts.isEmpty()) {
|
||||
const BuiltInDc *bdcs = builtInDcs();
|
||||
for (int i = 0, l = builtInDcsCount(); i < l; ++i) {
|
||||
dcOpts.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, "", bdcs[i].ip, bdcs[i].port));
|
||||
dcOpts.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, 0, 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));
|
||||
}
|
||||
|
||||
const BuiltInDc *bdcsipv6 = builtInDcsIPv6();
|
||||
for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) {
|
||||
int32 flags = MTPDdcOption_flag_ipv6, idWithShift = bdcsipv6[i].id + (flags * _mtp_internal::dcShift);
|
||||
dcOpts.insert(idWithShift, mtpDcOption(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));
|
||||
}
|
||||
}
|
||||
{
|
||||
QWriteLocker lock(MTP::dcOptionsMutex());
|
||||
@ -1759,10 +1775,16 @@ namespace Local {
|
||||
if (dcOpts.isEmpty()) {
|
||||
const BuiltInDc *bdcs = builtInDcs();
|
||||
for (int i = 0, l = builtInDcsCount(); i < l; ++i) {
|
||||
dcOpts.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, "", bdcs[i].ip, bdcs[i].port));
|
||||
dcOpts.insert(bdcs[i].id, mtpDcOption(bdcs[i].id, 0, 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));
|
||||
}
|
||||
|
||||
const BuiltInDc *bdcsipv6 = builtInDcsIPv6();
|
||||
for (int i = 0, l = builtInDcsCountIPv6(); i < l; ++i) {
|
||||
dcOpts.insert(bdcsipv6[i].id + (MTPDdcOption_flag_ipv6 * _mtp_internal::dcShift), mtpDcOption(bdcsipv6[i].id, MTPDdcOption_flag_ipv6, 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));
|
||||
}
|
||||
|
||||
QWriteLocker lock(MTP::dcOptionsMutex());
|
||||
cSetDcOptions(dcOpts);
|
||||
}
|
||||
@ -1770,7 +1792,7 @@ namespace Local {
|
||||
quint32 size = 10 * (sizeof(quint32) + sizeof(qint32));
|
||||
for (mtpDcOptions::const_iterator i = dcOpts.cbegin(), e = dcOpts.cend(); i != e; ++i) {
|
||||
size += sizeof(quint32) + sizeof(quint32) + sizeof(quint32);
|
||||
size += _stringSize(QString::fromUtf8(i->host.data(), i->host.size())) + _stringSize(QString::fromUtf8(i->ip.data(), i->ip.size()));
|
||||
size += sizeof(quint32) + _stringSize(QString::fromUtf8(i->ip.data(), i->ip.size()));
|
||||
}
|
||||
size += sizeof(quint32) + _stringSize(cLangFile());
|
||||
|
||||
@ -1794,8 +1816,8 @@ namespace Local {
|
||||
data.stream << quint32(dbiScale) << qint32(cConfigScale());
|
||||
data.stream << quint32(dbiLang) << qint32(cLang());
|
||||
for (mtpDcOptions::const_iterator i = dcOpts.cbegin(), e = dcOpts.cend(); i != e; ++i) {
|
||||
data.stream << quint32(dbiDcOption) << quint32(i->id);
|
||||
data.stream << QString::fromUtf8(i->host.data(), i->host.size()) << QString::fromUtf8(i->ip.data(), i->ip.size());
|
||||
data.stream << quint32(dbiDcOption) << quint32(i.key());
|
||||
data.stream << quint32(i->flags) << QString::fromUtf8(i->ip.data(), i->ip.size());
|
||||
data.stream << quint32(i->port);
|
||||
}
|
||||
data.stream << quint32(dbiLangFile) << cLangFile();
|
||||
|
@ -494,9 +494,13 @@ void MainWidget::finishForwarding(History *hist) {
|
||||
if (_toForward.size() < 2) {
|
||||
uint64 randomId = MTP::nonce<uint64>();
|
||||
MsgId newId = clientMsgId();
|
||||
hist->addToBackForwarded(newId, static_cast<HistoryMessage*>(_toForward.cbegin().value()));
|
||||
HistoryMessage *msg = static_cast<HistoryMessage*>(_toForward.cbegin().value());
|
||||
hist->addToBackForwarded(newId, msg);
|
||||
App::historyRegRandom(randomId, newId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_ForwardMessage(hist->peer->input, MTP_int(_toForward.cbegin().key()), MTP_long(randomId)), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
if (HistorySticker *sticker = dynamic_cast<HistorySticker*>(msg->getMedia())) {
|
||||
App::main()->incrementSticker(sticker->document());
|
||||
}
|
||||
} else {
|
||||
QVector<MTPint> ids;
|
||||
QVector<MTPlong> randomIds;
|
||||
@ -940,7 +944,7 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
|
||||
App::historyRegRandom(randomId, newId);
|
||||
|
||||
MTPstring msgText(MTP_string(sendingText));
|
||||
int32 flags = (hist->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out);
|
||||
int32 flags = newMessageFlags(hist->peer); // unread, out
|
||||
int32 sendFlags = 0;
|
||||
if (replyTo) {
|
||||
flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
@ -953,8 +957,8 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
|
||||
WebPageData *page = App::webPage(webPageId);
|
||||
media = MTP_messageMediaWebPage(MTP_webPagePending(MTP_long(page->id), MTP_int(page->pendingTill)));
|
||||
}
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
|
||||
finishForwarding(hist);
|
||||
@ -1575,7 +1579,7 @@ void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &
|
||||
QString sendingText, leftText = msg;
|
||||
HistoryItem *item = 0;
|
||||
while (textSplit(sendingText, leftText, MaxMessageSize)) {
|
||||
item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media), unread ? 1 : 2);
|
||||
item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup), unread ? 1 : 2);
|
||||
}
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
@ -2491,7 +2495,7 @@ void MainWidget::mtpPing() {
|
||||
}
|
||||
|
||||
void MainWidget::start(const MTPUser &user) {
|
||||
int32 uid = user.c_userSelf().vid.v;
|
||||
int32 uid = user.c_user().vid.v;
|
||||
if (MTP::authedId() != uid) {
|
||||
MTP::authed(uid);
|
||||
Local::writeMtpData();
|
||||
@ -2666,7 +2670,7 @@ bool MainWidget::inviteImportFail(const RPCError &error) {
|
||||
|
||||
void MainWidget::startFull(const MTPVector<MTPUser> &users) {
|
||||
const QVector<MTPUser> &v(users.c_vector().v);
|
||||
if (v.isEmpty() || v[0].type() != mtpc_userSelf) { // wtf?..
|
||||
if (v.isEmpty() || v[0].type() != mtpc_user || !(v[0].c_user().vflags.v & MTPDuser_flag_self)) { // wtf?..
|
||||
return App::logOut();
|
||||
}
|
||||
start(v[0]);
|
||||
@ -3054,7 +3058,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
return;
|
||||
}
|
||||
bool out = (d.vflags.v & MTPDmessage_flag_out);
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty()));
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
@ -3074,7 +3078,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
|
||||
return;
|
||||
}
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty()));
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
|
@ -743,8 +743,9 @@ void MTPautoConnection::disconnectFromServer() {
|
||||
status = FinishedWork;
|
||||
}
|
||||
|
||||
void MTPautoConnection::connectToServer(const QString &addr, int32 port) {
|
||||
address = QUrl(qsl("http://%1:%2/api").arg(addr).arg(80));//not port - always 80 port for http transport
|
||||
void MTPautoConnection::connectToServer(const QString &addr, int32 port, int32 flags) {
|
||||
address = QUrl(((flags & MTPDdcOption_flag_ipv6) ? qsl("http://[%1]:%2/api") : qsl("http://%1:%2/api")).arg(addr).arg(80));//not p - always 80 port for http transport
|
||||
TCP_LOG(("HTTP Info: address is %1").arg(address.toDisplayString()));
|
||||
connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
|
||||
|
||||
_addr = addr;
|
||||
@ -943,7 +944,7 @@ void MTPtcpConnection::disconnectFromServer() {
|
||||
sock.close();
|
||||
}
|
||||
|
||||
void MTPtcpConnection::connectToServer(const QString &addr, int32 port) {
|
||||
void MTPtcpConnection::connectToServer(const QString &addr, int32 port, int32 flags) {
|
||||
connect(&sock, SIGNAL(readyRead()), this, SLOT(socketRead()));
|
||||
sock.connectToHost(QHostAddress(addr), port);
|
||||
}
|
||||
@ -1013,8 +1014,9 @@ void MTPhttpConnection::disconnectFromServer() {
|
||||
address = QUrl();
|
||||
}
|
||||
|
||||
void MTPhttpConnection::connectToServer(const QString &addr, int32 p) {
|
||||
address = QUrl(qsl("http://%1:%2/api").arg(addr).arg(80));//not p - always 80 port for http transport
|
||||
void MTPhttpConnection::connectToServer(const QString &addr, int32 p, int32 flags) {
|
||||
address = QUrl(((flags & MTPDdcOption_flag_ipv6) ? qsl("http://[%1]:%2/api") : qsl("http://%1:%2/api")).arg(addr).arg(80));//not p - always 80 port for http transport
|
||||
TCP_LOG(("HTTP Info: address is %1").arg(address.toDisplayString()));
|
||||
connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
|
||||
emit connected();
|
||||
}
|
||||
@ -1062,19 +1064,30 @@ QString MTPhttpConnection::transport() const {
|
||||
return qsl("HTTP");
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::createConn() {
|
||||
if (conn) {
|
||||
conn->deleteLater();
|
||||
void MTProtoConnectionPrivate::createConn(bool createIPv4, bool createIPv6) {
|
||||
destroyConn();
|
||||
if (createIPv4) {
|
||||
if (cConnectionType() == dbictAuto) {
|
||||
_conn4 = new MTPautoConnection(thread());
|
||||
} else if (cConnectionType() == dbictTcpProxy) {
|
||||
_conn4 = new MTPtcpConnection(thread());
|
||||
} else {
|
||||
_conn4 = new MTPhttpConnection(thread());
|
||||
}
|
||||
connect(_conn4, SIGNAL(error(bool)), this, SLOT(onError4(bool)));
|
||||
connect(_conn4, SIGNAL(receivedSome()), this, SLOT(onReceivedSome()));
|
||||
}
|
||||
if (cConnectionType() == dbictAuto) {
|
||||
conn = new MTPautoConnection(thread());
|
||||
} else if (cConnectionType() == dbictTcpProxy) {
|
||||
conn = new MTPtcpConnection(thread());
|
||||
} else {
|
||||
conn = new MTPhttpConnection(thread());
|
||||
if (createIPv6) {
|
||||
if (cConnectionType() == dbictAuto) {
|
||||
_conn6 = new MTPautoConnection(thread());
|
||||
} else if (cConnectionType() == dbictTcpProxy) {
|
||||
_conn6 = new MTPtcpConnection(thread());
|
||||
} else {
|
||||
_conn6 = new MTPhttpConnection(thread());
|
||||
}
|
||||
connect(_conn6, SIGNAL(error(bool)), this, SLOT(onError6(bool)));
|
||||
connect(_conn6, SIGNAL(receivedSome()), this, SLOT(onReceivedSome()));
|
||||
}
|
||||
connect(conn, SIGNAL(error(bool)), this, SLOT(onError(bool)));
|
||||
connect(conn, SIGNAL(receivedSome()), this, SLOT(onReceivedSome()));
|
||||
firstSentAt = 0;
|
||||
if (oldConnection) {
|
||||
oldConnection = false;
|
||||
@ -1083,17 +1096,35 @@ void MTProtoConnectionPrivate::createConn() {
|
||||
oldConnectionTimer.start(MTPConnectionOldTimeout);
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::destroyConn(MTPabstractConnection **conn) {
|
||||
if (conn) {
|
||||
if (*conn) {
|
||||
disconnect(*conn, SIGNAL(disconnected()), 0, 0);
|
||||
disconnect(*conn, SIGNAL(receivedData()), 0, 0);
|
||||
disconnect(*conn, SIGNAL(receivedSome()), 0, 0);
|
||||
|
||||
(*conn)->disconnectFromServer();
|
||||
(*conn)->deleteLater();
|
||||
*conn = 0;
|
||||
}
|
||||
} else {
|
||||
destroyConn(&_conn4);
|
||||
destroyConn(&_conn6);
|
||||
_conn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConnection *owner, MTPSessionData *data, uint32 _dc)
|
||||
: QObject(0)
|
||||
, _state(MTProtoConnection::Disconnected)
|
||||
, _needSessionReset(false)
|
||||
, dc(_dc)
|
||||
, _owner(owner)
|
||||
, conn(0)
|
||||
, _conn(0), _conn4(0), _conn6(0)
|
||||
, retryTimeout(1)
|
||||
, oldConnection(true)
|
||||
, receiveDelay(MTPMinReceiveDelay)
|
||||
, connectDelay(MTPMinConnectDelay)
|
||||
, _waitForReceived(MTPMinReceiveDelay)
|
||||
, _waitForConnected(MTPMinConnectDelay)
|
||||
, firstSentAt(-1)
|
||||
, _pingId(0)
|
||||
, _pingIdToSend(0)
|
||||
@ -1107,14 +1138,13 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne
|
||||
, authKeyStrings(0) {
|
||||
|
||||
oldConnectionTimer.moveToThread(thread);
|
||||
cantConnectTimer.moveToThread(thread);
|
||||
connCheckTimer.moveToThread(thread);
|
||||
_waitForConnectedTimer.moveToThread(thread);
|
||||
_waitForReceivedTimer.moveToThread(thread);
|
||||
_waitForIPv4Timer.moveToThread(thread);
|
||||
_pingSender.moveToThread(thread);
|
||||
retryTimer.moveToThread(thread);
|
||||
moveToThread(thread);
|
||||
|
||||
// createConn();
|
||||
|
||||
if (!dc) {
|
||||
QReadLocker lock(mtpDcOptionsMutex());
|
||||
const mtpDcOptions &options(cDcOptions());
|
||||
@ -1131,8 +1161,9 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne
|
||||
connect(thread, SIGNAL(finished()), this, SLOT(doFinish()));
|
||||
|
||||
connect(&retryTimer, SIGNAL(timeout()), this, SLOT(retryByTimer()));
|
||||
connect(&connCheckTimer, SIGNAL(timeout()), this, SLOT(onBadConnection()));
|
||||
connect(&cantConnectTimer, SIGNAL(timeout()), this, SLOT(onCantConnect()));
|
||||
connect(&_waitForConnectedTimer, SIGNAL(timeout()), this, SLOT(onWaitConnectedFailed()));
|
||||
connect(&_waitForReceivedTimer, SIGNAL(timeout()), this, SLOT(onWaitReceivedFailed()));
|
||||
connect(&_waitForIPv4Timer, SIGNAL(timeout()), this, SLOT(onWaitIPv4Failed()));
|
||||
connect(&oldConnectionTimer, SIGNAL(timeout()), this, SLOT(onOldConnection()));
|
||||
connect(&_pingSender, SIGNAL(timeout()), this, SLOT(onPingSender()));
|
||||
connect(sessionData->owner(), SIGNAL(authKeyCreated()), this, SLOT(updateAuthKey()), Qt::QueuedConnection);
|
||||
@ -1183,10 +1214,10 @@ int32 MTProtoConnectionPrivate::getState() const {
|
||||
}
|
||||
|
||||
QString MTProtoConnectionPrivate::transport() const {
|
||||
if (!conn || _state < 0) {
|
||||
if ((!_conn4 && !_conn6) || _state < 0) {
|
||||
return QString();
|
||||
}
|
||||
return conn->transport();
|
||||
return (_conn4 ? _conn4 : _conn6)->transport();
|
||||
}
|
||||
|
||||
bool MTProtoConnectionPrivate::setState(int32 state, int32 ifState) {
|
||||
@ -1421,7 +1452,7 @@ mtpMsgId MTProtoConnectionPrivate::placeToContainer(mtpRequest &toSendRequest, m
|
||||
|
||||
void MTProtoConnectionPrivate::tryToSend() {
|
||||
QReadLocker lockFinished(&sessionDataMutex);
|
||||
if (!sessionData || !conn) {
|
||||
if (!sessionData || !_conn) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1513,7 +1544,7 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||
stateRequest->msDate = getms(true); // > 0 - can send without container
|
||||
stateRequest->requestId = reqid();// add to haveSent / wereAcked maps, but don't add to requestMap
|
||||
}
|
||||
if (conn->usingHttpWait()) {
|
||||
if (_conn->usingHttpWait()) {
|
||||
MTPHttpWait req(MTP_http_wait(MTP_int(100), MTP_int(30), MTP_int(25000)));
|
||||
|
||||
httpWaitRequest = mtpRequestData::prepare(req.innerLength() >> 2);
|
||||
@ -1734,47 +1765,63 @@ void MTProtoConnectionPrivate::restartNow() {
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::socketStart(bool afterConfig) {
|
||||
if (!conn) createConn();
|
||||
retryTimer.stop();
|
||||
cantConnectTimer.stop();
|
||||
|
||||
if (conn->isConnected()) {
|
||||
onConnected();
|
||||
return;
|
||||
}
|
||||
setState(MTProtoConnection::Connecting);
|
||||
_pingId = _pingMsgId = _pingIdToSend = _pingSendAt = 0;
|
||||
_pingSender.stop();
|
||||
|
||||
std::string ip;
|
||||
uint32 port = 0;
|
||||
int32 flags4 = 0, flags6 = 0;
|
||||
std::string ip4, ip6;
|
||||
uint32 port4 = 0, port6 = 0;
|
||||
{
|
||||
QReadLocker lock(mtpDcOptionsMutex());
|
||||
const mtpDcOptions &options(cDcOptions());
|
||||
mtpDcOptions::const_iterator dcIndex = options.constFind(dc % _mtp_internal::dcShift);
|
||||
DEBUG_LOG(("MTP Info: connecting to DC %1..").arg(dc));
|
||||
if (dcIndex != options.cend()) {
|
||||
ip = dcIndex->ip;
|
||||
port = dcIndex->port;
|
||||
mtpDcOptions::const_iterator dcIndex4 = options.constFind(dc % _mtp_internal::dcShift);
|
||||
if (dcIndex4 != options.cend()) {
|
||||
ip4 = dcIndex4->ip;
|
||||
flags4 = dcIndex4->flags;
|
||||
port4 = dcIndex4->port;
|
||||
}
|
||||
mtpDcOptions::const_iterator dcIndex6 = options.constFind((dc % _mtp_internal::dcShift) + (_mtp_internal::dcShift * MTPDdcOption_flag_ipv6));
|
||||
if (dcIndex6 != options.cend()) {
|
||||
ip6 = dcIndex6->ip;
|
||||
flags6 = dcIndex6->flags;
|
||||
port6 = dcIndex6->port;
|
||||
}
|
||||
}
|
||||
if (!port || ip.empty()) {
|
||||
bool noIPv4 = (!port4 || ip4.empty()), noIPv6 = (!port6 || ip6.empty());
|
||||
if (noIPv4 && noIPv6) {
|
||||
if (afterConfig) {
|
||||
LOG(("MTP Error: DC %1 options not found right after config load!").arg(dc));
|
||||
if (noIPv4) LOG(("MTP Error: DC %1 options for IPv4 not found right after config load!").arg(dc));
|
||||
if (noIPv6) LOG(("MTP Error: DC %1 options for IPv6 not found right after config load!").arg(dc));
|
||||
return restart();
|
||||
}
|
||||
DEBUG_LOG(("MTP Info: DC %1 options not found, waiting for config").arg(dc));
|
||||
if (noIPv4) DEBUG_LOG(("MTP Info: DC %1 options for IPv4 not found, waiting for config").arg(dc));
|
||||
if (noIPv6) DEBUG_LOG(("MTP Info: DC %1 options for IPv6 not found, waiting for config").arg(dc));
|
||||
connect(mtpConfigLoader(), SIGNAL(loaded()), this, SLOT(onConfigLoaded()));
|
||||
mtpConfigLoader()->load();
|
||||
return;
|
||||
}
|
||||
DEBUG_LOG(("MTP Info: socket connection to %1:%2..").arg(ip.c_str()).arg(port));
|
||||
|
||||
connect(conn, SIGNAL(connected()), this, SLOT(onConnected()));
|
||||
connect(conn, SIGNAL(disconnected()), this, SLOT(restart()));
|
||||
if (afterConfig && (_conn4 || _conn6)) return;
|
||||
|
||||
cantConnectTimer.start(connectDelay);
|
||||
conn->connectToServer(ip.c_str(), port);
|
||||
createConn(!noIPv4, !noIPv6);
|
||||
retryTimer.stop();
|
||||
_waitForConnectedTimer.stop();
|
||||
|
||||
setState(MTProtoConnection::Connecting);
|
||||
_pingId = _pingMsgId = _pingIdToSend = _pingSendAt = 0;
|
||||
_pingSender.stop();
|
||||
|
||||
if (!noIPv4) DEBUG_LOG(("MTP Info: creating IPv4 connection to %1:%2..").arg(ip4.c_str()).arg(port4));
|
||||
if (!noIPv6) DEBUG_LOG(("MTP Info: creating IPv6 connection to [%1]:%2..").arg(ip6.c_str()).arg(port6));
|
||||
|
||||
_waitForConnectedTimer.start(_waitForConnected);
|
||||
if (_conn4) {
|
||||
connect(_conn4, SIGNAL(connected()), this, SLOT(onConnected4()));
|
||||
connect(_conn4, SIGNAL(disconnected()), this, SLOT(onDisconnected4()));
|
||||
_conn4->connectToServer(ip4.c_str(), port4, flags4);
|
||||
}
|
||||
if (_conn6) {
|
||||
connect(_conn6, SIGNAL(connected()), this, SLOT(onConnected6()));
|
||||
connect(_conn6, SIGNAL(disconnected()), this, SLOT(onDisconnected6()));
|
||||
_conn6->connectToServer(ip6.c_str(), port6, flags6);
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::restart(bool maybeBadKey) {
|
||||
@ -1783,8 +1830,8 @@ void MTProtoConnectionPrivate::restart(bool maybeBadKey) {
|
||||
|
||||
DEBUG_LOG(("MTP Info: restarting MTProtoConnection, maybe bad key = %1").arg(logBool(maybeBadKey)));
|
||||
|
||||
connCheckTimer.stop();
|
||||
cantConnectTimer.stop();
|
||||
_waitForReceivedTimer.stop();
|
||||
_waitForConnectedTimer.stop();
|
||||
|
||||
mtpAuthKeyPtr key(sessionData->getKey());
|
||||
if (key) {
|
||||
@ -1812,12 +1859,12 @@ void MTProtoConnectionPrivate::restart(bool maybeBadKey) {
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onSentSome(uint64 size) {
|
||||
if (!connCheckTimer.isActive()) {
|
||||
uint64 remain = receiveDelay;
|
||||
if (!_waitForReceivedTimer.isActive()) {
|
||||
uint64 remain = _waitForReceived;
|
||||
if (!oldConnection) {
|
||||
uint64 remainBySize = size * receiveDelay / 8192; // 8kb / sec, so 512 kb give 64 sec
|
||||
uint64 remainBySize = size * _waitForReceived / 8192; // 8kb / sec, so 512 kb give 64 sec
|
||||
remain = snap(remainBySize, remain, uint64(MTPMaxReceiveDelay));
|
||||
if (remain != receiveDelay) {
|
||||
if (remain != _waitForReceived) {
|
||||
DEBUG_LOG(("Checking connect for request with size %1 bytes, delay will be %2").arg(size).arg(remain));
|
||||
}
|
||||
}
|
||||
@ -1826,7 +1873,7 @@ void MTProtoConnectionPrivate::onSentSome(uint64 size) {
|
||||
} else if (dc >= MTP::dld[0] && dc < MTP::dld[MTPDownloadSessionsCount - 1] + _mtp_internal::dcShift) {
|
||||
remain *= MTPDownloadSessionsCount;
|
||||
}
|
||||
connCheckTimer.start(remain);
|
||||
_waitForReceivedTimer.start(remain);
|
||||
}
|
||||
if (!firstSentAt) firstSentAt = getms(true);
|
||||
}
|
||||
@ -1837,20 +1884,20 @@ void MTProtoConnectionPrivate::onReceivedSome() {
|
||||
DEBUG_LOG(("This connection marked as not old!"));
|
||||
}
|
||||
oldConnectionTimer.start(MTPConnectionOldTimeout);
|
||||
connCheckTimer.stop();
|
||||
_waitForReceivedTimer.stop();
|
||||
if (firstSentAt > 0) {
|
||||
int32 ms = getms(true) - firstSentAt;
|
||||
DEBUG_LOG(("MTP Info: response in %1ms, receiveDelay: %2ms").arg(ms).arg(receiveDelay));
|
||||
DEBUG_LOG(("MTP Info: response in %1ms, _waitForReceived: %2ms").arg(ms).arg(_waitForReceived));
|
||||
|
||||
if (ms > 0 && ms * 2 < int32(receiveDelay)) receiveDelay = qMax(ms * 2, int32(MTPMinReceiveDelay));
|
||||
if (ms > 0 && ms * 2 < int32(_waitForReceived)) _waitForReceived = qMax(ms * 2, int32(MTPMinReceiveDelay));
|
||||
firstSentAt = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onOldConnection() {
|
||||
oldConnection = true;
|
||||
receiveDelay = MTPMinReceiveDelay;
|
||||
DEBUG_LOG(("This connection marked as old! delay now %1ms").arg(receiveDelay));
|
||||
_waitForReceived = MTPMinReceiveDelay;
|
||||
DEBUG_LOG(("This connection marked as old! _waitForReceived now %1ms").arg(_waitForReceived));
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onPingSender() {
|
||||
@ -1874,14 +1921,14 @@ void MTProtoConnectionPrivate::onPingSendForce() {
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onBadConnection() {
|
||||
void MTProtoConnectionPrivate::onWaitReceivedFailed() {
|
||||
if (cConnectionType() != dbictAuto && cConnectionType() != dbictTcpProxy) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(("MTP Info: bad connection, delay: %1ms").arg(receiveDelay));
|
||||
if (receiveDelay < MTPMaxReceiveDelay) {
|
||||
receiveDelay *= 2;
|
||||
DEBUG_LOG(("MTP Info: bad connection, _waitForReceived: %1ms").arg(_waitForReceived));
|
||||
if (_waitForReceived < MTPMaxReceiveDelay) {
|
||||
_waitForReceived *= 2;
|
||||
}
|
||||
doDisconnect();
|
||||
restarted = true;
|
||||
@ -1891,9 +1938,9 @@ void MTProtoConnectionPrivate::onBadConnection() {
|
||||
QTimer::singleShot(0, this, SLOT(socketStart()));
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onCantConnect() {
|
||||
DEBUG_LOG(("MTP Info: can't connect in %1ms").arg(connectDelay));
|
||||
if (connectDelay < MTPMaxConnectDelay) connectDelay *= 2;
|
||||
void MTProtoConnectionPrivate::onWaitConnectedFailed() {
|
||||
DEBUG_LOG(("MTP Info: can't connect in %1ms").arg(_waitForConnected));
|
||||
if (_waitForConnected < MTPMaxConnectDelay) _waitForConnected *= 2;
|
||||
|
||||
doDisconnect();
|
||||
restarted = true;
|
||||
@ -1902,16 +1949,21 @@ void MTProtoConnectionPrivate::onCantConnect() {
|
||||
QTimer::singleShot(0, this, SLOT(socketStart()));
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::doDisconnect() {
|
||||
if (conn) {
|
||||
disconnect(conn, SIGNAL(disconnected()), 0, 0);
|
||||
disconnect(conn, SIGNAL(receivedData()), 0, 0);
|
||||
disconnect(conn, SIGNAL(receivedSome()), 0, 0);
|
||||
void MTProtoConnectionPrivate::onWaitIPv4Failed() {
|
||||
_conn = _conn6;
|
||||
destroyConn(&_conn4);
|
||||
|
||||
if (_conn) {
|
||||
DEBUG_LOG(("MTP Info: can't connect through IPv4, using IPv6 connection."));
|
||||
|
||||
conn->disconnectFromServer();
|
||||
conn->deleteLater();
|
||||
conn = 0;
|
||||
updateAuthKey();
|
||||
} else {
|
||||
restart();
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::doDisconnect() {
|
||||
destroyConn();
|
||||
|
||||
unlockKey();
|
||||
|
||||
@ -1946,9 +1998,8 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
return restart();
|
||||
}
|
||||
|
||||
|
||||
while (conn->received().size()) {
|
||||
const mtpBuffer &encryptedBuf(conn->received().front());
|
||||
while (_conn->received().size()) {
|
||||
const mtpBuffer &encryptedBuf(_conn->received().front());
|
||||
uint32 len = encryptedBuf.size();
|
||||
const mtpPrime *encrypted(encryptedBuf.data());
|
||||
if (len < 18) { // 2 auth_key_id, 4 msg_key, 2 salt, 2 session, 2 msg_id, 1 seq_no, 1 length, (1 data + 3 padding) min
|
||||
@ -1976,14 +2027,14 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
if (uint32(dataBuffer.size()) < msgLen + 8 * sizeof(mtpPrime) || (msgLen & 0x03)) {
|
||||
LOG(("TCP Error: bad msg_len received %1, data size: %2").arg(msgLen).arg(dataBuffer.size()));
|
||||
TCP_LOG(("TCP Error: bad message %1").arg(mb(encrypted, len * sizeof(mtpPrime)).str()));
|
||||
conn->received().pop_front();
|
||||
_conn->received().pop_front();
|
||||
return restart();
|
||||
}
|
||||
uchar sha1Buffer[20];
|
||||
if (memcmp(&msgKey, hashSha1(data, msgLen + 8 * sizeof(mtpPrime), sha1Buffer) + 1, sizeof(msgKey))) {
|
||||
LOG(("TCP Error: bad SHA1 hash after aesDecrypt in message"));
|
||||
TCP_LOG(("TCP Error: bad message %1").arg(mb(encrypted, len * sizeof(mtpPrime)).str()));
|
||||
conn->received().pop_front();
|
||||
_conn->received().pop_front();
|
||||
return restart();
|
||||
}
|
||||
TCP_LOG(("TCP Info: decrypted message %1,%2,%3 is %4 len").arg(msgId).arg(seqNo).arg(logBool(needAck)).arg(msgLen + 8 * sizeof(mtpPrime)));
|
||||
@ -1992,11 +2043,11 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
if (session != serverSession) {
|
||||
LOG(("MTP Error: bad server session received"));
|
||||
TCP_LOG(("MTP Error: bad server session %1 instead of %2 in message received").arg(session).arg(serverSession));
|
||||
conn->received().pop_front();
|
||||
_conn->received().pop_front();
|
||||
return restart();
|
||||
}
|
||||
|
||||
conn->received().pop_front();
|
||||
_conn->received().pop_front();
|
||||
|
||||
int32 serverTime((int32)(msgId >> 32)), clientTime(unixtime());
|
||||
bool isReply = ((msgId & 0x03) == 1);
|
||||
@ -2079,6 +2130,7 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
_needSessionReset = (res < -1);
|
||||
return restart();
|
||||
}
|
||||
retryTimeout = 1; // reset restart() timer
|
||||
|
||||
if (!sessionData->isCheckedKey()) {
|
||||
DEBUG_LOG(("MTP Info: marked auth key as checked"));
|
||||
@ -2091,7 +2143,7 @@ void MTProtoConnectionPrivate::handleReceived() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (conn->needHttpWait()) {
|
||||
if (_conn->needHttpWait()) {
|
||||
emit sendHttpWaitAsync();
|
||||
}
|
||||
}
|
||||
@ -2588,8 +2640,6 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt
|
||||
}
|
||||
}
|
||||
requestsAcked(ids, true);
|
||||
|
||||
retryTimeout = 1; // reset restart() timer
|
||||
} return 1;
|
||||
|
||||
}
|
||||
@ -2836,27 +2886,72 @@ void MTProtoConnectionPrivate::resendMany(QVector<quint64> msgIds, quint64 msCan
|
||||
emit resendManyAsync(msgIds, msCanWait, forceContainer, sendMsgStateInfo);
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onConnected() {
|
||||
connectDelay = MTPMinConnectDelay;
|
||||
cantConnectTimer.stop();
|
||||
void MTProtoConnectionPrivate::onConnected4() {
|
||||
_waitForConnected = MTPMinConnectDelay;
|
||||
_waitForConnectedTimer.stop();
|
||||
|
||||
_waitForIPv4Timer.stop();
|
||||
|
||||
QReadLocker lockFinished(&sessionDataMutex);
|
||||
if (!sessionData) return;
|
||||
|
||||
disconnect(conn, SIGNAL(connected()), this, SLOT(onConnected()));
|
||||
if (!conn->isConnected()) {
|
||||
LOG(("Connection Error: not connected in onConnected(), state: %1").arg(conn->debugState()));
|
||||
disconnect(_conn4, SIGNAL(connected()), this, SLOT(onConnected4()));
|
||||
if (!_conn4->isConnected()) {
|
||||
LOG(("Connection Error: not connected in onConnected4(), state: %1").arg(_conn4->debugState()));
|
||||
return restart();
|
||||
}
|
||||
|
||||
TCP_LOG(("Connection Info: connection succeed."));
|
||||
_conn = _conn4;
|
||||
destroyConn(&_conn6);
|
||||
|
||||
DEBUG_LOG(("MTP Info: connection through IPv4 succeed."));
|
||||
|
||||
updateAuthKey();
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onConnected6() {
|
||||
_waitForConnected = MTPMinConnectDelay;
|
||||
_waitForConnectedTimer.stop();
|
||||
|
||||
QReadLocker lockFinished(&sessionDataMutex);
|
||||
if (!sessionData) return;
|
||||
|
||||
disconnect(_conn6, SIGNAL(connected()), this, SLOT(onConnected()));
|
||||
if (!_conn6->isConnected()) {
|
||||
LOG(("Connection Error: not connected in onConnected(), state: %1").arg(_conn6->debugState()));
|
||||
return restart();
|
||||
}
|
||||
|
||||
DEBUG_LOG(("MTP Info: connection through IPv6 succeed, waiting IPv4 for %1ms.").arg(MTPIPv4ConnectionWaitTimeout));
|
||||
|
||||
_waitForIPv4Timer.start(MTPIPv4ConnectionWaitTimeout);
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onDisconnected4() {
|
||||
if (_conn && _conn == _conn6) return; // disconnected the unused
|
||||
|
||||
if (_conn || !_conn6) {
|
||||
destroyConn();
|
||||
restart();
|
||||
} else {
|
||||
destroyConn(&_conn4);
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onDisconnected6() {
|
||||
if (_conn && _conn == _conn4) return; // disconnected the unused
|
||||
|
||||
if (_conn || !_conn4) {
|
||||
destroyConn();
|
||||
restart();
|
||||
} else {
|
||||
destroyConn(&_conn6);
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::updateAuthKey() {
|
||||
QReadLocker lockFinished(&sessionDataMutex);
|
||||
if (!sessionData || !conn) return;
|
||||
if (!sessionData || !_conn) return;
|
||||
|
||||
DEBUG_LOG(("AuthKey Info: MTProtoConnection updating key from MTProtoSession, dc %1").arg(dc));
|
||||
uint64 newKeyId = 0;
|
||||
@ -2899,20 +2994,20 @@ void MTProtoConnectionPrivate::updateAuthKey() {
|
||||
MTPReq_pq req_pq;
|
||||
req_pq.vnonce = authKeyData->nonce;
|
||||
|
||||
connect(conn, SIGNAL(receivedData()), this, SLOT(pqAnswered()));
|
||||
connect(_conn, SIGNAL(receivedData()), this, SLOT(pqAnswered()));
|
||||
|
||||
DEBUG_LOG(("AuthKey Info: sending Req_pq.."));
|
||||
sendRequestNotSecure(req_pq);
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::clearMessages() {
|
||||
if (keyId && keyId != mtpAuthKey::RecreateKeyId && conn) {
|
||||
conn->received().clear();
|
||||
if (keyId && keyId != mtpAuthKey::RecreateKeyId && _conn) {
|
||||
_conn->received().clear();
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::pqAnswered() {
|
||||
disconnect(conn, SIGNAL(receivedData()), this, SLOT(pqAnswered()));
|
||||
disconnect(_conn, SIGNAL(receivedData()), this, SLOT(pqAnswered()));
|
||||
DEBUG_LOG(("AuthKey Info: receiving Req_pq answer.."));
|
||||
|
||||
MTPReq_pq::ResponseType res_pq;
|
||||
@ -3008,14 +3103,14 @@ void MTProtoConnectionPrivate::pqAnswered() {
|
||||
return restart();
|
||||
}
|
||||
|
||||
connect(conn, SIGNAL(receivedData()), this, SLOT(dhParamsAnswered()));
|
||||
connect(_conn, SIGNAL(receivedData()), this, SLOT(dhParamsAnswered()));
|
||||
|
||||
DEBUG_LOG(("AuthKey Info: sending Req_DH_params.."));
|
||||
sendRequestNotSecure(req_DH_params);
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::dhParamsAnswered() {
|
||||
disconnect(conn, SIGNAL(receivedData()), this, SLOT(dhParamsAnswered()));
|
||||
disconnect(_conn, SIGNAL(receivedData()), this, SLOT(dhParamsAnswered()));
|
||||
DEBUG_LOG(("AuthKey Info: receiving Req_DH_params answer.."));
|
||||
|
||||
MTPReq_DH_params::ResponseType res_DH_params;
|
||||
@ -3190,7 +3285,7 @@ void MTProtoConnectionPrivate::dhClientParamsSend() {
|
||||
|
||||
aesEncrypt(&encBuffer[0], &sdhEncString[0], encFullSize * sizeof(mtpPrime), authKeyData->aesKey, authKeyData->aesIV);
|
||||
|
||||
connect(conn, SIGNAL(receivedData()), this, SLOT(dhClientParamsAnswered()));
|
||||
connect(_conn, SIGNAL(receivedData()), this, SLOT(dhClientParamsAnswered()));
|
||||
|
||||
DEBUG_LOG(("AuthKey Info: sending Req_client_DH_params.."));
|
||||
sendRequestNotSecure(req_client_DH_params);
|
||||
@ -3200,7 +3295,7 @@ void MTProtoConnectionPrivate::dhClientParamsAnswered() {
|
||||
QReadLocker lockFinished(&sessionDataMutex);
|
||||
if (!sessionData) return;
|
||||
|
||||
disconnect(conn, SIGNAL(receivedData()), this, SLOT(dhClientParamsAnswered()));
|
||||
disconnect(_conn, SIGNAL(receivedData()), this, SLOT(dhClientParamsAnswered()));
|
||||
DEBUG_LOG(("AuthKey Info: receiving Req_client_DH_params answer.."));
|
||||
|
||||
MTPSet_client_DH_params::ResponseType res_client_DH_params;
|
||||
@ -3295,7 +3390,7 @@ void MTProtoConnectionPrivate::dhClientParamsAnswered() {
|
||||
void MTProtoConnectionPrivate::authKeyCreated() {
|
||||
clearAuthKeyData();
|
||||
|
||||
connect(conn, SIGNAL(receivedData()), this, SLOT(handleReceived()));
|
||||
connect(_conn, SIGNAL(receivedData()), this, SLOT(handleReceived()));
|
||||
|
||||
if (sessionData->getSalt()) { // else receive salt in bad_server_salt first, then try to send all the requests
|
||||
setState(MTProtoConnection::Connected);
|
||||
@ -3328,11 +3423,32 @@ void MTProtoConnectionPrivate::clearAuthKeyData() {
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onError(bool mayBeBadKey) {
|
||||
cantConnectTimer.stop();
|
||||
void MTProtoConnectionPrivate::onError4(bool mayBeBadKey) {
|
||||
if (_conn && _conn == _conn6) return; // error in the unused
|
||||
|
||||
MTP_LOG(dc, ("Restarting after error, maybe bad key: %1..").arg(logBool(mayBeBadKey)));
|
||||
return restart(mayBeBadKey);
|
||||
if (_conn || !_conn6) {
|
||||
destroyConn();
|
||||
_waitForConnectedTimer.stop();
|
||||
|
||||
MTP_LOG(dc, ("Restarting after error in IPv4 connection, maybe bad key: %1..").arg(logBool(mayBeBadKey)));
|
||||
return restart(mayBeBadKey);
|
||||
} else {
|
||||
destroyConn(&_conn4);
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onError6(bool mayBeBadKey) {
|
||||
if (_conn && _conn == _conn4) return; // error in the unused
|
||||
|
||||
if (_conn || !_conn4) {
|
||||
destroyConn();
|
||||
_waitForConnectedTimer.stop();
|
||||
|
||||
MTP_LOG(dc, ("Restarting after error in IPv6 connection, maybe bad key: %1..").arg(logBool(mayBeBadKey)));
|
||||
return restart(mayBeBadKey);
|
||||
} else {
|
||||
destroyConn(&_conn6);
|
||||
}
|
||||
}
|
||||
|
||||
void MTProtoConnectionPrivate::onReadyData() {
|
||||
@ -3359,7 +3475,7 @@ void MTProtoConnectionPrivate::sendRequestNotSecure(const TRequest &request) {
|
||||
|
||||
DEBUG_LOG(("AuthKey Info: sending request, size: %1, num: %2, time: %3").arg(requestSize).arg(authKeyData->req_num).arg(buffer[5]));
|
||||
|
||||
conn->sendData(buffer);
|
||||
_conn->sendData(buffer);
|
||||
|
||||
onSentSome(buffer.size() * sizeof(mtpPrime));
|
||||
|
||||
@ -3373,12 +3489,12 @@ bool MTProtoConnectionPrivate::readResponseNotSecure(TResponse &response) {
|
||||
onReceivedSome();
|
||||
|
||||
try {
|
||||
if (conn->received().isEmpty()) {
|
||||
if (_conn->received().isEmpty()) {
|
||||
LOG(("AuthKey Error: trying to read response from empty received list"));
|
||||
return false;
|
||||
}
|
||||
mtpBuffer buffer(conn->received().front());
|
||||
conn->received().pop_front();
|
||||
mtpBuffer buffer(_conn->received().front());
|
||||
_conn->received().pop_front();
|
||||
|
||||
const mtpPrime *answer(buffer.constData());
|
||||
uint32 len = buffer.size();
|
||||
@ -3449,8 +3565,8 @@ bool MTProtoConnectionPrivate::sendRequest(mtpRequest &request, bool needAnyResp
|
||||
|
||||
DEBUG_LOG(("MTP Info: sending request, size: %1, num: %2, time: %3").arg(fullSize + 6).arg((*request)[4]).arg((*request)[5]));
|
||||
|
||||
conn->setSentEncrypted();
|
||||
conn->sendData(result);
|
||||
_conn->setSentEncrypted();
|
||||
_conn->sendData(result);
|
||||
|
||||
if (needAnyResponse) {
|
||||
onSentSome(result.size() * sizeof(mtpPrime));
|
||||
|
@ -25,9 +25,23 @@ enum {
|
||||
MTPDmessage_flag_out = (1 << 1),
|
||||
MTPDmessage_flag_notify_by_from = (1 << 4),
|
||||
MTPDmessage_flag_media_unread = (1 << 5),
|
||||
|
||||
MTPmessages_SendMessage_flag_skipWebPage = (1 << 1),
|
||||
|
||||
MTPDdcOption_flag_ipv6 = (1 << 0),
|
||||
MTPDdcOption_flag_files = (1 << 1),
|
||||
|
||||
MTPDuser_flag_self = (1 << 10),
|
||||
MTPDuser_flag_contact = (1 << 11),
|
||||
MTPDuser_flag_mutual_contact = (1 << 12),
|
||||
MTPDuser_flag_deleted = (1 << 13),
|
||||
MTPDuser_flag_bot = (1 << 14),
|
||||
MTPDuser_flag_bot_reads_all = (1 << 15),
|
||||
MTPDuser_flag_bot_cant_join = (1 << 16),
|
||||
};
|
||||
|
||||
static const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_vector<MTPKeyboardButtonRow>(0));
|
||||
|
||||
#include "mtproto/mtpPublicRSA.h"
|
||||
#include "mtproto/mtpAuthKey.h"
|
||||
|
||||
@ -97,11 +111,6 @@ public:
|
||||
int32 state() const;
|
||||
QString transport() const;
|
||||
|
||||
/*template <typename TRequest> // not used
|
||||
uint64 sendAsync(const TRequest &request) {
|
||||
return data->sendAsync(request);
|
||||
}*/
|
||||
|
||||
private:
|
||||
|
||||
QThread *thread;
|
||||
@ -125,7 +134,7 @@ public:
|
||||
|
||||
virtual void sendData(mtpBuffer &buffer) = 0; // has size + 3, buffer[0] = len, buffer[1] = packetnum, buffer[last] = crc32
|
||||
virtual void disconnectFromServer() = 0;
|
||||
virtual void connectToServer(const QString &addr, int32 port) = 0;
|
||||
virtual void connectToServer(const QString &addr, int32 port, int32 flags) = 0;
|
||||
virtual bool isConnected() = 0;
|
||||
virtual bool usingHttpWait() {
|
||||
return false;
|
||||
@ -193,7 +202,7 @@ public:
|
||||
|
||||
void sendData(mtpBuffer &buffer);
|
||||
void disconnectFromServer();
|
||||
void connectToServer(const QString &addr, int32 port);
|
||||
void connectToServer(const QString &addr, int32 port, int32 flags);
|
||||
bool isConnected();
|
||||
bool usingHttpWait();
|
||||
bool needHttpWait();
|
||||
@ -255,7 +264,7 @@ public:
|
||||
|
||||
void sendData(mtpBuffer &buffer);
|
||||
void disconnectFromServer();
|
||||
void connectToServer(const QString &addr, int32 port);
|
||||
void connectToServer(const QString &addr, int32 port, int32 flags);
|
||||
bool isConnected();
|
||||
|
||||
int32 debugState() const;
|
||||
@ -281,7 +290,7 @@ public:
|
||||
|
||||
void sendData(mtpBuffer &buffer);
|
||||
void disconnectFromServer();
|
||||
void connectToServer(const QString &addr, int32 port);
|
||||
void connectToServer(const QString &addr, int32 port, int32 flags);
|
||||
bool isConnected();
|
||||
bool usingHttpWait();
|
||||
bool needHttpWait();
|
||||
@ -343,16 +352,25 @@ public slots:
|
||||
|
||||
void onPingSender();
|
||||
void onPingSendForce();
|
||||
void onBadConnection();
|
||||
void onCantConnect();
|
||||
|
||||
void onWaitConnectedFailed();
|
||||
void onWaitReceivedFailed();
|
||||
void onWaitIPv4Failed();
|
||||
|
||||
void onOldConnection();
|
||||
void onSentSome(uint64 size);
|
||||
void onReceivedSome();
|
||||
|
||||
void onError(bool maybeBadKey = false);
|
||||
void onReadyData();
|
||||
void socketStart(bool afterConfig = false);
|
||||
void onConnected();
|
||||
|
||||
void onConnected4();
|
||||
void onConnected6();
|
||||
void onDisconnected4();
|
||||
void onDisconnected6();
|
||||
void onError4(bool maybeBadKey = false);
|
||||
void onError6(bool maybeBadKey = false);
|
||||
|
||||
void doDisconnect();
|
||||
void doFinish();
|
||||
|
||||
@ -373,7 +391,8 @@ public slots:
|
||||
|
||||
private:
|
||||
|
||||
void createConn();
|
||||
void createConn(bool createIPv4, bool createIPv6);
|
||||
void destroyConn(MTPabstractConnection **conn = 0); // 0 - destory all
|
||||
|
||||
mtpMsgId placeToContainer(mtpRequest &toSendRequest, mtpMsgId &bigMsgId, mtpMsgId *&haveSentArr, mtpRequest &req);
|
||||
mtpMsgId prepareToSend(mtpRequest &request, mtpMsgId currentLastId);
|
||||
@ -397,7 +416,7 @@ private:
|
||||
|
||||
uint32 dc;
|
||||
MTProtoConnection *_owner;
|
||||
MTPabstractConnection *conn;
|
||||
MTPabstractConnection *_conn, *_conn4, *_conn6;
|
||||
|
||||
SingleTimer retryTimer; // exp retry timer
|
||||
uint32 retryTimeout;
|
||||
@ -406,8 +425,8 @@ private:
|
||||
SingleTimer oldConnectionTimer;
|
||||
bool oldConnection;
|
||||
|
||||
SingleTimer connCheckTimer, cantConnectTimer;
|
||||
uint32 receiveDelay, connectDelay;
|
||||
SingleTimer _waitForConnectedTimer, _waitForReceivedTimer, _waitForIPv4Timer;
|
||||
uint32 _waitForReceived, _waitForConnected;
|
||||
int64 firstSentAt;
|
||||
|
||||
QVector<MTPlong> ackRequestData, resendRequestData;
|
||||
|
@ -366,7 +366,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||
mtpc_invokeWithLayer17,
|
||||
mtpc_invokeWithLayer18,
|
||||
}, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||
static const mtpPrime mtpCurrentLayer = 29;
|
||||
static const mtpPrime mtpCurrentLayer = 31;
|
||||
|
||||
template <typename bareT>
|
||||
class MTPBoxed : public bareT {
|
||||
|
@ -175,15 +175,16 @@ void mtpUpdateDcOptions(const QVector<MTPDcOption> &options) {
|
||||
}
|
||||
for (QVector<MTPDcOption>::const_iterator i = options.cbegin(), e = options.cend(); i != e; ++i) {
|
||||
const MTPDdcOption &optData(i->c_dcOption());
|
||||
if (already.constFind(optData.vid.v) == already.cend()) {
|
||||
already.insert(optData.vid.v);
|
||||
mtpDcOptions::const_iterator a = opts.constFind(optData.vid.v);
|
||||
int32 id = optData.vid.v, idWithShift = id + (optData.vflags.v * _mtp_internal::dcShift);
|
||||
if (already.constFind(idWithShift) == already.cend()) {
|
||||
already.insert(idWithShift);
|
||||
mtpDcOptions::const_iterator a = opts.constFind(idWithShift);
|
||||
if (a != opts.cend()) {
|
||||
if (a.value().ip != optData.vip_address.c_string().v || a.value().port != optData.vport.v) {
|
||||
restart.insert(optData.vid.v);
|
||||
restart.insert(id);
|
||||
}
|
||||
}
|
||||
opts.insert(optData.vid.v, mtpDcOption(optData.vid.v, optData.vhostname.c_string().v, optData.vip_address.c_string().v, optData.vport.v));
|
||||
opts.insert(idWithShift, mtpDcOption(id, optData.vflags.v, optData.vip_address.c_string().v, optData.vport.v));
|
||||
}
|
||||
}
|
||||
{
|
||||
|
@ -1109,96 +1109,24 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_userSelf:
|
||||
case mtpc_user:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ userSelf");
|
||||
to.add("{ user");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_userContact:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ userContact");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 7: to.add(" status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_userRequest:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ userRequest");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" phone: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 7: to.add(" status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_userForeign:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ userForeign");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" status: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_userDeleted:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ userDeleted");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" username: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" access_hash: "); ++stages.back(); if (flag & MTPDuser::flag_access_hash) { types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||
case 3: to.add(" first_name: "); ++stages.back(); if (flag & MTPDuser::flag_first_name) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||
case 4: to.add(" last_name: "); ++stages.back(); if (flag & MTPDuser::flag_last_name) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
case 5: to.add(" username: "); ++stages.back(); if (flag & MTPDuser::flag_username) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
case 6: to.add(" phone: "); ++stages.back(); if (flag & MTPDuser::flag_phone) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
|
||||
case 7: to.add(" photo: "); ++stages.back(); if (flag & MTPDuser::flag_photo) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
|
||||
case 8: to.add(" status: "); ++stages.back(); if (flag & MTPDuser::flag_status) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||
case 9: to.add(" bot_info_version: "); ++stages.back(); if (flag & MTPDuser::flag_bot_info_version) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 14 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@ -1347,6 +1275,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 2: to.add(" chat_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" exported_invite: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" bot_info: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@ -1444,6 +1373,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 7: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 8: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 9: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 10: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPDmessage::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@ -1893,8 +1823,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" expires: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" user: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 0: to.add(" user: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@ -2048,8 +1977,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 2: to.add(" profile_photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" notify_settings: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" blocked: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" real_first_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" real_last_name: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" bot_info: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@ -3057,8 +2985,8 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" hostname: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" ip_address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" port: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
@ -4353,6 +4281,81 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_botCommand:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ botCommand");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" command: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" params: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" description: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_botInfoEmpty:
|
||||
to.add("{ botInfoEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_botInfo:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ botInfo");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" share_text: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" description: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" commands: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_keyboardButton:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ keyboardButton");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" text: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_keyboardButtonRow:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ keyboardButtonRow");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" buttons: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_replyKeyboardMarkup:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ replyKeyboardMarkup");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" rows: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_req_pq:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -5018,6 +5021,22 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_auth_importBotAuthorization:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ auth_importBotAuthorization");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" flags: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" api_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" api_hash: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" bot_auth_token: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_auth_checkPassword:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -5388,6 +5407,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 2: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||
case 3: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMessage::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@ -5405,6 +5425,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 2: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMedia::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||
case 3: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMedia::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -193,11 +193,6 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
|
||||
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
|
||||
|
||||
userEmpty#200250ba id:int = User;
|
||||
userSelf#1c60e608 id:int first_name:string last_name:string username:string phone:string photo:UserProfilePhoto status:UserStatus = User;
|
||||
userContact#cab35e18 id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
|
||||
userRequest#d9ccc4ef id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
|
||||
userForeign#75cf7a8 id:int first_name:string last_name:string username:string access_hash:long photo:UserProfilePhoto status:UserStatus = User;
|
||||
userDeleted#d6016d7a id:int first_name:string last_name:string username:string = User;
|
||||
|
||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
|
||||
@ -210,7 +205,7 @@ chatEmpty#9ba2d800 id:int = Chat;
|
||||
chat#6e9c9bc7 id:int title:string photo:ChatPhoto participants_count:int date:int left:Bool version:int = Chat;
|
||||
chatForbidden#fb0ccc41 id:int title:string date:int = Chat;
|
||||
|
||||
chatFull#cade0791 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite = ChatFull;
|
||||
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
|
||||
|
||||
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
|
||||
|
||||
@ -221,7 +216,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
|
||||
|
||||
messageEmpty#83e5de54 id:int = Message;
|
||||
message#a7ab1991 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:MessageMedia = Message;
|
||||
message#c3060325 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:MessageMedia reply_markup:flags.6?ReplyMarkup = Message;
|
||||
messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
@ -258,7 +253,7 @@ auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone;
|
||||
|
||||
auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
|
||||
|
||||
auth.authorization#f6b673a4 expires:int user:User = auth.Authorization;
|
||||
auth.authorization#ff036af1 user:User = auth.Authorization;
|
||||
|
||||
auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorization;
|
||||
|
||||
@ -280,7 +275,7 @@ peerNotifySettings#8d5e11ee mute_until:int sound:string show_previews:Bool event
|
||||
|
||||
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
|
||||
|
||||
userFull#771095da user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool real_first_name:string real_last_name:string = UserFull;
|
||||
userFull#5a89ac5b user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool bot_info:BotInfo = UserFull;
|
||||
|
||||
contact#f911c994 user_id:int mutual:Bool = Contact;
|
||||
|
||||
@ -363,7 +358,7 @@ photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
|
||||
|
||||
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
|
||||
|
||||
dcOption#2ec2a43c id:int hostname:string ip_address:string port:int = DcOption;
|
||||
dcOption#5d8c6cc flags:# id:int ip_address:string port:int = DcOption;
|
||||
|
||||
config#4e32b894 date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int disabled_features:Vector<DisabledFeature> = Config;
|
||||
|
||||
@ -596,6 +591,19 @@ stickerSet#a7a43b17 id:long access_hash:long title:string short_name:string = St
|
||||
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
|
||||
user#22e49072 flags:# id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int = User;
|
||||
|
||||
botCommand#b79d22ab command:string params:string description:string = BotCommand;
|
||||
|
||||
botInfoEmpty#bb2e37ce = BotInfo;
|
||||
botInfo#9cf585d user_id:int version:int share_text:string description:string commands:Vector<BotCommand> = BotInfo;
|
||||
|
||||
keyboardButton#a2fa4880 text:string = KeyboardButton;
|
||||
|
||||
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
|
||||
|
||||
replyKeyboardMarkup#d59bfc31 rows:Vector<KeyboardButtonRow> = ReplyMarkup;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -647,8 +655,8 @@ messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHis
|
||||
messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
|
||||
messages.sendMessage#9add8f26 flags:# peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long = messages.SentMessage;
|
||||
messages.sendMedia#2d7923b1 flags:# peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long = Updates;
|
||||
messages.sendMessage#fc55e6b5 flags:# peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup = messages.SentMessage;
|
||||
messages.sendMedia#c8f16791 flags:# peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
|
||||
messages.forwardMessages#55e1728d peer:InputPeer id:Vector<int> random_id:Vector<long> = Updates;
|
||||
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
||||
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
|
||||
@ -736,6 +744,8 @@ messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;
|
||||
|
||||
account.updateDeviceLocked#38df3532 period:int = Bool;
|
||||
|
||||
auth.importBotAuthorization#67a3ff2c flags:int api_id:int api_hash:string bot_auth_token:string = auth.Authorization;
|
||||
|
||||
messages.getWebPagePreview#25223e24 message:string = MessageMedia;
|
||||
|
||||
account.getAuthorizations#e320c158 = account.Authorizations;
|
||||
|
@ -325,13 +325,13 @@ void ProfileInner::updateOnlineDisplayTimer() {
|
||||
if (_peerChat->participants.isEmpty()) return;
|
||||
|
||||
for (ChatData::Participants::const_iterator i = _peerChat->participants.cbegin(), e = _peerChat->participants.cend(); i != e; ++i) {
|
||||
int32 onlineWillChangeIn = App::onlineWillChangeIn(i.key()->onlineTill, t);
|
||||
int32 onlineWillChangeIn = App::onlineWillChangeIn(i.key(), t);
|
||||
if (onlineWillChangeIn < minIn) {
|
||||
minIn = onlineWillChangeIn;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
minIn = App::onlineWillChangeIn(_peerUser->onlineTill, t);
|
||||
minIn = App::onlineWillChangeIn(_peerUser, t);
|
||||
}
|
||||
App::main()->updateOnlineDisplayIn(minIn * 1000);
|
||||
}
|
||||
@ -354,13 +354,13 @@ void ProfileInner::reorderParticipants() {
|
||||
bool onlyMe = true;
|
||||
for (ChatData::Participants::const_iterator i = _peerChat->participants.cbegin(), e = _peerChat->participants.cend(); i != e; ++i) {
|
||||
UserData *user = i.key();
|
||||
int32 until = App::onlineForSort(user->onlineTill, t);
|
||||
int32 until = App::onlineForSort(user, t);
|
||||
Participants::iterator before = _participants.begin();
|
||||
if (user != self) {
|
||||
if (before != _participants.end() && (*before) == self) {
|
||||
++before;
|
||||
}
|
||||
while (before != _participants.end() && App::onlineForSort((*before)->onlineTill, t) >= until) {
|
||||
while (before != _participants.end() && App::onlineForSort(*before, t) >= until) {
|
||||
++before;
|
||||
}
|
||||
if (until > t && onlyMe) onlyMe = false;
|
||||
|
@ -53,11 +53,11 @@ inline bool rtl() {
|
||||
}
|
||||
|
||||
struct mtpDcOption {
|
||||
mtpDcOption(int _id, const string &_host, const string &_ip, int _port) : id(_id), host(_host), ip(_ip), port(_port) {
|
||||
mtpDcOption(int id, int flags, const string &ip, int port) : id(id), flags(flags), ip(ip), port(port) {
|
||||
}
|
||||
|
||||
int id;
|
||||
string host;
|
||||
int flags;
|
||||
string ip;
|
||||
int port;
|
||||
};
|
||||
|
@ -201,10 +201,58 @@ void UserData::setPhone(const QString &newPhone) {
|
||||
++nameVersion;
|
||||
}
|
||||
|
||||
void UserData::setBotInfoVersion(int32 version) {
|
||||
if (!botInfo) {
|
||||
botInfo = new BotInfo();
|
||||
botInfo->version = version;
|
||||
} else if (botInfo->version < version) {
|
||||
botInfo->commands.clear();
|
||||
botInfo->description.clear();
|
||||
botInfo->shareText.clear();
|
||||
botInfo->version = version;
|
||||
}
|
||||
}
|
||||
void UserData::setBotInfo(const MTPBotInfo &info) {
|
||||
switch (info.type()) {
|
||||
case mtpc_botInfoEmpty:
|
||||
delete botInfo;
|
||||
botInfo = 0;
|
||||
break;
|
||||
case mtpc_botInfo: {
|
||||
const MTPDbotInfo &d(info.c_botInfo());
|
||||
if (d.vuser_id.v != id) return;
|
||||
setBotInfoVersion(d.vversion.v);
|
||||
if (botInfo->version > d.vversion.v) return;
|
||||
botInfo->description = qs(d.vdescription);
|
||||
botInfo->shareText = qs(d.vshare_text);
|
||||
|
||||
const QVector<MTPBotCommand> &v(d.vcommands.c_vector().v);
|
||||
botInfo->commands.clear();
|
||||
botInfo->commands.reserve(v.size());
|
||||
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
||||
if (v.at(i).type() == mtpc_botCommand) {
|
||||
botInfo->commands.push_back(BotCommand(qs(v.at(i).c_botCommand().vcommand), qs(v.at(i).c_botCommand().vparams), qs(v.at(i).c_botCommand().vdescription)));
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void UserData::nameUpdated() {
|
||||
nameText.setText(st::msgNameFont, name, _textNameOptions);
|
||||
}
|
||||
|
||||
void UserData::madeAction() {
|
||||
int32 t = unixtime();
|
||||
if (onlineTill <= 0 && -onlineTill < t) {
|
||||
onlineTill = -t - SetOnlineAfterActivity;
|
||||
if (App::main()) App::main()->peerUpdated(this);
|
||||
} else if (onlineTill > 0 && onlineTill < t + 1) {
|
||||
onlineTill = t + SetOnlineAfterActivity;
|
||||
if (App::main()) App::main()->peerUpdated(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) {
|
||||
switch (p.type()) {
|
||||
case mtpc_chatPhoto: {
|
||||
|
@ -118,15 +118,30 @@ private:
|
||||
PeerData *_peer;
|
||||
};
|
||||
|
||||
struct BotCommand {
|
||||
BotCommand(const QString &command, const QString ¶ms, const QString &description) : command(command), params(params), description(description) {
|
||||
}
|
||||
QString command, params, description;
|
||||
};
|
||||
struct BotInfo {
|
||||
int32 version;
|
||||
QString shareText, description;
|
||||
QList<BotCommand> commands;
|
||||
};
|
||||
|
||||
struct PhotoData;
|
||||
struct UserData : public PeerData {
|
||||
UserData(const PeerId &id) : PeerData(id), lnk(new PeerLink(this)), onlineTill(0), contact(-1), photosCount(-1) {
|
||||
UserData(const PeerId &id) : PeerData(id), lnk(new PeerLink(this)), photoId(0), onlineTill(0), contact(-1), photosCount(-1), botInfo(0) {
|
||||
}
|
||||
void setPhoto(const MTPUserProfilePhoto &photo);
|
||||
void setName(const QString &first, const QString &last, const QString &phoneName, const QString &username);
|
||||
void setPhone(const QString &newPhone);
|
||||
void setBotInfoVersion(int32 version);
|
||||
void setBotInfo(const MTPBotInfo &info);
|
||||
void nameUpdated();
|
||||
|
||||
void madeAction(); // pseudo-online
|
||||
|
||||
QString firstName;
|
||||
QString lastName;
|
||||
QString username;
|
||||
@ -140,6 +155,8 @@ struct UserData : public PeerData {
|
||||
typedef QList<PhotoData*> Photos;
|
||||
Photos photos;
|
||||
int32 photosCount; // -1 not loaded, 0 all loaded
|
||||
|
||||
BotInfo *botInfo;
|
||||
};
|
||||
|
||||
struct ChatData : public PeerData {
|
||||
@ -164,6 +181,10 @@ struct ChatData : public PeerData {
|
||||
// geo
|
||||
};
|
||||
|
||||
inline int32 newMessageFlags(PeerData *p) {
|
||||
return (p->input.type() == mtpc_inputPeerSelf) ? 0 : (((p->chat || !p->asUser()->botInfo) ? MTPDmessage_flag_unread : 0) | MTPDmessage_flag_out);
|
||||
}
|
||||
|
||||
typedef QMap<char, QPixmap> PreparedPhotoThumbs;
|
||||
struct PhotoData {
|
||||
PhotoData(const PhotoId &id, const uint64 &access = 0, int32 user = 0, int32 date = 0, const ImagePtr &thumb = ImagePtr(), const ImagePtr &medium = ImagePtr(), const ImagePtr &full = ImagePtr()) :
|
||||
|
@ -233,7 +233,7 @@ QString rusKeyboardLayoutSwitch(const QString &from);
|
||||
enum DataBlockId {
|
||||
dbiKey = 0x00,
|
||||
dbiUser = 0x01,
|
||||
dbiDcOption = 0x02,
|
||||
dbiDcOptionOld = 0x02,
|
||||
dbiMaxGroupCount = 0x03,
|
||||
dbiMutePeer = 0x04,
|
||||
dbiSendKey = 0x05,
|
||||
@ -270,6 +270,7 @@ enum DataBlockId {
|
||||
dbiRecentEmojis = 0x24,
|
||||
dbiEmojiVariants = 0x25,
|
||||
dbiRecentStickers = 0x26,
|
||||
dbiDcOption = 0x27,
|
||||
|
||||
dbiEncryptedWithSalt = 333,
|
||||
dbiEncrypted = 444,
|
||||
|
@ -606,7 +606,8 @@ void Window::sendServiceHistoryRequest() {
|
||||
|
||||
UserData *user = App::userLoaded(ServiceUserId);
|
||||
if (!user) {
|
||||
user = App::feedUsers(MTP_vector<MTPUser>(1, MTP_userRequest(MTP_int(ServiceUserId), MTP_string("Telegram"), MTP_string(""), MTP_string(""), MTP_long(-1), MTP_string("42777"), MTP_userProfilePhotoEmpty(), MTP_userStatusRecently())));
|
||||
int32 userFlags = MTPDuser::flag_first_name | MTPDuser::flag_phone | MTPDuser::flag_status;
|
||||
user = App::feedUsers(MTP_vector<MTPUser>(1, MTP_user(MTP_int(userFlags), MTP_int(ServiceUserId), MTPlong(), MTP_string("Telegram"), MTPstring(), MTPstring(), MTP_string("42777"), MTP_userProfilePhotoEmpty(), MTP_userStatusRecently(), MTPint())));
|
||||
}
|
||||
_serviceHistoryRequest = MTP::send(MTPmessages_GetHistory(user->input, MTP_int(0), MTP_int(0), MTP_int(1)), main->rpcDone(&MainWidget::serviceHistoryDone), main->rpcFail(&MainWidget::serviceHistoryFail));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user