Use 48 bit [User/Chat/Channel]Id, 56 bit PeerId.

This commit is contained in:
John Preston 2021-04-02 01:04:10 +04:00
parent 61d0cc38b0
commit 1342077dcb
83 changed files with 904 additions and 475 deletions

View file

@ -420,6 +420,8 @@ PRIVATE
data/data_notify_settings.h data/data_notify_settings.h
data/data_peer.cpp data/data_peer.cpp
data/data_peer.h data/data_peer.h
data/data_peer_id.cpp
data/data_peer_id.h
data/data_peer_values.cpp data/data_peer_values.cpp
data/data_peer_values.h data/data_peer_values.h
data/data_photo.cpp data/data_photo.cpp

View file

@ -54,7 +54,7 @@ JoinedByLinkSlice ParseJoinedByLinkSlice(
for (const auto &importer : data.vimporters().v) { for (const auto &importer : data.vimporters().v) {
importer.match([&](const MTPDchatInviteImporter &data) { importer.match([&](const MTPDchatInviteImporter &data) {
result.users.push_back({ result.users.push_back({
.user = owner.user(data.vuser_id().v), .user = owner.user(data.vuser_id()),
.date = data.vdate().v, .date = data.vdate().v,
}); });
}); });
@ -623,7 +623,7 @@ auto InviteLinks::parse(
return invite.match([&](const MTPDchatInviteExported &data) { return invite.match([&](const MTPDchatInviteExported &data) {
return Link{ return Link{
.link = qs(data.vlink()), .link = qs(data.vlink()),
.admin = peer->session().data().user(data.vadmin_id().v), .admin = peer->session().data().user(data.vadmin_id()),
.date = data.vdate().v, .date = data.vdate().v,
.startDate = data.vstart_date().value_or_empty(), .startDate = data.vstart_date().value_or_empty(),
.expireDate = data.vexpire_date().value_or_empty(), .expireDate = data.vexpire_date().value_or_empty(),

View file

@ -37,7 +37,7 @@ Key ExtractKey(const QString &query) {
const auto params = parse(); const auto params = parse();
const auto channel = params.value("channel"); const auto channel = params.value("channel");
const auto post = params.value("post").toInt(); const auto post = params.value("post").toInt();
return (channel.toInt() && post) ? Key{ channel, post } : Key(); return (channel.toULongLong() && post) ? Key{ channel, post } : Key();
} else if (check.startsWith(qstr("tg://resolve"), Qt::CaseInsensitive)) { } else if (check.startsWith(qstr("tg://resolve"), Qt::CaseInsensitive)) {
const auto params = parse(); const auto params = parse();
const auto domain = params.value("domain"); const auto domain = params.value("domain");
@ -112,7 +112,7 @@ std::optional<HistoryItem*> SingleMessageSearch::performLookupByChannel(
&& received.messageIds.front() == postId) { && received.messageIds.front() == postId) {
_cache.emplace( _cache.emplace(
_requestKey, _requestKey,
FullMsgId(channel->bareId(), postId)); FullMsgId(peerToChannel(channel->id), postId));
ready(); ready();
} else { } else {
fail(); fail();
@ -142,7 +142,7 @@ std::optional<HistoryItem*> SingleMessageSearch::performLookupById(
_requestId = _session->api().request(MTPchannels_GetChannels( _requestId = _session->api().request(MTPchannels_GetChannels(
MTP_vector<MTPInputChannel>( MTP_vector<MTPInputChannel>(
1, 1,
MTP_inputChannel(MTP_int(channelId), MTP_long(0))) MTP_inputChannel(MTP_int(channelId.bare), MTP_long(0))) // #TODO ids
)).done([=](const MTPmessages_Chats &result) { )).done([=](const MTPmessages_Chats &result) {
result.match([&](const auto &data) { result.match([&](const auto &data) {
const auto peer = _session->data().processChats(data.vchats()); const auto peer = _session->data().processChats(data.vchats());
@ -212,7 +212,7 @@ std::optional<HistoryItem*> SingleMessageSearch::performLookup(
if (!_requestKey.domainOrId[0].isDigit()) { if (!_requestKey.domainOrId[0].isDigit()) {
return performLookupByUsername(_requestKey.domainOrId, ready); return performLookupByUsername(_requestKey.domainOrId, ready);
} }
const auto channelId = _requestKey.domainOrId.toInt(); const auto channelId = ChannelId(_requestKey.domainOrId.toULongLong());
return performLookupById(channelId, ready); return performLookupById(channelId, ready);
} }

View file

@ -35,15 +35,17 @@ EntitiesInText EntitiesFromMTP(
case mtpc_messageEntityMention: { auto &d = entity.c_messageEntityMention(); result.push_back({ EntityType::Mention, d.voffset().v, d.vlength().v }); } break; case mtpc_messageEntityMention: { auto &d = entity.c_messageEntityMention(); result.push_back({ EntityType::Mention, d.voffset().v, d.vlength().v }); } break;
case mtpc_messageEntityMentionName: { case mtpc_messageEntityMentionName: {
const auto &d = entity.c_messageEntityMentionName(); const auto &d = entity.c_messageEntityMentionName();
const auto userId = UserId(d.vuser_id());
const auto data = [&] { const auto data = [&] {
if (session) { if (session) {
if (const auto user = session->data().userLoaded(d.vuser_id().v)) { if (const auto user = session->data().userLoaded(userId)) {
return MentionNameDataFromFields({ return MentionNameDataFromFields({
d.vuser_id().v, userId.bare,
user->accessHash() }); user->accessHash()
});
} }
} }
return MentionNameDataFromFields(d.vuser_id().v); return MentionNameDataFromFields(userId.bare);
}(); }();
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data }); result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data });
} break; } break;
@ -51,10 +53,11 @@ EntitiesInText EntitiesFromMTP(
const auto &d = entity.c_inputMessageEntityMentionName(); const auto &d = entity.c_inputMessageEntityMentionName();
const auto data = [&] { const auto data = [&] {
if (session && d.vuser_id().type() == mtpc_inputUserSelf) { if (session && d.vuser_id().type() == mtpc_inputUserSelf) {
return MentionNameDataFromFields(session->userId()); return MentionNameDataFromFields(session->userId().bare);
} else if (d.vuser_id().type() == mtpc_inputUser) { } else if (d.vuser_id().type() == mtpc_inputUser) {
auto &user = d.vuser_id().c_inputUser(); auto &user = d.vuser_id().c_inputUser();
return MentionNameDataFromFields({ user.vuser_id().v, user.vaccess_hash().v }); const auto userId = UserId(user.vuser_id());
return MentionNameDataFromFields({ userId.bare, user.vaccess_hash().v });
} }
return QString(); return QString();
}(); }();
@ -110,7 +113,7 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(
case EntityType::MentionName: { case EntityType::MentionName: {
auto inputUser = [&](const QString &data) -> MTPInputUser { auto inputUser = [&](const QString &data) -> MTPInputUser {
auto fields = MentionNameDataToFields(data); auto fields = MentionNameDataToFields(data);
if (session && fields.userId == session->userId()) { if (session && fields.userId == session->userId().bare) {
return MTP_inputUserSelf(); return MTP_inputUserSelf();
} else if (fields.userId) { } else if (fields.userId) {
return MTP_inputUser(MTP_int(fields.userId), MTP_long(fields.accessHash)); return MTP_inputUser(MTP_int(fields.userId), MTP_long(fields.accessHash));

View file

@ -131,13 +131,13 @@ bool MentionUsersLoaded(
for (const auto &entity : entities.v) { for (const auto &entity : entities.v) {
auto type = entity.type(); auto type = entity.type();
if (type == mtpc_messageEntityMentionName) { if (type == mtpc_messageEntityMentionName) {
if (!session->data().userLoaded(entity.c_messageEntityMentionName().vuser_id().v)) { if (!session->data().userLoaded(entity.c_messageEntityMentionName().vuser_id())) {
return false; return false;
} }
} else if (type == mtpc_inputMessageEntityMentionName) { } else if (type == mtpc_inputMessageEntityMentionName) {
auto &inputUser = entity.c_inputMessageEntityMentionName().vuser_id(); auto &inputUser = entity.c_inputMessageEntityMentionName().vuser_id();
if (inputUser.type() == mtpc_inputUser) { if (inputUser.type() == mtpc_inputUser) {
if (!session->data().userLoaded(inputUser.c_inputUser().vuser_id().v)) { if (!session->data().userLoaded(inputUser.c_inputUser().vuser_id())) {
return false; return false;
} }
} }
@ -157,7 +157,7 @@ DataIsLoadedResult AllDataLoadedForMessage(
} }
} }
if (const auto viaBotId = message.vvia_bot_id()) { if (const auto viaBotId = message.vvia_bot_id()) {
if (!session->data().userLoaded(viaBotId->v)) { if (!session->data().userLoaded(*viaBotId)) {
return DataIsLoadedResult::NotLoaded; return DataIsLoadedResult::NotLoaded;
} }
} }
@ -181,19 +181,19 @@ DataIsLoadedResult AllDataLoadedForMessage(
} }
return message.vaction().match( return message.vaction().match(
[&](const MTPDmessageActionChatAddUser &action) { [&](const MTPDmessageActionChatAddUser &action) {
for (const MTPint &userId : action.vusers().v) { for (const auto &userId : action.vusers().v) {
if (!session->data().userLoaded(userId.v)) { if (!session->data().userLoaded(userId)) {
return DataIsLoadedResult::NotLoaded; return DataIsLoadedResult::NotLoaded;
} }
} }
return DataIsLoadedResult::Ok; return DataIsLoadedResult::Ok;
}, [&](const MTPDmessageActionChatJoinedByLink &action) { }, [&](const MTPDmessageActionChatJoinedByLink &action) {
if (!session->data().userLoaded(action.vinviter_id().v)) { if (!session->data().userLoaded(action.vinviter_id())) {
return DataIsLoadedResult::NotLoaded; return DataIsLoadedResult::NotLoaded;
} }
return DataIsLoadedResult::Ok; return DataIsLoadedResult::Ok;
}, [&](const MTPDmessageActionChatDeleteUser &action) { }, [&](const MTPDmessageActionChatDeleteUser &action) {
if (!session->data().userLoaded(action.vuser_id().v)) { if (!session->data().userLoaded(action.vuser_id())) {
return DataIsLoadedResult::NotLoaded; return DataIsLoadedResult::NotLoaded;
} }
return DataIsLoadedResult::Ok; return DataIsLoadedResult::Ok;
@ -1020,7 +1020,7 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
| MTPDmessage::Flag::f_from_id; | MTPDmessage::Flag::f_from_id;
const auto peerUserId = d.is_out() const auto peerUserId = d.is_out()
? d.vuser_id() ? d.vuser_id()
: MTP_int(_session->userId()); : MTP_int(_session->userId().bare); // #TODO ids
_session->data().addNewMessage( _session->data().addNewMessage(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
@ -1309,8 +1309,8 @@ void Updates::applyUpdates(
const auto viaBotId = d.vvia_bot_id(); const auto viaBotId = d.vvia_bot_id();
const auto entities = d.ventities(); const auto entities = d.ventities();
const auto fwd = d.vfwd_from(); const auto fwd = d.vfwd_from();
if (!session().data().userLoaded(d.vuser_id().v) if (!session().data().userLoaded(d.vuser_id())
|| (viaBotId && !session().data().userLoaded(viaBotId->v)) || (viaBotId && !session().data().userLoaded(*viaBotId))
|| (entities && !MentionUsersLoaded(&session(), *entities)) || (entities && !MentionUsersLoaded(&session(), *entities))
|| (fwd && !ForwardedInfoDataLoaded(&session(), *fwd))) { || (fwd && !ForwardedInfoDataLoaded(&session(), *fwd))) {
MTP_LOG(0, ("getDifference " MTP_LOG(0, ("getDifference "
@ -1326,14 +1326,14 @@ void Updates::applyUpdates(
case mtpc_updateShortChatMessage: { case mtpc_updateShortChatMessage: {
auto &d = updates.c_updateShortChatMessage(); auto &d = updates.c_updateShortChatMessage();
const auto noFrom = !session().data().userLoaded(d.vfrom_id().v); const auto noFrom = !session().data().userLoaded(d.vfrom_id());
const auto chat = session().data().chatLoaded(d.vchat_id().v); const auto chat = session().data().chatLoaded(d.vchat_id());
const auto viaBotId = d.vvia_bot_id(); const auto viaBotId = d.vvia_bot_id();
const auto entities = d.ventities(); const auto entities = d.ventities();
const auto fwd = d.vfwd_from(); const auto fwd = d.vfwd_from();
if (!chat if (!chat
|| noFrom || noFrom
|| (viaBotId && !session().data().userLoaded(viaBotId->v)) || (viaBotId && !session().data().userLoaded(*viaBotId))
|| (entities && !MentionUsersLoaded(&session(), *entities)) || (entities && !MentionUsersLoaded(&session(), *entities))
|| (fwd && !ForwardedInfoDataLoaded(&session(), *fwd))) { || (fwd && !ForwardedInfoDataLoaded(&session(), *fwd))) {
MTP_LOG(0, ("getDifference " MTP_LOG(0, ("getDifference "
@ -1491,7 +1491,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateChannelReadMessagesContents: { case mtpc_updateChannelReadMessagesContents: {
auto &d = update.c_updateChannelReadMessagesContents(); auto &d = update.c_updateChannelReadMessagesContents();
auto channel = session().data().channelLoaded(d.vchannel_id().v); auto channel = session().data().channelLoaded(d.vchannel_id());
if (!channel) { if (!channel) {
if (!_byMinChannelTimer.isActive()) { if (!_byMinChannelTimer.isActive()) {
// getDifference after timeout. // getDifference after timeout.
@ -1537,7 +1537,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updatePinnedChannelMessages: { case mtpc_updatePinnedChannelMessages: {
auto &d = update.c_updatePinnedChannelMessages(); auto &d = update.c_updatePinnedChannelMessages();
auto channel = session().data().channelLoaded(d.vchannel_id().v); auto channel = session().data().channelLoaded(d.vchannel_id());
if (channel && !_handlingChannelDifference) { if (channel && !_handlingChannelDifference) {
if (channel->ptsRequesting()) { // skip global updates while getting channel difference if (channel->ptsRequesting()) { // skip global updates while getting channel difference
@ -1623,7 +1623,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateDeleteChannelMessages: { case mtpc_updateDeleteChannelMessages: {
auto &d = update.c_updateDeleteChannelMessages(); auto &d = update.c_updateDeleteChannelMessages();
auto channel = session().data().channelLoaded(d.vchannel_id().v); auto channel = session().data().channelLoaded(d.vchannel_id());
if (channel && !_handlingChannelDifference) { if (channel && !_handlingChannelDifference) {
if (channel->ptsRequesting()) { // skip global updates while getting channel difference if (channel->ptsRequesting()) { // skip global updates while getting channel difference
@ -1662,7 +1662,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
session().data().processWebpage(d.vwebpage()); session().data().processWebpage(d.vwebpage());
session().data().sendWebPageGamePollNotifications(); session().data().sendWebPageGamePollNotifications();
auto channel = session().data().channelLoaded(d.vchannel_id().v); auto channel = session().data().channelLoaded(d.vchannel_id());
if (channel && !_handlingChannelDifference) { if (channel && !_handlingChannelDifference) {
if (channel->ptsRequesting()) { // skip global updates while getting channel difference if (channel->ptsRequesting()) { // skip global updates while getting channel difference
return; return;
@ -1683,27 +1683,25 @@ void Updates::feedUpdate(const MTPUpdate &update) {
handleSendActionUpdate( handleSendActionUpdate(
peerFromUser(d.vuser_id()), peerFromUser(d.vuser_id()),
0, 0,
d.vuser_id().v, peerFromUser(d.vuser_id()),
d.vaction()); d.vaction());
} break; } break;
case mtpc_updateChatUserTyping: { case mtpc_updateChatUserTyping: {
auto &d = update.c_updateChatUserTyping(); auto &d = update.c_updateChatUserTyping();
const auto fromId = peerFromMTP(d.vfrom_id());
handleSendActionUpdate( handleSendActionUpdate(
peerFromChat(d.vchat_id()), peerFromChat(d.vchat_id()),
0, 0,
fromId, peerFromMTP(d.vfrom_id()),
d.vaction()); d.vaction());
} break; } break;
case mtpc_updateChannelUserTyping: { case mtpc_updateChannelUserTyping: {
const auto &d = update.c_updateChannelUserTyping(); const auto &d = update.c_updateChannelUserTyping();
const auto fromId = peerFromMTP(d.vfrom_id());
handleSendActionUpdate( handleSendActionUpdate(
peerFromChannel(d.vchannel_id()), peerFromChannel(d.vchannel_id()),
d.vtop_msg_id().value_or_empty(), d.vtop_msg_id().value_or_empty(),
fromId, peerFromMTP(d.vfrom_id()),
d.vaction()); d.vaction());
} break; } break;
@ -1729,7 +1727,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateUserStatus: { case mtpc_updateUserStatus: {
auto &d = update.c_updateUserStatus(); auto &d = update.c_updateUserStatus();
if (auto user = session().data().userLoaded(d.vuser_id().v)) { if (auto user = session().data().userLoaded(d.vuser_id())) {
switch (d.vstatus().type()) { switch (d.vstatus().type()) {
case mtpc_userStatusEmpty: user->onlineTill = 0; break; case mtpc_userStatusEmpty: user->onlineTill = 0; break;
case mtpc_userStatusRecently: case mtpc_userStatusRecently:
@ -1746,7 +1744,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
user, user,
Data::PeerUpdate::Flag::OnlineStatus); Data::PeerUpdate::Flag::OnlineStatus);
} }
if (d.vuser_id().v == session().userId()) { if (UserId(d.vuser_id()) == session().userId()) {
if (d.vstatus().type() == mtpc_userStatusOffline if (d.vstatus().type() == mtpc_userStatusOffline
|| d.vstatus().type() == mtpc_userStatusEmpty) { || d.vstatus().type() == mtpc_userStatusEmpty) {
updateOnline(true); updateOnline(true);
@ -1763,7 +1761,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateUserName: { case mtpc_updateUserName: {
auto &d = update.c_updateUserName(); auto &d = update.c_updateUserName();
if (auto user = session().data().userLoaded(d.vuser_id().v)) { if (auto user = session().data().userLoaded(d.vuser_id())) {
if (!user->isContact()) { if (!user->isContact()) {
user->setName( user->setName(
TextUtilities::SingleLine(qs(d.vfirst_name())), TextUtilities::SingleLine(qs(d.vfirst_name())),
@ -1782,7 +1780,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateUserPhoto: { case mtpc_updateUserPhoto: {
auto &d = update.c_updateUserPhoto(); auto &d = update.c_updateUserPhoto();
if (auto user = session().data().userLoaded(d.vuser_id().v)) { if (auto user = session().data().userLoaded(d.vuser_id())) {
user->setPhoto(d.vphoto()); user->setPhoto(d.vphoto());
user->loadUserpic(); user->loadUserpic();
// After that update we don't have enough information to // After that update we don't have enough information to
@ -1793,11 +1791,11 @@ void Updates::feedUpdate(const MTPUpdate &update) {
// //
//if (mtpIsTrue(d.vprevious()) || !user->userpicPhotoId()) { //if (mtpIsTrue(d.vprevious()) || !user->userpicPhotoId()) {
session().storage().remove(Storage::UserPhotosRemoveAfter( session().storage().remove(Storage::UserPhotosRemoveAfter(
user->bareId(), peerToUser(user->id),
user->userpicPhotoId())); user->userpicPhotoId()));
//} else { //} else {
// session().storage().add(Storage::UserPhotosAddNew( // session().storage().add(Storage::UserPhotosAddNew(
// user->bareId(), // peerToUser(user->id),
// user->userpicPhotoId())); // user->userpicPhotoId()));
//} //}
} }
@ -1831,7 +1829,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateUserPhone: { case mtpc_updateUserPhone: {
const auto &d = update.c_updateUserPhone(); const auto &d = update.c_updateUserPhone();
if (const auto user = session().data().userLoaded(d.vuser_id().v)) { if (const auto user = session().data().userLoaded(d.vuser_id())) {
const auto newPhone = qs(d.vphone()); const auto newPhone = qs(d.vphone());
if (newPhone != user->phone()) { if (newPhone != user->phone()) {
user->setPhone(newPhone); user->setPhone(newPhone);
@ -1914,8 +1912,8 @@ void Updates::feedUpdate(const MTPUpdate &update) {
auto &d = update.c_updatePrivacy(); auto &d = update.c_updatePrivacy();
const auto allChatsLoaded = [&](const MTPVector<MTPint> &ids) { const auto allChatsLoaded = [&](const MTPVector<MTPint> &ids) {
for (const auto &chatId : ids.v) { for (const auto &chatId : ids.v) {
if (!session().data().chatLoaded(chatId.v) if (!session().data().chatLoaded(chatId)
&& !session().data().channelLoaded(chatId.v)) { && !session().data().channelLoaded(chatId)) {
return false; return false;
} }
} }
@ -1999,7 +1997,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
} }
DEBUG_LOG(("API Error: " DEBUG_LOG(("API Error: "
"pinned chat not loaded for peer %1, folder: %2" "pinned chat not loaded for peer %1, folder: %2"
).arg(id ).arg(id.value
).arg(folderId ).arg(folderId
)); ));
return false; return false;
@ -2027,7 +2025,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateChannel: { case mtpc_updateChannel: {
auto &d = update.c_updateChannel(); auto &d = update.c_updateChannel();
if (const auto channel = session().data().channelLoaded(d.vchannel_id().v)) { if (const auto channel = session().data().channelLoaded(d.vchannel_id())) {
channel->inviter = UserId(0); channel->inviter = UserId(0);
if (channel->amIn()) { if (channel->amIn()) {
if (channel->isMegagroup() if (channel->isMegagroup()
@ -2049,7 +2047,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateChannelTooLong: { case mtpc_updateChannelTooLong: {
const auto &d = update.c_updateChannelTooLong(); const auto &d = update.c_updateChannelTooLong();
if (const auto channel = session().data().channelLoaded(d.vchannel_id().v)) { if (const auto channel = session().data().channelLoaded(d.vchannel_id())) {
const auto pts = d.vpts(); const auto pts = d.vpts();
if (!pts || channel->pts() < pts->v) { if (!pts || channel->pts() < pts->v) {
getChannelDifference(channel); getChannelDifference(channel);
@ -2108,7 +2106,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateChannelAvailableMessages: { case mtpc_updateChannelAvailableMessages: {
auto &d = update.c_updateChannelAvailableMessages(); auto &d = update.c_updateChannelAvailableMessages();
if (const auto channel = session().data().channelLoaded(d.vchannel_id().v)) { if (const auto channel = session().data().channelLoaded(d.vchannel_id())) {
channel->setAvailableMinId(d.vavailable_min_id().v); channel->setAvailableMinId(d.vavailable_min_id().v);
if (const auto history = session().data().historyLoaded(channel)) { if (const auto history = session().data().historyLoaded(channel)) {
history->clearUpTill(d.vavailable_min_id().v); history->clearUpTill(d.vavailable_min_id().v);

View file

@ -692,7 +692,7 @@ QString ApiWrap::exportDirectMessageLink(
if (inRepliesContext) { if (inRepliesContext) {
if (const auto rootId = item->replyToTop()) { if (const auto rootId = item->replyToTop()) {
const auto root = item->history()->owner().message( const auto root = item->history()->owner().message(
channel->bareId(), peerToChannel(channel->id),
rootId); rootId);
const auto sender = root const auto sender = root
? root->discussionPostOriginalSender() ? root->discussionPostOriginalSender()
@ -715,7 +715,7 @@ QString ApiWrap::exportDirectMessageLink(
} }
const auto base = linkChannel->hasUsername() const auto base = linkChannel->hasUsername()
? linkChannel->username ? linkChannel->username
: "c/" + QString::number(linkChannel->bareId()); : "c/" + QString::number(peerToChannel(linkChannel->id).bare);
const auto query = base const auto query = base
+ '/' + '/'
+ QString::number(linkItemId) + QString::number(linkItemId)
@ -776,7 +776,7 @@ void ApiWrap::requestContacts() {
for (const auto &contact : d.vcontacts().v) { for (const auto &contact : d.vcontacts().v) {
if (contact.type() != mtpc_contact) continue; if (contact.type() != mtpc_contact) continue;
const auto userId = contact.c_contact().vuser_id().v; const auto userId = UserId(contact.c_contact().vuser_id());
if (userId == _session->userId()) { if (userId == _session->userId()) {
_session->user()->setIsContact(true); _session->user()->setIsContact(true);
} }
@ -2267,7 +2267,7 @@ void ApiWrap::updatePrivacyLastSeens(const QVector<MTPPrivacyRule> &rules) {
for (const auto &item : result.v) { for (const auto &item : result.v) {
Assert(item.type() == mtpc_contactStatus); Assert(item.type() == mtpc_contactStatus);
auto &data = item.c_contactStatus(); auto &data = item.c_contactStatus();
if (auto user = _session->data().userLoaded(data.vuser_id().v)) { if (auto user = _session->data().userLoaded(data.vuser_id())) {
auto oldOnlineTill = user->onlineTill; auto oldOnlineTill = user->onlineTill;
auto newOnlineTill = OnlineTillFromStatus(data.vstatus(), oldOnlineTill); auto newOnlineTill = OnlineTillFromStatus(data.vstatus(), oldOnlineTill);
if (oldOnlineTill != newOnlineTill) { if (oldOnlineTill != newOnlineTill) {
@ -3566,7 +3566,7 @@ void ApiWrap::userPhotosDone(
} }
} }
_session->storage().add(Storage::UserPhotosAddSlice( _session->storage().add(Storage::UserPhotosAddSlice(
user->id, peerToUser(user->id),
std::move(photoIds), std::move(photoIds),
fullCount fullCount
)); ));
@ -3809,7 +3809,7 @@ void ApiWrap::sendSharedContact(
MTP_string(firstName), MTP_string(firstName),
MTP_string(lastName), MTP_string(lastName),
MTP_string(vcard), MTP_string(vcard),
MTP_int(userId)), MTP_int(userId.bare)), // #TODO ids
MTPReplyMarkup(), MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(), MTPVector<MTPMessageEntity>(),
MTP_int(views), MTP_int(views),
@ -4613,7 +4613,7 @@ void ApiWrap::clearPeerPhoto(not_null<PhotoData*> photo) {
MTP_vector<MTPInputPhoto>(1, photo->mtpInput()) MTP_vector<MTPInputPhoto>(1, photo->mtpInput())
)).send(); )).send();
_session->storage().remove(Storage::UserPhotosRemoveOne( _session->storage().remove(Storage::UserPhotosRemoveOne(
self->bareId(), peerToUser(self->id),
photo->id)); photo->id));
} }
} }
@ -4790,11 +4790,11 @@ auto ApiWrap::parsePrivacy(const QVector<MTPPrivacyRule> &rules)
}, [&](const MTPDprivacyValueAllowChatParticipants &data) { }, [&](const MTPDprivacyValueAllowChatParticipants &data) {
const auto &chats = data.vchats().v; const auto &chats = data.vchats().v;
always.reserve(always.size() + chats.size()); always.reserve(always.size() + chats.size());
for (const auto chatId : chats) { for (const auto &chatId : chats) {
const auto chat = _session->data().chatLoaded(chatId.v); const auto chat = _session->data().chatLoaded(chatId);
const auto peer = chat const auto peer = chat
? static_cast<PeerData*>(chat) ? static_cast<PeerData*>(chat)
: _session->data().channelLoaded(chatId.v); : _session->data().channelLoaded(chatId);
if (peer if (peer
&& !base::contains(never, peer) && !base::contains(never, peer)
&& !base::contains(always, peer)) { && !base::contains(always, peer)) {
@ -4818,11 +4818,11 @@ auto ApiWrap::parsePrivacy(const QVector<MTPPrivacyRule> &rules)
}, [&](const MTPDprivacyValueDisallowChatParticipants &data) { }, [&](const MTPDprivacyValueDisallowChatParticipants &data) {
const auto &chats = data.vchats().v; const auto &chats = data.vchats().v;
never.reserve(never.size() + chats.size()); never.reserve(never.size() + chats.size());
for (const auto chatId : chats) { for (const auto &chatId : chats) {
const auto chat = _session->data().chatLoaded(chatId.v); const auto chat = _session->data().chatLoaded(chatId);
const auto peer = chat const auto peer = chat
? static_cast<PeerData*>(chat) ? static_cast<PeerData*>(chat)
: _session->data().channelLoaded(chatId.v); : _session->data().channelLoaded(chatId);
if (peer if (peer
&& !base::contains(always, peer) && !base::contains(always, peer)
&& !base::contains(never, peer)) { && !base::contains(never, peer)) {

View file

@ -76,6 +76,15 @@ inline QString ToString(uint64 value) {
return QString::number(value); return QString::number(value);
} }
template <uchar Shift>
inline QString ToString(ChatIdType<Shift> value) {
return QString::number(value.bare);
}
inline QString ToString(PeerId value) {
return QString::number(value.value);
}
} // namespace details } // namespace details
template < template <

View file

@ -94,7 +94,7 @@ void ChatCreateDone(
} }
| [&](auto chats) { | [&](auto chats) {
return navigation->session().data().chat( return navigation->session().data().chat(
chats->front().c_chat().vid().v); chats->front().c_chat().vid());
} }
| [&](not_null<ChatData*> chat) { | [&](not_null<ChatData*> chat) {
if (!image.isNull()) { if (!image.isNull()) {
@ -401,7 +401,7 @@ void AddContactBox::save() {
const auto extractUser = [&](const MTPImportedContact &data) { const auto extractUser = [&](const MTPImportedContact &data) {
return data.match([&](const MTPDimportedContact &data) { return data.match([&](const MTPDimportedContact &data) {
return (data.vclient_id().v == _contactId) return (data.vclient_id().v == _contactId)
? _session->data().userLoaded(data.vuser_id().v) ? _session->data().userLoaded(data.vuser_id())
: nullptr; : nullptr;
}); });
}; };
@ -687,7 +687,7 @@ void GroupInfoBox::createChannel(const QString &title, const QString &descriptio
} }
| [&](auto chats) { | [&](auto chats) {
return _navigation->session().data().channel( return _navigation->session().data().channel(
chats->front().c_channel().vid().v); chats->front().c_channel().vid());
} }
| [&](not_null<ChannelData*> channel) { | [&](not_null<ChannelData*> channel) {
auto image = _photo->takeResultImage(); auto image = _photo->takeResultImage();

View file

@ -295,7 +295,7 @@ AdminLog::OwnedItem GenerateTextItem(
| (out ? Flag::f_out : Flag(0)); | (out ? Flag::f_out : Flag(0));
const auto clientFlags = MTPDmessage_ClientFlag::f_fake_history_item; const auto clientFlags = MTPDmessage_ClientFlag::f_fake_history_item;
const auto replyTo = 0; const auto replyTo = 0;
const auto viaBotId = 0; const auto viaBotId = UserId(0);
const auto item = history->makeMessage( const auto item = history->makeMessage(
++id, ++id,
flags, flags,
@ -402,14 +402,12 @@ BackgroundPreviewBox::BackgroundPreviewBox(
, _controller(controller) , _controller(controller)
, _text1(GenerateTextItem( , _text1(GenerateTextItem(
delegate(), delegate(),
_controller->session().data().history( _controller->session().data().history(PeerData::kServiceNotificationsId),
peerFromUser(PeerData::kServiceNotificationsId)),
tr::lng_background_text1(tr::now), tr::lng_background_text1(tr::now),
false)) false))
, _text2(GenerateTextItem( , _text2(GenerateTextItem(
delegate(), delegate(),
_controller->session().data().history( _controller->session().data().history(PeerData::kServiceNotificationsId),
peerFromUser(PeerData::kServiceNotificationsId)),
tr::lng_background_text2(tr::now), tr::lng_background_text2(tr::now),
true)) true))
, _paper(paper) , _paper(paper)

View file

@ -182,11 +182,11 @@ QVector<MTPInputPrivacyRule> EditPrivacyBox::collectResult() {
return result; return result;
}; };
const auto collectInputChats = [](const auto &peers) { const auto collectInputChats = [](const auto &peers) {
auto result = QVector<MTPint>(); auto result = QVector<MTPint>(); // #TODO ids
result.reserve(peers.size()); result.reserve(peers.size());
for (const auto peer : peers) { for (const auto peer : peers) {
if (!peer->isUser()) { if (!peer->isUser()) {
result.push_back(MTP_int(peer->bareId())); result.push_back(peerToBareMTPInt(peer->id));
} }
} }
return result; return result;

View file

@ -119,7 +119,7 @@ private:
} }
[[nodiscard]] uint64 TypeId(Flag flag) { [[nodiscard]] uint64 TypeId(Flag flag) {
return PeerIdFakeShift | static_cast<uint64>(flag); return PeerId(FakeChatId(static_cast<BareId>(flag))).value;
} }
TypeRow::TypeRow(Flag flag) : PeerListRow(TypeId(flag)) { TypeRow::TypeRow(Flag flag) : PeerListRow(TypeId(flag)) {

View file

@ -86,8 +86,8 @@ void PeerListBox::createMultiSelect() {
if (_controller->handleDeselectForeignRow(itemId)) { if (_controller->handleDeselectForeignRow(itemId)) {
return; return;
} }
if (const auto peer = _controller->session().data().peerLoaded(itemId)) { if (const auto peer = _controller->session().data().peerLoaded(PeerId(itemId))) {
if (const auto row = peerListFindRow(peer->id)) { if (const auto row = peerListFindRow(itemId)) {
content()->changeCheckState(row, false, anim::type::normal); content()->changeCheckState(row, false, anim::type::normal);
update(); update();
} }
@ -275,11 +275,11 @@ void PeerListController::search(const QString &query) {
} }
void PeerListController::peerListSearchAddRow(not_null<PeerData*> peer) { void PeerListController::peerListSearchAddRow(not_null<PeerData*> peer) {
if (auto row = delegate()->peerListFindRow(peer->id)) { if (auto row = delegate()->peerListFindRow(peer->id.value)) {
Assert(row->id() == row->peer()->id); Assert(row->id() == row->peer()->id.value);
delegate()->peerListAppendFoundRow(row); delegate()->peerListAppendFoundRow(row);
} else if (auto row = createSearchRow(peer)) { } else if (auto row = createSearchRow(peer)) {
Assert(row->id() == row->peer()->id); Assert(row->id() == row->peer()->id.value);
delegate()->peerListAppendSearchRow(std::move(row)); delegate()->peerListAppendSearchRow(std::move(row));
} }
} }
@ -353,7 +353,7 @@ void PeerListBox::addSelectItem(
? tr::lng_replies_messages(tr::now) ? tr::lng_replies_messages(tr::now)
: peer->shortName(); : peer->shortName();
addSelectItem( addSelectItem(
peer->id, peer->id.value,
text, text,
PaintUserpicCallback(peer, respect), PaintUserpicCallback(peer, respect),
animated); animated);
@ -420,7 +420,7 @@ auto PeerListBox::collectSelectedRows()
result.reserve(items.size()); result.reserve(items.size());
for (const auto itemId : items) { for (const auto itemId : items) {
if (!_controller->isForeignRow(itemId)) { if (!_controller->isForeignRow(itemId)) {
result.push_back(_controller->session().data().peer(itemId)); result.push_back(_controller->session().data().peer(PeerId(itemId)));
} }
} }
} }
@ -428,7 +428,7 @@ auto PeerListBox::collectSelectedRows()
} }
PeerListRow::PeerListRow(not_null<PeerData*> peer) PeerListRow::PeerListRow(not_null<PeerData*> peer)
: PeerListRow(peer, peer->id) { : PeerListRow(peer, peer->id.value) {
} }
PeerListRow::PeerListRow(not_null<PeerData*> peer, PeerListRowId id) PeerListRow::PeerListRow(not_null<PeerData*> peer, PeerListRowId id)
@ -800,7 +800,7 @@ void PeerListContent::addRowEntry(not_null<PeerListRow*> row) {
addToSearchIndex(row); addToSearchIndex(row);
} }
if (_controller->isRowSelected(row)) { if (_controller->isRowSelected(row)) {
Assert(row->special() || row->id() == row->peer()->id); Assert(row->special() || row->id() == row->peer()->id.value);
changeCheckState(row, true, anim::type::instant); changeCheckState(row, true, anim::type::instant);
} }
} }
@ -1643,7 +1643,7 @@ void PeerListContent::restoreState(
auto searchWords = TextUtilities::PrepareSearchWords(query); auto searchWords = TextUtilities::PrepareSearchWords(query);
setSearchQuery(query, searchWords.join(' ')); setSearchQuery(query, searchWords.join(' '));
for (auto peer : state->filterResults) { for (auto peer : state->filterResults) {
if (auto existingRow = findRow(peer->id)) { if (auto existingRow = findRow(peer->id.value)) {
_filterResults.push_back(existingRow); _filterResults.push_back(existingRow);
} else if (auto row = _controller->createSearchRow(peer)) { } else if (auto row = _controller->createSearchRow(peer)) {
appendSearchRow(std::move(row)); appendSearchRow(std::move(row));

View file

@ -344,7 +344,7 @@ std::unique_ptr<PeerListRow> ChatsListBoxController::createSearchRow(not_null<Pe
} }
bool ChatsListBoxController::appendRow(not_null<History*> history) { bool ChatsListBoxController::appendRow(not_null<History*> history) {
if (auto row = delegate()->peerListFindRow(history->peer->id)) { if (auto row = delegate()->peerListFindRow(history->peer->id.value)) {
updateRowHook(static_cast<Row*>(row)); updateRowHook(static_cast<Row*>(row));
return false; return false;
} }
@ -426,7 +426,7 @@ void ContactsBoxController::rowClicked(not_null<PeerListRow*> row) {
} }
bool ContactsBoxController::appendRow(not_null<UserData*> user) { bool ContactsBoxController::appendRow(not_null<UserData*> user) {
if (auto row = delegate()->peerListFindRow(user->id)) { if (auto row = delegate()->peerListFindRow(user->id.value)) {
updateRowHook(row); updateRowHook(row);
return false; return false;
} }

View file

@ -46,7 +46,7 @@ auto PeerListsBox::collectSelectedRows()
return false; return false;
}(); }();
if (!foreign) { if (!foreign) {
result.push_back(session->data().peer(itemId)); result.push_back(session->data().peer(PeerId(itemId)));
} }
} }
} }
@ -108,10 +108,10 @@ void PeerListsBox::createMultiSelect() {
} }
} }
const auto session = &firstController()->session(); const auto session = &firstController()->session();
if (const auto peer = session->data().peerLoaded(itemId)) { if (const auto peer = session->data().peerLoaded(PeerId(itemId))) {
const auto id = peer->id; const auto id = peer->id;
for (const auto &list : _lists) { for (const auto &list : _lists) {
if (const auto row = list.delegate->peerListFindRow(id)) { if (const auto row = list.delegate->peerListFindRow(id.value)) {
list.content->changeCheckState( list.content->changeCheckState(
row, row,
false, false,
@ -385,7 +385,7 @@ void PeerListsBox::addSelectItem(
not_null<PeerData*> peer, not_null<PeerData*> peer,
anim::type animated) { anim::type animated) {
addSelectItem( addSelectItem(
peer->id, peer->id.value,
peer->shortName(), peer->shortName(),
PaintUserpicCallback(peer, false), PaintUserpicCallback(peer, false),
animated); animated);

View file

@ -661,12 +661,12 @@ void AddSpecialBoxController::editAdminDone(
using Flag = MTPDchannelParticipantCreator::Flag; using Flag = MTPDchannelParticipantCreator::Flag;
_additional.applyParticipant(MTP_channelParticipantCreator( _additional.applyParticipant(MTP_channelParticipantCreator(
MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank), MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank),
MTP_int(user->bareId()), peerToBareMTPInt(user->id),
rights, rights,
MTP_string(rank))); MTP_string(rank)));
} else if (rights.c_chatAdminRights().vflags().v == 0) { } else if (rights.c_chatAdminRights().vflags().v == 0) {
_additional.applyParticipant(MTP_channelParticipant( _additional.applyParticipant(MTP_channelParticipant(
MTP_int(user->bareId()), peerToBareMTPInt(user->id),
MTP_int(date))); MTP_int(date)));
} else { } else {
using Flag = MTPDchannelParticipantAdmin::Flag; using Flag = MTPDchannelParticipantAdmin::Flag;
@ -674,11 +674,11 @@ void AddSpecialBoxController::editAdminDone(
_additional.applyParticipant(MTP_channelParticipantAdmin( _additional.applyParticipant(MTP_channelParticipantAdmin(
MTP_flags(Flag::f_can_edit MTP_flags(Flag::f_can_edit
| (rank.isEmpty() ? Flag(0) : Flag::f_rank)), | (rank.isEmpty() ? Flag(0) : Flag::f_rank)),
MTP_int(user->bareId()), peerToBareMTPInt(user->id),
MTPint(), // inviter_id MTPint(), // inviter_id
MTP_int(alreadyPromotedBy peerToBareMTPInt(alreadyPromotedBy
? alreadyPromotedBy->bareId() ? alreadyPromotedBy->id
: user->session().userId()), : user->session().userPeerId()),
MTP_int(date), MTP_int(date),
rights, rights,
MTP_string(rank))); MTP_string(rank)));
@ -763,7 +763,7 @@ void AddSpecialBoxController::editRestrictedDone(
if (Data::ChatBannedRightsFlags(rights) == 0) { if (Data::ChatBannedRightsFlags(rights) == 0) {
if (const auto user = participant->asUser()) { if (const auto user = participant->asUser()) {
_additional.applyParticipant(MTP_channelParticipant( _additional.applyParticipant(MTP_channelParticipant(
MTP_int(user->bareId()), peerToBareMTPInt(user->id),
MTP_int(date))); MTP_int(date)));
} else { } else {
_additional.setExternal(participant); _additional.setExternal(participant);
@ -777,14 +777,10 @@ void AddSpecialBoxController::editRestrictedDone(
MTP_flags(kicked MTP_flags(kicked
? MTPDchannelParticipantBanned::Flag::f_left ? MTPDchannelParticipantBanned::Flag::f_left
: MTPDchannelParticipantBanned::Flag(0)), : MTPDchannelParticipantBanned::Flag(0)),
(participant->isUser() peerToMTP(participant->id),
? MTP_peerUser(MTP_int(participant->bareId())) peerToBareMTPInt(alreadyRestrictedBy
: participant->isChat() ? alreadyRestrictedBy->id
? MTP_peerChat(MTP_int(participant->bareId())) : participant->session().userPeerId()),
: MTP_peerChannel(MTP_int(participant->bareId()))),
MTP_int(alreadyRestrictedBy
? alreadyRestrictedBy->bareId()
: participant->session().userId()),
MTP_int(date), MTP_int(date),
rights)); rights));
} }
@ -861,7 +857,7 @@ void AddSpecialBoxController::kickUser(
} }
bool AddSpecialBoxController::appendRow(not_null<PeerData*> participant) { bool AddSpecialBoxController::appendRow(not_null<PeerData*> participant) {
if (delegate()->peerListFindRow(participant->id) if (delegate()->peerListFindRow(participant->id.value)
|| (_excludeSelf && participant->isSelf())) { || (_excludeSelf && participant->isSelf())) {
return false; return false;
} }
@ -870,7 +866,7 @@ bool AddSpecialBoxController::appendRow(not_null<PeerData*> participant) {
} }
bool AddSpecialBoxController::prependRow(not_null<UserData*> user) { bool AddSpecialBoxController::prependRow(not_null<UserData*> user) {
if (delegate()->peerListFindRow(user->id)) { if (delegate()->peerListFindRow(user->id.value)) {
return false; return false;
} }
delegate()->peerListPrependRow(createRow(user)); delegate()->peerListPrependRow(createRow(user));

View file

@ -31,7 +31,7 @@ constexpr auto kMaxUserFirstLastName = 64; // See also add_contact_box.
QString UserPhone(not_null<UserData*> user) { QString UserPhone(not_null<UserData*> user) {
const auto phone = user->phone(); const auto phone = user->phone();
return phone.isEmpty() return phone.isEmpty()
? user->owner().findContactPhone(user->bareId()) ? user->owner().findContactPhone(peerToUser(user->id))
: phone; : phone;
} }

View file

@ -82,7 +82,7 @@ int Controller::contentWidth() const {
void Controller::prepare() { void Controller::prepare() {
const auto appendRow = [&](not_null<PeerData*> chat) { const auto appendRow = [&](not_null<PeerData*> chat) {
if (delegate()->peerListFindRow(chat->id)) { if (delegate()->peerListFindRow(chat->id.value)) {
return; return;
} }
auto row = std::make_unique<PeerListRow>(chat); auto row = std::make_unique<PeerListRow>(chat);

View file

@ -607,7 +607,7 @@ UserData *ParticipantsAdditionalData::applyCreator(
UserData *ParticipantsAdditionalData::applyAdmin( UserData *ParticipantsAdditionalData::applyAdmin(
const MTPDchannelParticipantAdmin &data) { const MTPDchannelParticipantAdmin &data) {
const auto user = _peer->owner().userLoaded(data.vuser_id().v); const auto user = _peer->owner().userLoaded(UserId(data.vuser_id().v));
if (!user) { if (!user) {
return nullptr; return nullptr;
} else if (const auto chat = _peer->asChat()) { } else if (const auto chat = _peer->asChat()) {
@ -631,7 +631,7 @@ UserData *ParticipantsAdditionalData::applyAdmin(
} else { } else {
_adminRanks.remove(user); _adminRanks.remove(user);
} }
if (const auto by = _peer->owner().userLoaded(data.vpromoted_by().v)) { if (const auto by = _peer->owner().userLoaded(data.vpromoted_by())) {
const auto i = _adminPromotedBy.find(user); const auto i = _adminPromotedBy.find(user);
if (i == _adminPromotedBy.end()) { if (i == _adminPromotedBy.end()) {
_adminPromotedBy.emplace(user, by); _adminPromotedBy.emplace(user, by);
@ -646,7 +646,7 @@ UserData *ParticipantsAdditionalData::applyAdmin(
} }
UserData *ParticipantsAdditionalData::applyRegular(MTPint userId) { UserData *ParticipantsAdditionalData::applyRegular(MTPint userId) {
const auto user = _peer->owner().userLoaded(userId.v); const auto user = _peer->owner().userLoaded(userId);
if (!user) { if (!user) {
return nullptr; return nullptr;
} else if (const auto chat = _peer->asChat()) { } else if (const auto chat = _peer->asChat()) {
@ -685,7 +685,7 @@ PeerData *ParticipantsAdditionalData::applyBanned(
_kicked.erase(participant); _kicked.erase(participant);
} }
_restrictedRights[participant] = data.vbanned_rights(); _restrictedRights[participant] = data.vbanned_rights();
if (const auto by = _peer->owner().userLoaded(data.vkicked_by().v)) { if (const auto by = _peer->owner().userLoaded(data.vkicked_by())) {
const auto i = _restrictedBy.find(participant); const auto i = _restrictedBy.find(participant);
if (i == _restrictedBy.end()) { if (i == _restrictedBy.end()) {
_restrictedBy.emplace(participant, by); _restrictedBy.emplace(participant, by);
@ -725,7 +725,7 @@ ParticipantsOnlineSorter::ParticipantsOnlineSorter(
Data::PeerUpdate::Flag::OnlineStatus Data::PeerUpdate::Flag::OnlineStatus
) | rpl::start_with_next([=](const Data::PeerUpdate &update) { ) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
const auto peerId = update.peer->id; const auto peerId = update.peer->id;
if (const auto row = _delegate->peerListFindRow(peerId)) { if (const auto row = _delegate->peerListFindRow(peerId.value)) {
row->refreshStatus(); row->refreshStatus();
sortDelayed(); sortDelayed();
} }
@ -827,7 +827,7 @@ void ParticipantsBoxController::setupListChangeViewers() {
return; return;
} }
} }
if (const auto row = delegate()->peerListFindRow(user->id)) { if (const auto row = delegate()->peerListFindRow(user->id.value)) {
delegate()->peerListPartitionRows([&](const PeerListRow &row) { delegate()->peerListPartitionRows([&](const PeerListRow &row) {
return (row.peer() == user); return (row.peer() == user);
}); });
@ -843,7 +843,7 @@ void ParticipantsBoxController::setupListChangeViewers() {
channel->owner().megagroupParticipantRemoved( channel->owner().megagroupParticipantRemoved(
channel channel
) | rpl::start_with_next([=](not_null<UserData*> user) { ) | rpl::start_with_next([=](not_null<UserData*> user) {
if (const auto row = delegate()->peerListFindRow(user->id)) { if (const auto row = delegate()->peerListFindRow(user->id.value)) {
delegate()->peerListRemoveRow(row); delegate()->peerListRemoveRow(row);
} }
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
@ -1561,12 +1561,12 @@ void ParticipantsBoxController::editAdminDone(
using Flag = MTPDchannelParticipantCreator::Flag; using Flag = MTPDchannelParticipantCreator::Flag;
_additional.applyParticipant(MTP_channelParticipantCreator( _additional.applyParticipant(MTP_channelParticipantCreator(
MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank), MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank),
MTP_int(user->bareId()), peerToBareMTPInt(user->id),
rights, rights,
MTP_string(rank))); MTP_string(rank)));
} else if (rights.c_chatAdminRights().vflags().v == 0) { } else if (rights.c_chatAdminRights().vflags().v == 0) {
_additional.applyParticipant(MTP_channelParticipant( _additional.applyParticipant(MTP_channelParticipant(
MTP_int(user->bareId()), peerToBareMTPInt(user->id),
MTP_int(date))); MTP_int(date)));
if (_role == Role::Admins) { if (_role == Role::Admins) {
removeRow(user); removeRow(user);
@ -1577,11 +1577,11 @@ void ParticipantsBoxController::editAdminDone(
_additional.applyParticipant(MTP_channelParticipantAdmin( _additional.applyParticipant(MTP_channelParticipantAdmin(
MTP_flags(Flag::f_can_edit MTP_flags(Flag::f_can_edit
| (rank.isEmpty() ? Flag(0) : Flag::f_rank)), | (rank.isEmpty() ? Flag(0) : Flag::f_rank)),
MTP_int(user->bareId()), peerToBareMTPInt(user->id),
MTPint(), // inviter_id MTPint(), // inviter_id
MTP_int(alreadyPromotedBy peerToBareMTPInt(alreadyPromotedBy
? alreadyPromotedBy->bareId() ? alreadyPromotedBy->id
: user->session().userId()), : user->session().userPeerId()),
MTP_int(date), MTP_int(date),
rights, rights,
MTP_string(rank))); MTP_string(rank)));
@ -1637,7 +1637,7 @@ void ParticipantsBoxController::editRestrictedDone(
if (Data::ChatBannedRightsFlags(rights) == 0) { if (Data::ChatBannedRightsFlags(rights) == 0) {
if (user) { if (user) {
_additional.applyParticipant(MTP_channelParticipant( _additional.applyParticipant(MTP_channelParticipant(
MTP_int(user->bareId()), peerToBareMTPInt(user->id),
MTP_int(date))); MTP_int(date)));
} else { } else {
_additional.setExternal(participant); _additional.setExternal(participant);
@ -1654,14 +1654,10 @@ void ParticipantsBoxController::editRestrictedDone(
MTP_flags(kicked MTP_flags(kicked
? MTPDchannelParticipantBanned::Flag::f_left ? MTPDchannelParticipantBanned::Flag::f_left
: MTPDchannelParticipantBanned::Flag(0)), : MTPDchannelParticipantBanned::Flag(0)),
(participant->isUser() peerToMTP(participant->id),
? MTP_peerUser(MTP_int(participant->bareId())) peerToBareMTPInt(alreadyRestrictedBy
: participant->isChat() ? alreadyRestrictedBy->id
? MTP_peerChat(MTP_int(participant->bareId())) : participant->session().userPeerId()),
: MTP_peerChannel(MTP_int(participant->bareId()))),
MTP_int(alreadyRestrictedBy
? alreadyRestrictedBy->bareId()
: participant->session().userId()),
MTP_int(date), MTP_int(date),
rights)); rights));
if (kicked) { if (kicked) {
@ -1704,7 +1700,7 @@ void ParticipantsBoxController::kickParticipant(not_null<PeerData*> participant)
void ParticipantsBoxController::unkickParticipant(not_null<UserData*> user) { void ParticipantsBoxController::unkickParticipant(not_null<UserData*> user) {
_editBox = nullptr; _editBox = nullptr;
if (const auto row = delegate()->peerListFindRow(user->id)) { if (const auto row = delegate()->peerListFindRow(user->id.value)) {
delegate()->peerListRemoveRow(row); delegate()->peerListRemoveRow(row);
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
} }
@ -1720,7 +1716,7 @@ void ParticipantsBoxController::kickParticipantSure(
? *restrictedRights ? *restrictedRights
: ChannelData::EmptyRestrictedRights(participant); : ChannelData::EmptyRestrictedRights(participant);
if (const auto row = delegate()->peerListFindRow(participant->id)) { if (const auto row = delegate()->peerListFindRow(participant->id.value)) {
delegate()->peerListRemoveRow(row); delegate()->peerListRemoveRow(row);
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
} }
@ -1770,7 +1766,7 @@ void ParticipantsBoxController::removeAdminSure(not_null<UserData*> user) {
void ParticipantsBoxController::removeKickedWithRow( void ParticipantsBoxController::removeKickedWithRow(
not_null<PeerData*> participant) { not_null<PeerData*> participant) {
if (const auto row = delegate()->peerListFindRow(participant->id)) { if (const auto row = delegate()->peerListFindRow(participant->id.value)) {
removeKicked(row, participant); removeKicked(row, participant);
} else { } else {
removeKicked(participant); removeKicked(participant);
@ -1796,7 +1792,7 @@ void ParticipantsBoxController::removeKicked(
} }
bool ParticipantsBoxController::appendRow(not_null<PeerData*> participant) { bool ParticipantsBoxController::appendRow(not_null<PeerData*> participant) {
if (delegate()->peerListFindRow(participant->id)) { if (delegate()->peerListFindRow(participant->id.value)) {
recomputeTypeFor(participant); recomputeTypeFor(participant);
return false; return false;
} else if (auto row = createRow(participant)) { } else if (auto row = createRow(participant)) {
@ -1810,7 +1806,7 @@ bool ParticipantsBoxController::appendRow(not_null<PeerData*> participant) {
} }
bool ParticipantsBoxController::prependRow(not_null<PeerData*> participant) { bool ParticipantsBoxController::prependRow(not_null<PeerData*> participant) {
if (const auto row = delegate()->peerListFindRow(participant->id)) { if (const auto row = delegate()->peerListFindRow(participant->id.value)) {
recomputeTypeFor(participant); recomputeTypeFor(participant);
refreshCustomStatus(row); refreshCustomStatus(row);
if (_role == Role::Admins) { if (_role == Role::Admins) {
@ -1829,7 +1825,7 @@ bool ParticipantsBoxController::prependRow(not_null<PeerData*> participant) {
} }
bool ParticipantsBoxController::removeRow(not_null<PeerData*> participant) { bool ParticipantsBoxController::removeRow(not_null<PeerData*> participant) {
if (auto row = delegate()->peerListFindRow(participant->id)) { if (auto row = delegate()->peerListFindRow(participant->id.value)) {
if (_role == Role::Admins) { if (_role == Role::Admins) {
// Perhaps we are removing an admin from search results. // Perhaps we are removing an admin from search results.
row->setCustomStatus(tr::lng_channel_admin_status_not_admin(tr::now)); row->setCustomStatus(tr::lng_channel_admin_status_not_admin(tr::now));
@ -1903,7 +1899,7 @@ void ParticipantsBoxController::recomputeTypeFor(
if (_role != Role::Profile) { if (_role != Role::Profile) {
return; return;
} }
if (const auto row = delegate()->peerListFindRow(participant->id)) { if (const auto row = delegate()->peerListFindRow(participant->id.value)) {
static_cast<Row*>(row)->setType(computeType(participant)); static_cast<Row*>(row)->setType(computeType(participant));
} }
} }

View file

@ -766,7 +766,7 @@ void AdminsController::prepare() {
owner.processUsers(data.vusers()); owner.processUsers(data.vusers());
for (const auto &admin : data.vadmins().v) { for (const auto &admin : data.vadmins().v) {
admin.match([&](const MTPDchatAdminWithInvites &data) { admin.match([&](const MTPDchatAdminWithInvites &data) {
const auto adminId = data.vadmin_id().v; const auto adminId = data.vadmin_id();
if (const auto user = owner.userLoaded(adminId)) { if (const auto user = owner.userLoaded(adminId)) {
if (!user->isSelf()) { if (!user->isSelf()) {
appendRow(user, data.vinvites_count().v); appendRow(user, data.vinvites_count().v);

View file

@ -254,7 +254,7 @@ void ShareBox::prepare() {
applyFilterUpdate(query); applyFilterUpdate(query);
}); });
_select->setItemRemovedCallback([=](uint64 itemId) { _select->setItemRemovedCallback([=](uint64 itemId) {
if (const auto peer = _descriptor.session->data().peerLoaded(itemId)) { if (const auto peer = _descriptor.session->data().peerLoaded(PeerId(itemId))) {
_inner->peerUnselected(peer); _inner->peerUnselected(peer);
selectedChanged(); selectedChanged();
update(); update();
@ -469,7 +469,7 @@ void ShareBox::addPeerToMultiSelect(PeerData *peer, bool skipAnimation) {
using AddItemWay = Ui::MultiSelect::AddItemWay; using AddItemWay = Ui::MultiSelect::AddItemWay;
auto addItemWay = skipAnimation ? AddItemWay::SkipAnimation : AddItemWay::Default; auto addItemWay = skipAnimation ? AddItemWay::SkipAnimation : AddItemWay::Default;
_select->addItem( _select->addItem(
peer->id, peer->id.value,
peer->isSelf() ? tr::lng_saved_short(tr::now) : peer->shortName(), peer->isSelf() ? tr::lng_saved_short(tr::now) : peer->shortName(),
st::activeButtonBg, st::activeButtonBg,
PaintUserpicCallback(peer, true), PaintUserpicCallback(peer, true),
@ -481,7 +481,7 @@ void ShareBox::innerSelectedChanged(PeerData *peer, bool checked) {
addPeerToMultiSelect(peer); addPeerToMultiSelect(peer);
_select->clearQuery(); _select->clearQuery();
} else { } else {
_select->removeItem(peer->id); _select->removeItem(peer->id.value);
} }
selectedChanged(); selectedChanged();
update(); update();
@ -1107,25 +1107,25 @@ QString AppendShareGameScoreUrl(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const QString &url, const QString &url,
const FullMsgId &fullId) { const FullMsgId &fullId) {
auto shareHashData = QByteArray(0x10, Qt::Uninitialized); auto shareHashData = QByteArray(0x20, Qt::Uninitialized);
auto shareHashDataInts = reinterpret_cast<int32*>(shareHashData.data()); auto shareHashDataInts = reinterpret_cast<uint64*>(shareHashData.data());
auto channel = fullId.channel auto channel = fullId.channel
? session->data().channelLoaded(fullId.channel) ? session->data().channelLoaded(fullId.channel)
: static_cast<ChannelData*>(nullptr); : static_cast<ChannelData*>(nullptr);
auto channelAccessHash = channel ? channel->access : 0ULL; auto channelAccessHash = uint64(channel ? channel->access : 0);
auto channelAccessHashInts = reinterpret_cast<int32*>(&channelAccessHash); auto channelAccessHashInts = reinterpret_cast<int32*>(&channelAccessHash);
shareHashDataInts[0] = session->userId(); shareHashDataInts[0] = session->userId().bare;
shareHashDataInts[1] = fullId.channel; shareHashDataInts[1] = fullId.channel.bare;
shareHashDataInts[2] = fullId.msg; shareHashDataInts[2] = fullId.msg;
shareHashDataInts[3] = channelAccessHashInts[0]; shareHashDataInts[3] = channelAccessHash;
// Count SHA1() of data. // Count SHA1() of data.
auto key128Size = 0x10; auto key128Size = 0x10;
auto shareHashEncrypted = QByteArray(key128Size + shareHashData.size(), Qt::Uninitialized); auto shareHashEncrypted = QByteArray(key128Size + shareHashData.size(), Qt::Uninitialized);
hashSha1(shareHashData.constData(), shareHashData.size(), shareHashEncrypted.data()); hashSha1(shareHashData.constData(), shareHashData.size(), shareHashEncrypted.data());
// Mix in channel access hash to the first 64 bits of SHA1 of data. //// Mix in channel access hash to the first 64 bits of SHA1 of data.
*reinterpret_cast<uint64*>(shareHashEncrypted.data()) ^= *reinterpret_cast<uint64*>(channelAccessHashInts); //*reinterpret_cast<uint64*>(shareHashEncrypted.data()) ^= channelAccessHash;
// Encrypt data. // Encrypt data.
if (!session->local().encrypt(shareHashData.constData(), shareHashEncrypted.data() + key128Size, shareHashData.size(), shareHashEncrypted.constData())) { if (!session->local().encrypt(shareHashData.constData(), shareHashEncrypted.data() + key128Size, shareHashData.size(), shareHashEncrypted.constData())) {
@ -1157,7 +1157,7 @@ void ShareGameScoreByHash(
auto key128Size = 0x10; auto key128Size = 0x10;
auto hashEncrypted = QByteArray::fromBase64(hash.toLatin1(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); auto hashEncrypted = QByteArray::fromBase64(hash.toLatin1(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
if (hashEncrypted.size() <= key128Size || (hashEncrypted.size() % 0x10) != 0) { if (hashEncrypted.size() <= key128Size || (hashEncrypted.size() != key128Size + 0x20)) {
Ui::show(Box<InformBox>(tr::lng_confirm_phone_link_invalid(tr::now))); Ui::show(Box<InformBox>(tr::lng_confirm_phone_link_invalid(tr::now)));
return; return;
} }
@ -1172,37 +1172,46 @@ void ShareGameScoreByHash(
char dataSha1[20] = { 0 }; char dataSha1[20] = { 0 };
hashSha1(hashData.constData(), hashData.size(), dataSha1); hashSha1(hashData.constData(), hashData.size(), dataSha1);
// Mix out channel access hash from the first 64 bits of SHA1 of data. //// Mix out channel access hash from the first 64 bits of SHA1 of data.
auto channelAccessHash = *reinterpret_cast<uint64*>(hashEncrypted.data()) ^ *reinterpret_cast<uint64*>(dataSha1); //auto channelAccessHash = *reinterpret_cast<uint64*>(hashEncrypted.data()) ^ *reinterpret_cast<uint64*>(dataSha1);
// Check next 64 bits of SHA1() of data. //// Check next 64 bits of SHA1() of data.
auto skipSha1Part = sizeof(channelAccessHash); //auto skipSha1Part = sizeof(channelAccessHash);
if (memcmp(dataSha1 + skipSha1Part, hashEncrypted.constData() + skipSha1Part, key128Size - skipSha1Part) != 0) { //if (memcmp(dataSha1 + skipSha1Part, hashEncrypted.constData() + skipSha1Part, key128Size - skipSha1Part) != 0) {
// Ui::show(Box<InformBox>(tr::lng_share_wrong_user(tr::now)));
// return;
//}
// Check 128 bits of SHA1() of data.
if (memcmp(dataSha1, hashEncrypted.constData(), key128Size) != 0) {
Ui::show(Box<InformBox>(tr::lng_share_wrong_user(tr::now))); Ui::show(Box<InformBox>(tr::lng_share_wrong_user(tr::now)));
return; return;
} }
auto hashDataInts = reinterpret_cast<int32*>(hashData.data()); auto hashDataInts = reinterpret_cast<uint64*>(hashData.data());
if (hashDataInts[0] != session->userId()) { if (hashDataInts[0] != session->userId().bare) {
Ui::show(Box<InformBox>(tr::lng_share_wrong_user(tr::now))); Ui::show(Box<InformBox>(tr::lng_share_wrong_user(tr::now)));
return; return;
} }
// Check first 32 bits of channel access hash. // Check first 32 bits of channel access hash.
auto channelAccessHashInts = reinterpret_cast<int32*>(&channelAccessHash); auto channelAccessHash = hashDataInts[3];
if (channelAccessHashInts[0] != hashDataInts[3]) { //auto channelAccessHashInts = reinterpret_cast<int32*>(&channelAccessHash);
Ui::show(Box<InformBox>(tr::lng_share_wrong_user(tr::now))); //if (channelAccessHashInts[0] != hashDataInts[3]) {
return; // Ui::show(Box<InformBox>(tr::lng_share_wrong_user(tr::now)));
} // return;
//}
auto channelId = hashDataInts[1]; if (((hashDataInts[1] >> 40) != 0)
auto msgId = hashDataInts[2]; || ((hashDataInts[2] >> 32) != 0)
if (!channelId && channelAccessHash) { || (!hashDataInts[1] && channelAccessHash)) {
// If there is no channel id, there should be no channel access_hash. // If there is no channel id, there should be no channel access_hash.
Ui::show(Box<InformBox>(tr::lng_share_wrong_user(tr::now))); Ui::show(Box<InformBox>(tr::lng_share_wrong_user(tr::now)));
return; return;
} }
auto channelId = ChannelId(hashDataInts[1]);
auto msgId = MsgId(hashDataInts[2]);
if (const auto item = session->data().message(channelId, msgId)) { if (const auto item = session->data().message(channelId, msgId)) {
FastShareMessage(item); FastShareMessage(item);
} else { } else {
@ -1228,7 +1237,7 @@ void ShareGameScoreByHash(
MTP_vector<MTPInputChannel>( MTP_vector<MTPInputChannel>(
1, 1,
MTP_inputChannel( MTP_inputChannel(
MTP_int(channelId), MTP_int(channelId.bare), // #TODO ids
MTP_long(channelAccessHash))) MTP_long(channelAccessHash)))
)).done([=](const MTPmessages_Chats &result) { )).done([=](const MTPmessages_Chats &result) {
result.match([&](const auto &data) { result.match([&](const auto &data) {

View file

@ -402,7 +402,8 @@ void BoxController::receivedCalls(const QVector<MTPMessage> &result) {
NewMessageType::Existing); NewMessageType::Existing);
insertRow(item, InsertWay::Append); insertRow(item, InsertWay::Append);
} else { } else {
LOG(("API Error: a search results with not loaded peer %1").arg(peerId)); LOG(("API Error: a search results with not loaded peer %1"
).arg(peerId.value));
} }
_offsetId = msgId; _offsetId = msgId;
} }

View file

@ -490,13 +490,13 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
auto &data = call.c_phoneCallRequested(); auto &data = call.c_phoneCallRequested();
if (_type != Type::Incoming if (_type != Type::Incoming
|| _id != 0 || _id != 0
|| peerToUser(_user->id) != data.vadmin_id().v) { || peerToUser(_user->id) != UserId(data.vadmin_id())) {
Unexpected("phoneCallRequested call inside an existing call handleUpdate()"); Unexpected("phoneCallRequested call inside an existing call handleUpdate()");
} }
if (_user->session().userId() != data.vparticipant_id().v) { if (_user->session().userId() != UserId(data.vparticipant_id())) {
LOG(("Call Error: Wrong call participant_id %1, expected %2." LOG(("Call Error: Wrong call participant_id %1, expected %2."
).arg(data.vparticipant_id().v ).arg(data.vparticipant_id().v
).arg(_user->session().userId())); ).arg(_user->session().userId().bare));
finish(FinishType::Failed); finish(FinishType::Failed);
return true; return true;
} }
@ -891,12 +891,12 @@ bool Call::checkCallCommonFields(const T &call) {
} }
auto adminId = (_type == Type::Outgoing) ? _user->session().userId() : peerToUser(_user->id); auto adminId = (_type == Type::Outgoing) ? _user->session().userId() : peerToUser(_user->id);
auto participantId = (_type == Type::Outgoing) ? peerToUser(_user->id) : _user->session().userId(); auto participantId = (_type == Type::Outgoing) ? peerToUser(_user->id) : _user->session().userId();
if (call.vadmin_id().v != adminId) { if (UserId(call.vadmin_id()) != adminId) {
LOG(("Call Error: Wrong call admin_id %1, expected %2.").arg(call.vadmin_id().v).arg(adminId)); LOG(("Call Error: Wrong call admin_id %1, expected %2.").arg(call.vadmin_id().v).arg(adminId.bare));
return checkFailed(); return checkFailed();
} }
if (call.vparticipant_id().v != participantId) { if (UserId(call.vparticipant_id()) != participantId) {
LOG(("Call Error: Wrong call participant_id %1, expected %2.").arg(call.vparticipant_id().v).arg(participantId)); LOG(("Call Error: Wrong call participant_id %1, expected %2.").arg(call.vparticipant_id().v).arg(participantId.bare));
return checkFailed(); return checkFailed();
} }
return true; return true;

View file

@ -105,7 +105,7 @@ void ListController::rowClicked(not_null<PeerListRow*> row) {
if (peer == _selected) { if (peer == _selected) {
return; return;
} }
const auto previous = delegate()->peerListFindRow(_selected->id); const auto previous = delegate()->peerListFindRow(_selected->id.value);
Assert(previous != nullptr); Assert(previous != nullptr);
delegate()->peerListSetRowChecked(previous, false); delegate()->peerListSetRowChecked(previous, false);
delegate()->peerListSetRowChecked(row, true); delegate()->peerListSetRowChecked(row, true);

View file

@ -112,7 +112,7 @@ private:
} }
if (const auto chat = peer->asChat()) { if (const auto chat = peer->asChat()) {
return chat->admins.contains(user) return chat->admins.contains(user)
|| (chat->creator == user->bareId()); || (chat->creator == peerToUser(user->id));
} else if (const auto group = peer->asChannel()) { } else if (const auto group = peer->asChannel()) {
if (const auto mgInfo = group->mgInfo.get()) { if (const auto mgInfo = group->mgInfo.get()) {
if (mgInfo->creator == user) { if (mgInfo->creator == user) {

View file

@ -1293,7 +1293,7 @@ void MembersController::updateRowLevel(
Row *MembersController::findRow(not_null<PeerData*> participantPeer) const { Row *MembersController::findRow(not_null<PeerData*> participantPeer) const {
return static_cast<Row*>( return static_cast<Row*>(
delegate()->peerListFindRow(participantPeer->id)); delegate()->peerListFindRow(participantPeer->id.value));
} }
Main::Session &MembersController::session() const { Main::Session &MembersController::session() const {
@ -1402,7 +1402,7 @@ void MembersController::rowUpdateRow(not_null<Row*> row) {
void MembersController::rowScheduleRaisedHandStatusRemove( void MembersController::rowScheduleRaisedHandStatusRemove(
not_null<Row*> row) { not_null<Row*> row) {
const auto id = row->peer()->id; const auto id = row->id();
const auto when = crl::now() + kKeepRaisedHandStatusDuration; const auto when = crl::now() + kKeepRaisedHandStatusDuration;
const auto i = _raisedHandStatusRemoveAt.find(id); const auto i = _raisedHandStatusRemoveAt.find(id);
if (i != _raisedHandStatusRemoveAt.end()) { if (i != _raisedHandStatusRemoveAt.end()) {

View file

@ -302,7 +302,7 @@ void InviteController::itemDeselectedHook(not_null<PeerData*> peer) {
} }
bool InviteController::hasRowFor(not_null<PeerData*> peer) const { bool InviteController::hasRowFor(not_null<PeerData*> peer) const {
return (delegate()->peerListFindRow(peer->id) != nullptr); return (delegate()->peerListFindRow(peer->id.value) != nullptr);
} }
bool InviteController::isAlreadyIn(not_null<UserData*> user) const { bool InviteController::isAlreadyIn(not_null<UserData*> user) const {
@ -356,7 +356,7 @@ void InviteContactsController::prepareViewHook() {
std::move( std::move(
_discoveredInGroup _discoveredInGroup
) | rpl::start_with_next([=](not_null<UserData*> user) { ) | rpl::start_with_next([=](not_null<UserData*> user) {
if (auto row = delegate()->peerListFindRow(user->id)) { if (auto row = delegate()->peerListFindRow(user->id.value)) {
delegate()->peerListRemoveRow(row); delegate()->peerListRemoveRow(row);
} }
}, _lifetime); }, _lifetime);

View file

@ -374,7 +374,7 @@ void Instance::handleCallUpdate(
const MTPPhoneCall &call) { const MTPPhoneCall &call) {
if (call.type() == mtpc_phoneCallRequested) { if (call.type() == mtpc_phoneCallRequested) {
auto &phoneCall = call.c_phoneCallRequested(); auto &phoneCall = call.c_phoneCallRequested();
auto user = session->data().userLoaded(phoneCall.vadmin_id().v); auto user = session->data().userLoaded(phoneCall.vadmin_id());
if (!user) { if (!user) {
LOG(("API Error: User not loaded for phoneCallRequested.")); LOG(("API Error: User not loaded for phoneCallRequested."));
} else if (user->isSelf()) { } else if (user->isSelf()) {

View file

@ -93,7 +93,7 @@ QString FieldTagMimeProcessor::tagFromMimeTag(const QString &mimeTag) {
const auto userId = _controller->session().userId(); const auto userId = _controller->session().userId();
auto match = QRegularExpression(":(\\d+)$").match(mimeTag); auto match = QRegularExpression(":(\\d+)$").match(mimeTag);
if (!match.hasMatch() if (!match.hasMatch()
|| match.capturedRef(1).toInt() != userId) { || match.capturedRef(1).toULongLong() != userId.bare) {
return QString(); return QString();
} }
return mimeTag.mid(0, mimeTag.size() - match.capturedLength()); return mimeTag.mid(0, mimeTag.size() - match.capturedLength());
@ -249,7 +249,7 @@ TextWithEntities StripSupportHashtag(TextWithEntities &&text) {
QString PrepareMentionTag(not_null<UserData*> user) { QString PrepareMentionTag(not_null<UserData*> user) {
return TextUtilities::kMentionTagStart return TextUtilities::kMentionTagStart
+ QString::number(user->bareId()) + QString::number(user->id.value)
+ '.' + '.'
+ QString::number(user->accessHash()); + QString::number(user->accessHash());
} }

View file

@ -136,7 +136,9 @@ void MentionNameClickHandler::onClick(ClickContext context) const {
} }
auto MentionNameClickHandler::getTextEntity() const -> TextEntity { auto MentionNameClickHandler::getTextEntity() const -> TextEntity {
auto data = QString::number(_userId) + '.' + QString::number(_accessHash); const auto data = QString::number(_userId.bare)
+ '.'
+ QString::number(_accessHash);
return { EntityType::MentionName, data }; return { EntityType::MentionName, data };
} }

View file

@ -191,7 +191,7 @@ bool ShowPassportForm(
if (!controller) { if (!controller) {
return false; return false;
} }
const auto botId = params.value("bot_id", QString()).toInt(); const auto botId = params.value("bot_id", QString()).toULongLong();
const auto scope = params.value("scope", QString()); const auto scope = params.value("scope", QString());
const auto callback = params.value("callback_url", QString()); const auto callback = params.value("callback_url", QString());
const auto publicKey = params.value("public_key", QString()); const auto publicKey = params.value("public_key", QString());
@ -317,7 +317,8 @@ bool ResolvePrivatePost(
const auto params = url_parse_params( const auto params = url_parse_params(
match->captured(1), match->captured(1),
qthelp::UrlParamNameTransform::ToLower); qthelp::UrlParamNameTransform::ToLower);
const auto channelId = params.value(qsl("channel")).toInt(); const auto channelId = ChannelId(
params.value(qsl("channel")).toULongLong());
const auto msgId = params.value(qsl("post")).toInt(); const auto msgId = params.value(qsl("post")).toInt();
const auto commentParam = params.value(qsl("comment")); const auto commentParam = params.value(qsl("comment"));
const auto commentId = commentParam.toInt(); const auto commentId = commentParam.toInt();

View file

@ -232,7 +232,7 @@ rpl::producer<> UiIntegration::forcePopupMenuHideRequests() {
QString UiIntegration::convertTagToMimeTag(const QString &tagId) { QString UiIntegration::convertTagToMimeTag(const QString &tagId) {
if (TextUtilities::IsMentionLink(tagId)) { if (TextUtilities::IsMentionLink(tagId)) {
if (const auto session = Core::App().activeAccount().maybeSession()) { if (const auto session = Core::App().activeAccount().maybeSession()) {
return tagId + ':' + QString::number(session->userId()); return tagId + ':' + QString::number(session->userId().bare);
} }
} }
return tagId; return tagId;

View file

@ -48,7 +48,8 @@ void MegagroupInfo::setLocation(const ChannelLocation &location) {
ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id) ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id)
: PeerData(owner, id) : PeerData(owner, id)
, inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))) , inputChannel(
MTP_inputChannel(MTP_int(peerToChannel(id).bare), MTP_long(0)))
, _ptsWaiter(&owner->session().updates()) { , _ptsWaiter(&owner->session().updates()) {
_flags.changes( _flags.changes(
) | rpl::start_with_next([=](const Flags::Change &change) { ) | rpl::start_with_next([=](const Flags::Change &change) {
@ -90,8 +91,8 @@ void ChannelData::setName(const QString &newName, const QString &newUsername) {
void ChannelData::setAccessHash(uint64 accessHash) { void ChannelData::setAccessHash(uint64 accessHash) {
access = accessHash; access = accessHash;
input = MTP_inputPeerChannel(MTP_int(bareId()), MTP_long(accessHash)); input = MTP_inputPeerChannel(MTP_int(peerToChannel(id).bare), MTP_long(accessHash)); // #TODO ids
inputChannel = MTP_inputChannel(MTP_int(bareId()), MTP_long(accessHash)); inputChannel = MTP_inputChannel(MTP_int(peerToChannel(id).bare), MTP_long(accessHash));
} }
void ChannelData::setInviteLink(const QString &newInviteLink) { void ChannelData::setInviteLink(const QString &newInviteLink) {
@ -348,7 +349,7 @@ void ChannelData::markForbidden() {
MTP_flags(isMegagroup() MTP_flags(isMegagroup()
? MTPDchannelForbidden::Flag::f_megagroup ? MTPDchannelForbidden::Flag::f_megagroup
: MTPDchannelForbidden::Flag::f_broadcast), : MTPDchannelForbidden::Flag::f_broadcast),
MTP_int(bareId()), MTP_int(peerToChannel(id).bare),
MTP_long(access), MTP_long(access),
MTP_string(name), MTP_string(name),
MTPint())); MTPint()));

View file

@ -25,7 +25,7 @@ using UpdateFlag = Data::PeerUpdate::Flag;
ChatData::ChatData(not_null<Data::Session*> owner, PeerId id) ChatData::ChatData(not_null<Data::Session*> owner, PeerId id)
: PeerData(owner, id) : PeerData(owner, id)
, inputChat(MTP_int(bareId())) { , inputChat(MTP_int(peerToChat(id).bare)) {
_flags.changes( _flags.changes(
) | rpl::start_with_next([=](const Flags::Change &change) { ) | rpl::start_with_next([=](const Flags::Change &change) {
if (change.diff & MTPDchat::Flag::f_call_not_empty) { if (change.diff & MTPDchat::Flag::f_call_not_empty) {
@ -45,7 +45,7 @@ void ChatData::setPhoto(const MTPChatPhoto &photo) {
} }
auto ChatData::defaultAdminRights(not_null<UserData*> user) -> AdminRights { auto ChatData::defaultAdminRights(not_null<UserData*> user) -> AdminRights {
const auto isCreator = (creator == user->bareId()) const auto isCreator = (creator == peerToUser(user->id))
|| (user->isSelf() && amCreator()); || (user->isSelf() && amCreator());
using Flag = AdminRight; using Flag = AdminRight;
return Flag::f_other return Flag::f_other
@ -276,7 +276,7 @@ void ApplyChatUpdate(
chat->botStatus = 0; chat->botStatus = 0;
} else { } else {
chat->participants.emplace(user); chat->participants.emplace(user);
if (update.vinviter_id().v == session->userId()) { if (UserId(update.vinviter_id()) == session->userId()) {
chat->invitedByMe.insert(user); chat->invitedByMe.insert(user);
} else { } else {
chat->invitedByMe.remove(user); chat->invitedByMe.remove(user);
@ -463,9 +463,9 @@ void ApplyChatUpdate(
const auto inviterId = participant.match([&]( const auto inviterId = participant.match([&](
const MTPDchatParticipantCreator &data) { const MTPDchatParticipantCreator &data) {
return 0; return UserId(0);
}, [&](const auto &data) { }, [&](const auto &data) {
return data.vinviter_id().v; return UserId(data.vinviter_id());
}); });
if (inviterId == selfUserId) { if (inviterId == selfUserId) {
chat->invitedByMe.insert(user); chat->invitedByMe.insert(user);

View file

@ -270,7 +270,9 @@ void GroupCall::discard(const MTPDgroupCallDiscarded &data) {
Core::App().calls().applyGroupCallUpdateChecked( Core::App().calls().applyGroupCallUpdateChecked(
&peer->session(), &peer->session(),
MTP_updateGroupCall( MTP_updateGroupCall(
MTP_int(peer->bareId()), MTP_int(peer->isChat()
? peerToChat(peer->id).bare
: peerToChannel(peer->id).bare),
MTP_groupCallDiscarded( MTP_groupCallDiscarded(
data.vid(), data.vid(),
data.vaccess_hash(), data.vaccess_hash(),
@ -740,12 +742,12 @@ void GroupCall::requestUnknownParticipants() {
for (const auto &[participantPeerId, when] : participantPeerIds) { for (const auto &[participantPeerId, when] : participantPeerIds) {
if (const auto userId = peerToUser(participantPeerId)) { if (const auto userId = peerToUser(participantPeerId)) {
peerInputs.push_back( peerInputs.push_back(
MTP_inputPeerUser(MTP_int(userId), MTP_long(0))); MTP_inputPeerUser(MTP_int(userId.bare), MTP_long(0))); // #TODO ids
} else if (const auto chatId = peerToChat(participantPeerId)) { } else if (const auto chatId = peerToChat(participantPeerId)) {
peerInputs.push_back(MTP_inputPeerChat(MTP_int(chatId))); peerInputs.push_back(MTP_inputPeerChat(MTP_int(chatId.bare))); // #TODO ids
} else if (const auto channelId = peerToChannel(participantPeerId)) { } else if (const auto channelId = peerToChannel(participantPeerId)) {
peerInputs.push_back( peerInputs.push_back(
MTP_inputPeerChannel(MTP_int(channelId), MTP_long(0))); MTP_inputPeerChannel(MTP_int(channelId.bare), MTP_long(0))); // #TODO ids
} }
} }
_unknownParticipantPeersRequestId = api().request( _unknownParticipantPeersRequestId = api().request(

View file

@ -782,11 +782,12 @@ bool MediaContact::updateSentMedia(const MTPMessageMedia &media) {
if (media.type() != mtpc_messageMediaContact) { if (media.type() != mtpc_messageMediaContact) {
return false; return false;
} }
if (_contact.userId != media.c_messageMediaContact().vuser_id().v) { const auto userId = UserId(media.c_messageMediaContact().vuser_id());
if (_contact.userId != userId) {
parent()->history()->owner().unregisterContactItem( parent()->history()->owner().unregisterContactItem(
_contact.userId, _contact.userId,
parent()); parent());
_contact.userId = media.c_messageMediaContact().vuser_id().v; _contact.userId = userId;
parent()->history()->owner().registerContactItem( parent()->history()->owner().registerContactItem(
_contact.userId, _contact.userId,
parent()); parent());

View file

@ -54,14 +54,14 @@ using UpdateFlag = Data::PeerUpdate::Flag;
namespace Data { namespace Data {
int PeerColorIndex(int32 bareId) { int PeerColorIndex(BareId bareId) {
const auto index = std::abs(bareId) % 7; const auto index = bareId % 7;
const int map[] = { 0, 7, 4, 1, 6, 3, 5 }; const int map[] = { 0, 7, 4, 1, 6, 3, 5 };
return map[index]; return map[index];
} }
int PeerColorIndex(PeerId peerId) { int PeerColorIndex(PeerId peerId) {
return PeerColorIndex(peerToBareInt(peerId)); return PeerColorIndex(peerId.value & PeerId::kChatTypeMask);
} }
style::color PeerUserpicColor(PeerId peerId) { style::color PeerUserpicColor(PeerId peerId) {
@ -373,7 +373,7 @@ Data::FileOrigin PeerData::userpicOrigin() const {
Data::FileOrigin PeerData::userpicPhotoOrigin() const { Data::FileOrigin PeerData::userpicPhotoOrigin() const {
return (isUser() && userpicPhotoId()) return (isUser() && userpicPhotoId())
? Data::FileOriginUserPhoto(bareId(), userpicPhotoId()) ? Data::FileOriginUserPhoto(peerToUser(id).bare, userpicPhotoId())
: Data::FileOrigin(); : Data::FileOrigin();
} }
@ -383,7 +383,7 @@ void PeerData::updateUserpic(PhotoId photoId, MTP::DcId dcId) {
ImageLocation( ImageLocation(
{ StorageFileLocation( { StorageFileLocation(
dcId, dcId,
isSelf() ? peerToUser(id) : 0, isSelf() ? peerToUser(id) : UserId(),
MTP_inputPeerPhotoFileLocation( MTP_inputPeerPhotoFileLocation(
MTP_flags(0), MTP_flags(0),
input, input,

View file

@ -38,7 +38,7 @@ class GroupCall;
class CloudImageView; class CloudImageView;
int PeerColorIndex(PeerId peerId); int PeerColorIndex(PeerId peerId);
int PeerColorIndex(int32 bareId); int PeerColorIndex(BareId bareId);
style::color PeerUserpicColor(PeerId peerId); style::color PeerUserpicColor(PeerId peerId);
PeerId FakePeerIdForJustName(const QString &name); PeerId FakePeerIdForJustName(const QString &name);
@ -172,7 +172,7 @@ public:
|| (id == kServiceNotificationsId); || (id == kServiceNotificationsId);
} }
[[nodiscard]] bool isServiceUser() const { [[nodiscard]] bool isServiceUser() const {
return isUser() && !(id % 1000); return isUser() && !(id.value % 1000);
} }
[[nodiscard]] std::optional<TimeId> notifyMuteUntil() const { [[nodiscard]] std::optional<TimeId> notifyMuteUntil() const {
@ -239,10 +239,6 @@ public:
[[nodiscard]] const Ui::Text::String &topBarNameText() const; [[nodiscard]] const Ui::Text::String &topBarNameText() const;
[[nodiscard]] QString userName() const; [[nodiscard]] QString userName() const;
[[nodiscard]] int32 bareId() const {
return int32(uint32(id & 0xFFFFFFFFULL));
}
[[nodiscard]] const base::flat_set<QString> &nameWords() const { [[nodiscard]] const base::flat_set<QString> &nameWords() const {
return _nameWords; return _nameWords;
} }

View file

@ -0,0 +1,58 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "data/data_peer_id.h"
PeerId peerFromMTP(const MTPPeer &peer) {
return peer.match([](const MTPDpeerUser &data) {
return peerFromUser(data.vuser_id());
}, [](const MTPDpeerChat &data) {
return peerFromChat(data.vchat_id());
}, [](const MTPDpeerChannel &data) {
return peerFromChannel(data.vchannel_id());
});
}
MTPpeer peerToMTP(PeerId id) {
if (peerIsUser(id)) {
return MTP_peerUser(peerToBareMTPInt(id));
} else if (peerIsChat(id)) {
return MTP_peerChat(peerToBareMTPInt(id));
} else if (peerIsChannel(id)) {
return MTP_peerChannel(peerToBareMTPInt(id));
}
return MTP_peerUser(MTP_int(0));
}
PeerId DeserializePeerId(quint64 serialized) {
const auto flag = (UserId::kReservedBit << 48);
const auto legacy = !(serialized & (UserId::kReservedBit << 48));
if (!legacy) {
return PeerId(serialized & (~flag));
}
constexpr auto PeerIdMask = uint64(0xFFFFFFFFULL);
constexpr auto PeerIdTypeMask = uint64(0xF00000000ULL);
constexpr auto PeerIdUserShift = uint64(0x000000000ULL);
constexpr auto PeerIdChatShift = uint64(0x100000000ULL);
constexpr auto PeerIdChannelShift = uint64(0x200000000ULL);
constexpr auto PeerIdFakeShift = uint64(0xF00000000ULL);
return ((serialized & PeerIdTypeMask) == PeerIdUserShift)
? peerFromUser(UserId(serialized & PeerIdMask))
: ((serialized & PeerIdTypeMask) == PeerIdChatShift)
? peerFromChat(ChatId(serialized & PeerIdMask))
: ((serialized & PeerIdTypeMask) == PeerIdChannelShift)
? peerFromChannel(ChannelId(serialized & PeerIdMask))
: ((serialized & PeerIdTypeMask) == PeerIdFakeShift)
? PeerId(FakeChatId(serialized & PeerIdMask))
: PeerId(0);
}
quint64 SerializePeerId(PeerId id) {
Expects(!(id.value & (UserId::kReservedBit << 48)));
return id.value | (UserId::kReservedBit << 48);
}

View file

@ -0,0 +1,318 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
using BareId = uint64;
struct PeerIdZeroHelper {
};
using PeerIdZero = void(PeerIdZeroHelper::*)();
template <uint8 Shift>
struct ChatIdType {
BareId bare = 0;
static constexpr BareId kShift = Shift;
static constexpr BareId kReservedBit = BareId(0x80);
static_assert((Shift & kReservedBit) == 0, "Last bit is reserved.");
constexpr ChatIdType() noexcept = default;
//constexpr ChatIdType(PeerIdZero) noexcept { // UserId id = 0;
//}
constexpr ChatIdType(BareId value) noexcept : bare(value) {
}
constexpr ChatIdType(int32 value) noexcept : bare(value) { // #TODO ids remove
}
constexpr ChatIdType(MTPint value) noexcept : bare(value.v) { // #TODO ids
}
[[nodiscard]] constexpr explicit operator bool() const noexcept {
return (bare != 0);
}
[[nodiscard]] constexpr bool operator!() const noexcept {
return !bare;
}
};
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator==(
ChatIdType<Shift> a,
ChatIdType<Shift> b) noexcept {
return (a.bare == b.bare);
}
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator!=(
ChatIdType<Shift> a,
ChatIdType<Shift> b) noexcept {
return (a.bare != b.bare);
}
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator<(
ChatIdType<Shift> a,
ChatIdType<Shift> b) noexcept {
return (a.bare < b.bare);
}
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator>(
ChatIdType<Shift> a,
ChatIdType<Shift> b) noexcept {
return (a.bare > b.bare);
}
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator<=(
ChatIdType<Shift> a,
ChatIdType<Shift> b) noexcept {
return (a.bare <= b.bare);
}
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator>=(
ChatIdType<Shift> a,
ChatIdType<Shift> b) noexcept {
return (a.bare >= b.bare);
}
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator==(
ChatIdType<Shift> a,
PeerIdZero) noexcept {
return (a.bare == 0);
}
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator==(
PeerIdZero,
ChatIdType<Shift> a) noexcept {
return (0 == a.bare);
}
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator!=(
ChatIdType<Shift> a,
PeerIdZero) noexcept {
return (a.bare != 0);
}
template <uchar Shift>
[[nodiscard]] inline constexpr bool operator!=(
PeerIdZero,
ChatIdType<Shift> a) noexcept {
return (0 != a.bare);
}
template <uchar Shift>
bool operator<(ChatIdType<Shift>, PeerIdZero) = delete;
template <uchar Shift>
bool operator<(PeerIdZero, ChatIdType<Shift>) = delete;
template <uchar Shift>
bool operator>(ChatIdType<Shift>, PeerIdZero) = delete;
template <uchar Shift>
bool operator>(PeerIdZero, ChatIdType<Shift>) = delete;
template <uchar Shift>
bool operator<=(ChatIdType<Shift>, PeerIdZero) = delete;
template <uchar Shift>
bool operator<=(PeerIdZero, ChatIdType<Shift>) = delete;
template <uchar Shift>
bool operator>=(ChatIdType<Shift>, PeerIdZero) = delete;
template <uchar Shift>
bool operator>=(PeerIdZero, ChatIdType<Shift>) = delete;
using UserId = ChatIdType<0>;
using ChatId = ChatIdType<1>;
using ChannelId = ChatIdType<2>;
using FakeChatId = ChatIdType<0x7F>;
inline constexpr auto NoChannel = ChannelId(0);
struct PeerIdHelper {
BareId value = 0;
constexpr PeerIdHelper(BareId value) noexcept : value(value) {
}
};
struct PeerId {
BareId value = 0;
static constexpr BareId kChatTypeMask = BareId(0xFFFFFFFFFFFFULL);
constexpr PeerId() noexcept = default;
constexpr PeerId(PeerIdZero) noexcept { // PeerId id = 0;
}
template <uchar Shift>
constexpr PeerId(ChatIdType<Shift> id) noexcept
: value(id.bare | (BareId(Shift) << 48)) {
}
// This instead of explicit PeerId(BareId) allows to use both
// PeerId(uint64(..)) and PeerId(0).
constexpr PeerId(PeerIdHelper value) noexcept : value(value.value) {
}
template <typename SomeChatIdType, BareId = SomeChatIdType::kShift>
[[nodiscard]] constexpr bool is() const noexcept {
return ((value >> 48) & BareId(0xFF)) == SomeChatIdType::kShift;
}
template <typename SomeChatIdType, BareId = SomeChatIdType::kShift>
[[nodiscard]] constexpr SomeChatIdType to() const noexcept {
return is<SomeChatIdType>() ? (value & kChatTypeMask) : 0;
}
[[nodiscard]] constexpr explicit operator bool() const noexcept {
return (value != 0);
}
[[nodiscard]] constexpr bool operator!() const noexcept {
return !value;
}
};
[[nodiscard]] inline constexpr bool operator==(PeerId a, PeerId b) noexcept {
return (a.value == b.value);
}
[[nodiscard]] inline constexpr bool operator!=(PeerId a, PeerId b) noexcept {
return (a.value != b.value);
}
[[nodiscard]] inline constexpr bool operator<(PeerId a, PeerId b) noexcept {
return (a.value < b.value);
}
[[nodiscard]] inline constexpr bool operator>(PeerId a, PeerId b) noexcept {
return (a.value > b.value);
}
[[nodiscard]] inline constexpr bool operator<=(PeerId a, PeerId b) noexcept {
return (a.value <= b.value);
}
[[nodiscard]] inline constexpr bool operator>=(PeerId a, PeerId b) noexcept {
return (a.value >= b.value);
}
[[nodiscard]] inline constexpr bool operator==(
PeerId a,
PeerIdZero) noexcept {
return (a.value == 0);
}
[[nodiscard]] inline constexpr bool operator==(
PeerIdZero,
PeerId a) noexcept {
return (0 == a.value);
}
[[nodiscard]] inline constexpr bool operator!=(
PeerId a,
PeerIdZero) noexcept {
return (a.value != 0);
}
[[nodiscard]] inline constexpr bool operator!=(
PeerIdZero,
PeerId a) noexcept {
return (0 != a.value);
}
bool operator<(PeerId, PeerIdZero) = delete;
bool operator<(PeerIdZero, PeerId) = delete;
bool operator>(PeerId, PeerIdZero) = delete;
bool operator>(PeerIdZero, PeerId) = delete;
bool operator<=(PeerId, PeerIdZero) = delete;
bool operator<=(PeerIdZero, PeerId) = delete;
bool operator>=(PeerId, PeerIdZero) = delete;
bool operator>=(PeerIdZero, PeerId) = delete;
[[nodiscard]] inline constexpr bool peerIsUser(PeerId id) noexcept {
return id.is<UserId>();
}
[[nodiscard]] inline constexpr bool peerIsChat(PeerId id) noexcept {
return id.is<ChatId>();
}
[[nodiscard]] inline constexpr bool peerIsChannel(PeerId id) noexcept {
return id.is<ChannelId>();
}
[[nodiscard]] inline constexpr PeerId peerFromUser(UserId userId) noexcept {
return userId;
}
[[nodiscard]] inline constexpr PeerId peerFromChat(ChatId chatId) noexcept {
return chatId;
}
[[nodiscard]] inline constexpr PeerId peerFromChannel(
ChannelId channelId) noexcept {
return channelId;
}
[[nodiscard]] inline constexpr PeerId peerFromUser(MTPint userId) noexcept { // #TODO ids
return peerFromUser(userId.v);
}
[[nodiscard]] inline constexpr PeerId peerFromChat(MTPint chatId) noexcept {
return peerFromChat(chatId.v);
}
[[nodiscard]] inline constexpr PeerId peerFromChannel(
MTPint channelId) noexcept {
return peerFromChannel(channelId.v);
}
[[nodiscard]] inline constexpr UserId peerToUser(PeerId id) noexcept {
return id.to<UserId>();
}
[[nodiscard]] inline constexpr ChatId peerToChat(PeerId id) noexcept {
return id.to<ChatId>();
}
[[nodiscard]] inline constexpr ChannelId peerToChannel(PeerId id) noexcept {
return id.to<ChannelId>();
}
[[nodiscard]] inline MTPint peerToBareMTPInt(PeerId id) { // #TODO ids
return MTP_int(id.value & PeerId::kChatTypeMask);
}
[[nodiscard]] PeerId peerFromMTP(const MTPPeer &peer);
[[nodiscard]] MTPpeer peerToMTP(PeerId id);
// Supports both modern and legacy serializations.
[[nodiscard]] PeerId DeserializePeerId(quint64 serialized);
[[nodiscard]] quint64 SerializePeerId(PeerId id);
namespace std {
template <uchar Shift>
struct hash<ChatIdType<Shift>> : private hash<BareId> {
size_t operator()(ChatIdType<Shift> value) const noexcept {
return hash<BareId>::operator()(value.bare);
}
};
template <>
struct hash<PeerId> : private hash<BareId> {
size_t operator()(PeerId value) const noexcept {
return hash<BareId>::operator()(value.value);
}
};
} // namespace std

View file

@ -133,12 +133,15 @@ bool PollData::applyResults(const MTPPollResults &results) {
} }
} }
if (const auto recent = results.vrecent_voters()) { if (const auto recent = results.vrecent_voters()) {
const auto bareProj = [](not_null<UserData*> user) {
return peerToUser(user->id).bare;
};
const auto recentChanged = !ranges::equal( const auto recentChanged = !ranges::equal(
recentVoters, recentVoters,
recent->v, recent->v,
ranges::equal_to(), ranges::equal_to(),
&UserData::id, bareProj,
&MTPint::v); &MTPint::v); // #TODO ids
if (recentChanged) { if (recentChanged) {
changed = true; changed = true;
recentVoters = ranges::views::all( recentVoters = ranges::views::all(

View file

@ -3525,7 +3525,7 @@ HistoryItem *Session::findWebPageItem(not_null<WebPageData*> page) const {
QString Session::findContactPhone(not_null<UserData*> contact) const { QString Session::findContactPhone(not_null<UserData*> contact) const {
const auto result = contact->phone(); const auto result = contact->phone();
return result.isEmpty() return result.isEmpty()
? findContactPhone(contact->bareId()) ? findContactPhone(peerToUser(contact->id))
: App::formatPhone(result); : App::formatPhone(result);
} }
@ -3970,7 +3970,7 @@ void Session::serviceNotification(
| MTPDuser::Flag::f_phone | MTPDuser::Flag::f_phone
| MTPDuser::Flag::f_status | MTPDuser::Flag::f_status
| MTPDuser::Flag::f_verified), | MTPDuser::Flag::f_verified),
MTP_int(peerToUser(PeerData::kServiceNotificationsId)), MTP_int(peerToUser(PeerData::kServiceNotificationsId).bare), // #TODO ids
MTPlong(), // access_hash MTPlong(), // access_hash
MTP_string("Telegram"), MTP_string("Telegram"),
MTPstring(), // last_name MTPstring(), // last_name

View file

@ -269,7 +269,7 @@ std::optional<int> SharedMediaWithLastSlice::indexOf(Value value) const {
? QString::number(*_ending->skippedAfter()) ? QString::number(*_ending->skippedAfter())
: QString("-")); : QString("-"));
if (const auto msgId = std::get_if<FullMsgId>(&value)) { if (const auto msgId = std::get_if<FullMsgId>(&value)) {
info.push_back("value:" + QString::number(msgId->channel)); info.push_back("value:" + QString::number(msgId->channel.bare));
info.push_back(QString::number(msgId->msg)); info.push_back(QString::number(msgId->msg));
const auto index = _slice.indexOf(*std::get_if<FullMsgId>(&value)); const auto index = _slice.indexOf(*std::get_if<FullMsgId>(&value));
info.push_back("index:" + (index info.push_back("index:" + (index

View file

@ -155,9 +155,7 @@ private:
return (a && b) ? base::make_optional(*a + *b) : std::nullopt; return (a && b) ? base::make_optional(*a + *b) : std::nullopt;
} }
static Value ComputeId(PeerId peerId, MsgId msgId) { static Value ComputeId(PeerId peerId, MsgId msgId) {
return FullMsgId( return FullMsgId(peerToChannel(peerId), msgId);
peerIsChannel(peerId) ? peerToBareInt(peerId) : 0,
msgId);
} }
static Value ComputeId(const Key &key) { static Value ComputeId(const Key &key) {
if (const auto messageId = std::get_if<MessageId>(&key.universalId)) { if (const auto messageId = std::get_if<MessageId>(&key.universalId)) {

View file

@ -119,9 +119,7 @@ private:
: !fullId.channel; : !fullId.channel;
} }
static FullMsgId ComputeId(PeerId peerId, MsgId msgId) { static FullMsgId ComputeId(PeerId peerId, MsgId msgId) {
return FullMsgId( return FullMsgId(peerToChannel(peerId), msgId);
peerIsChannel(peerId) ? peerToBareInt(peerId) : 0,
msgId);
} }
static FullMsgId ComputeId(const Key &key) { static FullMsgId ComputeId(const Key &key) {
return (key.universalId >= 0) return (key.universalId >= 0)

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/value_ordering.h" #include "base/value_ordering.h"
#include "ui/text/text.h" // For QFIXED_MAX #include "ui/text/text.h" // For QFIXED_MAX
#include "data/data_peer_id.h"
class HistoryItem; class HistoryItem;
using HistoryItemsList = std::vector<not_null<HistoryItem*>>; using HistoryItemsList = std::vector<not_null<HistoryItem*>>;
@ -63,11 +64,11 @@ struct FileOrigin;
} // namespace Data } // namespace Data
struct MessageGroupId { struct MessageGroupId {
uint64 peer = 0; PeerId peer = 0;
uint64 value = 0; uint64 value = 0;
MessageGroupId() = default; MessageGroupId() = default;
static MessageGroupId FromRaw(uint64 peer, uint64 value) { static MessageGroupId FromRaw(PeerId peer, uint64 value) {
auto result = MessageGroupId(); auto result = MessageGroupId();
result.peer = peer; result.peer = peer;
result.value = value; result.value = value;
@ -85,7 +86,7 @@ struct MessageGroupId {
} }
friend inline std::pair<uint64, uint64> value_ordering_helper(MessageGroupId value) { friend inline std::pair<uint64, uint64> value_ordering_helper(MessageGroupId value) {
return std::make_pair(value.value, value.peer); return std::make_pair(value.value, value.peer.value);
} }
}; };
@ -101,84 +102,8 @@ namespace Data {
class Folder; class Folder;
} // namespace Data } // namespace Data
using UserId = int32;
using ChatId = int32;
using ChannelId = int32;
using FolderId = int32; using FolderId = int32;
using FilterId = int32; using FilterId = int32;
constexpr auto NoChannel = ChannelId(0);
using PeerId = uint64;
constexpr auto PeerIdMask = PeerId(0xFFFFFFFFULL);
constexpr auto PeerIdTypeMask = PeerId(0xF00000000ULL);
constexpr auto PeerIdUserShift = PeerId(0x000000000ULL);
constexpr auto PeerIdChatShift = PeerId(0x100000000ULL);
constexpr auto PeerIdChannelShift = PeerId(0x200000000ULL);
constexpr auto PeerIdFakeShift = PeerId(0xF00000000ULL);
inline constexpr bool peerIsUser(const PeerId &id) {
return (id & PeerIdTypeMask) == PeerIdUserShift;
}
inline constexpr bool peerIsChat(const PeerId &id) {
return (id & PeerIdTypeMask) == PeerIdChatShift;
}
inline constexpr bool peerIsChannel(const PeerId &id) {
return (id & PeerIdTypeMask) == PeerIdChannelShift;
}
inline constexpr PeerId peerFromUser(UserId user_id) {
return PeerIdUserShift | uint64(uint32(user_id));
}
inline constexpr PeerId peerFromChat(ChatId chat_id) {
return PeerIdChatShift | uint64(uint32(chat_id));
}
inline constexpr PeerId peerFromChannel(ChannelId channel_id) {
return PeerIdChannelShift | uint64(uint32(channel_id));
}
inline constexpr PeerId peerFromUser(const MTPint &user_id) {
return peerFromUser(user_id.v);
}
inline constexpr PeerId peerFromChat(const MTPint &chat_id) {
return peerFromChat(chat_id.v);
}
inline constexpr PeerId peerFromChannel(const MTPint &channel_id) {
return peerFromChannel(channel_id.v);
}
inline constexpr int32 peerToBareInt(const PeerId &id) {
return int32(uint32(id & PeerIdMask));
}
inline constexpr UserId peerToUser(const PeerId &id) {
return peerIsUser(id) ? peerToBareInt(id) : 0;
}
inline constexpr ChatId peerToChat(const PeerId &id) {
return peerIsChat(id) ? peerToBareInt(id) : 0;
}
inline constexpr ChannelId peerToChannel(const PeerId &id) {
return peerIsChannel(id) ? peerToBareInt(id) : NoChannel;
}
inline MTPint peerToBareMTPInt(const PeerId &id) {
return MTP_int(peerToBareInt(id));
}
inline PeerId peerFromMTP(const MTPPeer &peer) {
switch (peer.type()) {
case mtpc_peerUser: return peerFromUser(peer.c_peerUser().vuser_id());
case mtpc_peerChat: return peerFromChat(peer.c_peerChat().vchat_id());
case mtpc_peerChannel: return peerFromChannel(peer.c_peerChannel().vchannel_id());
}
return 0;
}
inline MTPpeer peerToMTP(const PeerId &id) {
if (peerIsUser(id)) {
return MTP_peerUser(peerToBareMTPInt(id));
} else if (peerIsChat(id)) {
return MTP_peerChat(peerToBareMTPInt(id));
} else if (peerIsChannel(id)) {
return MTP_peerChannel(peerToBareMTPInt(id));
}
return MTP_peerUser(MTP_int(0));
}
using MsgId = int32; using MsgId = int32;
constexpr auto StartClientMsgId = MsgId(-0x7FFFFFFF); constexpr auto StartClientMsgId = MsgId(-0x7FFFFFFF);
constexpr auto EndClientMsgId = MsgId(-0x40000000); constexpr auto EndClientMsgId = MsgId(-0x40000000);
@ -214,7 +139,8 @@ inline bool operator!=(const MsgRange &a, const MsgRange &b) {
struct FullMsgId { struct FullMsgId {
constexpr FullMsgId() = default; constexpr FullMsgId() = default;
constexpr FullMsgId(ChannelId channel, MsgId msg) : channel(channel), msg(msg) { constexpr FullMsgId(ChannelId channel, MsgId msg)
: channel(channel), msg(msg) {
} }
explicit operator bool() const { explicit operator bool() const {

View file

@ -365,11 +365,14 @@ QByteArray WallPaper::serialize() const {
+ Serialize::stringSize(_slug) + Serialize::stringSize(_slug)
+ sizeof(qint32) // _settings + sizeof(qint32) // _settings
+ sizeof(quint32) // _backgroundColor + sizeof(quint32) // _backgroundColor
+ sizeof(qint32); // _intensity + sizeof(qint32) // _intensity
+ (2 * sizeof(qint32)); // ownerId
auto result = QByteArray(); auto result = QByteArray();
result.reserve(size); result.reserve(size);
{ {
const auto field1 = qint32(uint32(_ownerId.bare & 0xFFFFFFFF));
const auto field2 = qint32(uint32(_ownerId.bare >> 32));
auto stream = QDataStream(&result, QIODevice::WriteOnly); auto stream = QDataStream(&result, QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_5_1); stream.setVersion(QDataStream::Qt_5_1);
stream stream
@ -380,7 +383,8 @@ QByteArray WallPaper::serialize() const {
<< qint32(_settings) << qint32(_settings)
<< SerializeMaybeColor(_backgroundColor) << SerializeMaybeColor(_backgroundColor)
<< qint32(_intensity) << qint32(_intensity)
<< qint32(_ownerId); << field1
<< field2;
} }
return result; return result;
} }
@ -393,7 +397,7 @@ std::optional<WallPaper> WallPaper::FromSerialized(
auto id = quint64(); auto id = quint64();
auto accessHash = quint64(); auto accessHash = quint64();
auto ownerId = qint32(); auto ownerId = UserId();
auto flags = qint32(); auto flags = qint32();
auto slug = QString(); auto slug = QString();
auto settings = qint32(); auto settings = qint32();
@ -411,7 +415,14 @@ std::optional<WallPaper> WallPaper::FromSerialized(
>> backgroundColor >> backgroundColor
>> intensity; >> intensity;
if (!stream.atEnd()) { if (!stream.atEnd()) {
stream >> ownerId; auto field1 = qint32();
auto field2 = qint32();
stream >> field1;
if (!stream.atEnd()) {
stream >> field2;
}
ownerId = UserId(
BareId(uint32(field1)) | (BareId(uint32(field2)) << 32));
} }
if (stream.status() != QDataStream::Ok) { if (stream.status() != QDataStream::Ok) {
return std::nullopt; return std::nullopt;

View file

@ -729,7 +729,7 @@ bool InnerWidget::isSearchResultActive(
const auto peer = item->history()->peer; const auto peer = item->history()->peer;
return (item->fullId() == entry.fullId) return (item->fullId() == entry.fullId)
|| (peer->migrateTo() || (peer->migrateTo()
&& (peer->migrateTo()->bareId() == entry.fullId.channel) && (peerToChannel(peer->migrateTo()->id) == entry.fullId.channel)
&& (item->id == -entry.fullId.msg)) && (item->id == -entry.fullId.msg))
|| (uniqueSearchResults() && peer == entry.key.peer()); || (uniqueSearchResults() && peer == entry.key.peer());
} }
@ -2080,7 +2080,8 @@ bool InnerWidget::searchReceived(
_lastSearchPeer = peer; _lastSearchPeer = peer;
} }
} else { } else {
LOG(("API Error: a search results with not loaded peer %1").arg(peerId)); LOG(("API Error: a search results with not loaded peer %1"
).arg(peerId.value));
} }
if (isMigratedSearch) { if (isMigratedSearch) {
_lastSearchMigratedId = msgId; _lastSearchMigratedId = msgId;
@ -2142,7 +2143,7 @@ void InnerWidget::peerSearchReceived(
} else { } else {
LOG(("API Error: " LOG(("API Error: "
"user %1 was not loaded in InnerWidget::peopleReceived()" "user %1 was not loaded in InnerWidget::peopleReceived()"
).arg(peer->id)); ).arg(peer->id.value));
} }
} }
for (const auto &mtpPeer : result) { for (const auto &mtpPeer : result) {
@ -2157,7 +2158,7 @@ void InnerWidget::peerSearchReceived(
} else { } else {
LOG(("API Error: " LOG(("API Error: "
"user %1 was not loaded in InnerWidget::peopleReceived()" "user %1 was not loaded in InnerWidget::peopleReceived()"
).arg(peer->id)); ).arg(peer->id.value));
} }
} }
refresh(); refresh();

View file

@ -61,7 +61,7 @@ void SearchFromController::prepare() {
AddSpecialBoxController::prepare(); AddSpecialBoxController::prepare();
delegate()->peerListSetTitle(tr::lng_search_messages_from()); delegate()->peerListSetTitle(tr::lng_search_messages_from());
if (const auto megagroup = peer()->asMegagroup()) { if (const auto megagroup = peer()->asMegagroup()) {
if (!delegate()->peerListFindRow(megagroup->id)) { if (!delegate()->peerListFindRow(megagroup->id.value)) {
delegate()->peerListAppendRow( delegate()->peerListAppendRow(
std::make_unique<PeerListRow>(megagroup)); std::make_unique<PeerListRow>(megagroup));
setDescriptionText({}); setDescriptionText({});

View file

@ -350,7 +350,7 @@ auto GenerateParticipantString(
auto peer = session->data().peer(participantId); auto peer = session->data().peer(participantId);
auto name = TextWithEntities { peer->name }; auto name = TextWithEntities { peer->name };
if (const auto user = peer->asUser()) { if (const auto user = peer->asUser()) {
auto entityData = QString::number(user->id) auto entityData = QString::number(user->id.value)
+ '.' + '.'
+ QString::number(user->accessHash()); + QString::number(user->accessHash());
name.entities.push_back({ name.entities.push_back({

View file

@ -321,7 +321,7 @@ not_null<ChannelData*> Widget::channel() const {
Dialogs::RowDescriptor Widget::activeChat() const { Dialogs::RowDescriptor Widget::activeChat() const {
return { return {
channel()->owner().history(channel()), channel()->owner().history(channel()),
FullMsgId(channel()->bareId(), ShowAtUnreadMsgId) FullMsgId(peerToChannel(channel()->id), ShowAtUnreadMsgId)
}; };
} }

View file

@ -2499,7 +2499,7 @@ void History::dialogEntryApplied() {
addOlderSlice(QVector<MTPMessage>()); addOlderSlice(QVector<MTPMessage>());
if (const auto channel = peer->asChannel()) { if (const auto channel = peer->asChannel()) {
const auto inviter = channel->inviter; const auto inviter = channel->inviter;
if (inviter > 0 && channel->amIn()) { if (inviter && channel->amIn()) {
if (const auto from = owner().userLoaded(inviter)) { if (const auto from = owner().userLoaded(inviter)) {
insertJoinedMessage(); insertJoinedMessage();
} }
@ -2511,7 +2511,7 @@ void History::dialogEntryApplied() {
if (chatListTimeId() != 0 && loadedAtBottom()) { if (chatListTimeId() != 0 && loadedAtBottom()) {
if (const auto channel = peer->asChannel()) { if (const auto channel = peer->asChannel()) {
const auto inviter = channel->inviter; const auto inviter = channel->inviter;
if (inviter > 0 if (inviter
&& chatListTimeId() <= channel->inviteDate && chatListTimeId() <= channel->inviteDate
&& channel->amIn()) { && channel->amIn()) {
if (const auto from = owner().userLoaded(inviter)) { if (const auto from = owner().userLoaded(inviter)) {
@ -2766,7 +2766,7 @@ HistoryService *History::insertJoinedMessage() {
return _joinedMessage; return _joinedMessage;
} }
const auto inviter = (peer->asChannel()->inviter > 0) const auto inviter = peer->asChannel()->inviter
? owner().userLoaded(peer->asChannel()->inviter) ? owner().userLoaded(peer->asChannel()->inviter)
: nullptr; : nullptr;
if (!inviter) { if (!inviter) {
@ -2837,7 +2837,7 @@ void History::checkLocalMessages() {
} }
if (isChannel() if (isChannel()
&& !_joinedMessage && !_joinedMessage
&& (peer->asChannel()->inviter > 0) && peer->asChannel()->inviter
&& goodDate(peer->asChannel()->inviteDate)) { && goodDate(peer->asChannel()->inviteDate)) {
insertJoinedMessage(); insertJoinedMessage();
} }

View file

@ -791,7 +791,7 @@ bool HistoryMessage::checkCommentsLinkedChat(ChannelId id) const {
if (channel->linkedChatKnown() if (channel->linkedChatKnown()
|| !(channel->flags() & MTPDchannel::Flag::f_has_link)) { || !(channel->flags() & MTPDchannel::Flag::f_has_link)) {
const auto linked = channel->linkedChat(); const auto linked = channel->linkedChat();
if (!linked || linked->bareId() != id) { if (!linked || peerToChannel(linked->id) != id) {
return false; return false;
} }
} }
@ -1108,7 +1108,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),
MTPVector<MTPPeer>(), // recent_repliers MTPVector<MTPPeer>(), // recent_repliers
MTP_int(linked->bareId()), MTP_int(peerToChannel(linked->id).bare),
MTP_int(0), // max_id MTP_int(0), // max_id
MTP_int(0))); // read_max_id MTP_int(0))); // read_max_id
} }
@ -1745,10 +1745,11 @@ void HistoryMessage::setReplies(const MTPMessageReplies &data) {
return result; return result;
}(); }();
const auto count = data.vreplies().v; const auto count = data.vreplies().v;
const auto channelId = data.vchannel_id().value_or_empty(); const auto channelId = ChannelId(
data.vchannel_id().value_or_empty());
const auto readTillId = data.vread_max_id() const auto readTillId = data.vread_max_id()
? std::max( ? std::max(
{ views->repliesInboxReadTillId, data.vread_max_id()->v, 1 }) { views->repliesInboxReadTillId, data.vread_max_id()->v, 1 })
: views->repliesInboxReadTillId; : views->repliesInboxReadTillId;
const auto maxId = data.vmax_id().value_or(views->repliesMaxId); const auto maxId = data.vmax_id().value_or(views->repliesMaxId);
const auto countsChanged = (views->replies.count != count) const auto countsChanged = (views->replies.count != count)

View file

@ -496,7 +496,7 @@ void HistoryService::applyAction(const MTPMessageAction &action) {
if (const auto channel = history()->peer->asMegagroup()) { if (const auto channel = history()->peer->asMegagroup()) {
const auto selfUserId = history()->session().userId(); const auto selfUserId = history()->session().userId();
for (const auto &item : data.vusers().v) { for (const auto &item : data.vusers().v) {
if (item.v == selfUserId) { if (peerFromUser(item) == selfUserId) {
channel->mgInfo->joinedMessageFound = true; channel->mgInfo->joinedMessageFound = true;
break; break;
} }

View file

@ -971,7 +971,7 @@ void CopyPostLink(
Assert(channel != nullptr); Assert(channel != nullptr);
if (const auto rootId = item->replyToTop()) { if (const auto rootId = item->replyToTop()) {
const auto root = item->history()->owner().message( const auto root = item->history()->owner().message(
channel->bareId(), peerToChannel(channel->id),
rootId); rootId);
const auto sender = root const auto sender = root
? root->discussionPostOriginalSender() ? root->discussionPostOriginalSender()

View file

@ -149,7 +149,7 @@ rpl::producer<Ui::GroupCallBarContent> GroupCallTracker::ContentByCall(
state->current.users.push_back({ state->current.users.push_back({
.userpic = pic.toImage(), .userpic = pic.toImage(),
.userpicKey = userpic.uniqueKey, .userpicKey = userpic.uniqueKey,
.id = userpic.peer->bareId(), .id = userpic.peer->id.value,
.speaking = userpic.speaking, .speaking = userpic.speaking,
}); });
if (userpic.peer->hasUserpic() if (userpic.peer->hasUserpic()

View file

@ -47,7 +47,7 @@ QString DocumentTimestampLinkBase(
FullMsgId context) { FullMsgId context) {
return QString( return QString(
"doc%1_%2_%3" "doc%1_%2_%3"
).arg(document->id).arg(context.channel).arg(context.msg); ).arg(document->id).arg(context.channel.bare).arg(context.msg);
} }
TextWithEntities AddTimestampLinks( TextWithEntities AddTimestampLinks(

View file

@ -50,7 +50,7 @@ private:
std::unique_ptr<PeerListRow> createRow(not_null<PeerData*> peer); std::unique_ptr<PeerListRow> createRow(not_null<PeerData*> peer);
struct SavedState : SavedStateBase { struct SavedState : SavedStateBase {
int32 preloadGroupId = 0; PeerId preloadGroupId = 0;
bool allLoaded = false; bool allLoaded = false;
bool wasLoading = false; bool wasLoading = false;
}; };
@ -59,7 +59,7 @@ private:
not_null<UserData*> _user; not_null<UserData*> _user;
mtpRequestId _preloadRequestId = 0; mtpRequestId _preloadRequestId = 0;
bool _allLoaded = false; bool _allLoaded = false;
int32 _preloadGroupId = 0; PeerId _preloadGroupId = 0;
}; };
@ -96,7 +96,9 @@ void ListController::loadMoreRows() {
} }
_preloadRequestId = _api.request(MTPmessages_GetCommonChats( _preloadRequestId = _api.request(MTPmessages_GetCommonChats(
_user->inputUser, _user->inputUser,
MTP_int(_preloadGroupId), MTP_int(peerIsChat(_preloadGroupId)
? peerToChat(_preloadGroupId).bare
: peerToChannel(_preloadGroupId).bare), // #TODO ids
MTP_int(kCommonGroupsPerPage) MTP_int(kCommonGroupsPerPage)
)).done([this](const MTPmessages_Chats &result) { )).done([this](const MTPmessages_Chats &result) {
_preloadRequestId = 0; _preloadRequestId = 0;
@ -112,7 +114,7 @@ void ListController::loadMoreRows() {
delegate()->peerListAppendRow( delegate()->peerListAppendRow(
createRow(peer)); createRow(peer));
} }
_preloadGroupId = peer->bareId(); _preloadGroupId = peer->id;
_allLoaded = false; _allLoaded = false;
} }
} }

View file

@ -690,11 +690,9 @@ void ListWidget::itemRemoved(not_null<const HistoryItem*> item) {
FullMsgId ListWidget::computeFullId( FullMsgId ListWidget::computeFullId(
UniversalMsgId universalId) const { UniversalMsgId universalId) const {
Expects(universalId != 0); Expects(universalId != 0);
auto peerChannel = [&] {
return _peer->isChannel() ? _peer->bareId() : NoChannel;
};
return (universalId > 0) return (universalId > 0)
? FullMsgId(peerChannel(), universalId) ? FullMsgId(peerToChannel(_peer->id), universalId)
: FullMsgId(NoChannel, ServerMaxMsgId + universalId); : FullMsgId(NoChannel, ServerMaxMsgId + universalId);
} }
@ -799,8 +797,8 @@ bool ListWidget::isMyItem(not_null<const HistoryItem*> item) const {
} }
bool ListWidget::isPossiblyMyId(FullMsgId fullId) const { bool ListWidget::isPossiblyMyId(FullMsgId fullId) const {
return (fullId.channel != 0) return fullId.channel
? (_peer->isChannel() && _peer->bareId() == fullId.channel) ? (_peer->isChannel() && peerToChannel(_peer->id) == fullId.channel)
: (!_peer->isChannel() || _migrated); : (!_peer->isChannel() || _migrated);
} }

View file

@ -438,7 +438,7 @@ void ListController::rowClicked(not_null<PeerListRow*> row) {
} }
bool ListController::appendRow(not_null<UserData*> user) { bool ListController::appendRow(not_null<UserData*> user) {
if (delegate()->peerListFindRow(user->id)) { if (delegate()->peerListFindRow(user->id.value)) {
return false; return false;
} }
delegate()->peerListAppendRow(createRow(user)); delegate()->peerListAppendRow(createRow(user));

View file

@ -166,7 +166,7 @@ Image *ItemBase::getResultThumb(Data::FileOrigin origin) const {
QPixmap ItemBase::getResultContactAvatar(int width, int height) const { QPixmap ItemBase::getResultContactAvatar(int width, int height) const {
if (_result->_type == Result::Type::Contact) { if (_result->_type == Result::Type::Contact) {
auto result = Ui::EmptyUserpic( auto result = Ui::EmptyUserpic(
Data::PeerUserpicColor(qHash(_result->_id)), Data::PeerUserpicColor(FakeChatId(BareId(qHash(_result->_id)))),
_result->getLayoutTitle() _result->getLayoutTitle()
).generate(width); ).generate(width);
if (result.height() != height * cIntRetinaFactor()) { if (result.height() != height * cIntRetinaFactor()) {

View file

@ -59,7 +59,7 @@ void SendDataCommon::addToHistory(
peerToMTP(fromId), peerToMTP(fromId),
peerToMTP(history->peer->id), peerToMTP(history->peer->id),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTP_int(viaBotId), MTP_int(viaBotId.bare), // #TODO ids
replyHeader, replyHeader,
mtpDate, mtpDate,
fields.text, fields.text,

View file

@ -153,7 +153,7 @@ void Step::finish(const MTPUser &user, QImage &&photo) {
const auto raw = existing.get(); const auto raw = existing.get();
if (const auto session = raw->maybeSession()) { if (const auto session = raw->maybeSession()) {
if (raw->mtp().environment() == _account->mtp().environment() if (raw->mtp().environment() == _account->mtp().environment()
&& user.c_user().vid().v == session->userId()) { && UserId(user.c_user().vid()) == session->userId()) {
_account->logOut(); _account->logOut();
crl::on_main(raw, [=] { crl::on_main(raw, [=] {
Core::App().domain().activate(raw); Core::App().domain().activate(raw);

View file

@ -35,6 +35,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Main { namespace Main {
namespace { namespace {
constexpr auto kWideIdsTag = ~uint64(0);
[[nodiscard]] QString ComposeDataString(const QString &dataName, int index) { [[nodiscard]] QString ComposeDataString(const QString &dataName, int index) {
auto result = dataName; auto result = dataName;
result.replace('#', QString()); result.replace('#', QString());
@ -127,7 +129,7 @@ uint64 Account::willHaveSessionUniqueId(MTP::Config *config) const {
if (!_sessionUserId) { if (!_sessionUserId) {
return 0; return 0;
} }
return uint64(uint32(_sessionUserId)) return _sessionUserId.bare
| (config && config->isTestMode() ? 0x0100'0000'0000'0000ULL : 0ULL); | (config && config->isTestMode() ? 0x0100'0000'0000'0000ULL : 0ULL);
} }
@ -155,7 +157,7 @@ void Account::createSession(
createSession( createSession(
MTP_user( MTP_user(
MTP_flags(flags), MTP_flags(flags),
MTP_int(base::take(_sessionUserId)), MTP_int(base::take(_sessionUserId).bare), // #TODO ids
MTPlong(), // access_hash MTPlong(), // access_hash
MTPstring(), // first_name MTPstring(), // first_name
MTPstring(), // last_name MTPstring(), // last_name
@ -276,7 +278,8 @@ QByteArray Account::serializeMtpAuthorization() const {
}; };
auto result = QByteArray(); auto result = QByteArray();
auto size = sizeof(qint32) + sizeof(qint32); // userId + mainDcId // wide tag + userId + mainDcId
auto size = 2 * sizeof(quint64) + sizeof(qint32);
size += keysSize(keys) + keysSize(keysToDestroy); size += keysSize(keys) + keysSize(keysToDestroy);
result.reserve(size); result.reserve(size);
{ {
@ -285,12 +288,17 @@ QByteArray Account::serializeMtpAuthorization() const {
const auto currentUserId = sessionExists() const auto currentUserId = sessionExists()
? session().userId() ? session().userId()
: 0; : UserId();
stream << qint32(currentUserId) << qint32(mainDcId); stream
<< quint64(kWideIdsTag)
<< quint64(currentUserId.bare)
<< qint32(mainDcId);
writeKeys(stream, keys); writeKeys(stream, keys);
writeKeys(stream, keysToDestroy); writeKeys(stream, keysToDestroy);
DEBUG_LOG(("MTP Info: Keys written, userId: %1, dcId: %2").arg(currentUserId).arg(mainDcId)); DEBUG_LOG(("MTP Info: Keys written, userId: %1, dcId: %2"
).arg(currentUserId.bare
).arg(mainDcId));
} }
return result; return result;
}; };
@ -343,8 +351,18 @@ void Account::setMtpAuthorization(const QByteArray &serialized) {
QDataStream stream(serialized); QDataStream stream(serialized);
stream.setVersion(QDataStream::Qt_5_1); stream.setVersion(QDataStream::Qt_5_1);
auto userId = Serialize::read<qint32>(stream); auto legacyUserId = Serialize::read<qint32>(stream);
auto mainDcId = Serialize::read<qint32>(stream); auto legacyMainDcId = Serialize::read<qint32>(stream);
auto userId = quint64();
auto mainDcId = qint32();
if (((uint64(legacyUserId) << 32) | uint64(legacyMainDcId))
== kWideIdsTag) {
userId = Serialize::read<quint64>(stream);
mainDcId = Serialize::read<qint32>(stream);
} else {
userId = legacyUserId;
mainDcId = legacyMainDcId;
}
if (stream.status() != QDataStream::Ok) { if (stream.status() != QDataStream::Ok) {
LOG(("MTP Error: " LOG(("MTP Error: "
"Could not read main fields from mtp authorization.")); "Could not read main fields from mtp authorization."));

View file

@ -212,12 +212,12 @@ rpl::producer<> Session::downloaderTaskFinished() const {
uint64 Session::uniqueId() const { uint64 Session::uniqueId() const {
// See also Account::willHaveSessionUniqueId. // See also Account::willHaveSessionUniqueId.
return uint64(uint32(userId())) return userId().bare
| (mtp().isTestMode() ? 0x0100'0000'0000'0000ULL : 0ULL); | (mtp().isTestMode() ? 0x0100'0000'0000'0000ULL : 0ULL);
} }
UserId Session::userId() const { UserId Session::userId() const {
return _user->bareId(); return peerToUser(_user->id);
} }
PeerId Session::userPeerId() const { PeerId Session::userPeerId() const {
@ -228,7 +228,7 @@ bool Session::validateSelf(const MTPUser &user) {
if (user.type() != mtpc_user || !user.c_user().is_self()) { if (user.type() != mtpc_user || !user.c_user().is_self()) {
LOG(("API Error: bad self user received.")); LOG(("API Error: bad self user received."));
return false; return false;
} else if (user.c_user().vid().v != userId()) { } else if (UserId(user.c_user().vid()) != userId()) {
LOG(("Auth Error: wrong self user received.")); LOG(("Auth Error: wrong self user received."));
crl::on_main(this, [=] { _account->logOut(); }); crl::on_main(this, [=] { _account->logOut(); });
return false; return false;

View file

@ -48,8 +48,8 @@ QByteArray SessionSettings::serialize() const {
stream << qint32(kVersionTag) << qint32(kVersion); stream << qint32(kVersionTag) << qint32(kVersion);
stream << static_cast<qint32>(_selectorTab); stream << static_cast<qint32>(_selectorTab);
stream << qint32(_groupStickersSectionHidden.size()); stream << qint32(_groupStickersSectionHidden.size());
for (auto peerId : _groupStickersSectionHidden) { for (const auto peerId : _groupStickersSectionHidden) {
stream << quint64(peerId); stream << SerializePeerId(peerId);
} }
stream << qint32(_supportSwitch); stream << qint32(_supportSwitch);
stream << qint32(_supportFixChatsOrder ? 1 : 0); stream << qint32(_supportFixChatsOrder ? 1 : 0);
@ -66,7 +66,7 @@ QByteArray SessionSettings::serialize() const {
} }
stream << qint32(_hiddenPinnedMessages.size()); stream << qint32(_hiddenPinnedMessages.size());
for (const auto &[key, value] : _hiddenPinnedMessages) { for (const auto &[key, value] : _hiddenPinnedMessages) {
stream << quint64(key) << qint32(value); stream << SerializePeerId(key) << qint32(value);
} }
stream << qint32(_dialogsFiltersEnabled ? 1 : 0); stream << qint32(_dialogsFiltersEnabled ? 1 : 0);
stream << qint32(_supportAllSilent ? 1 : 0); stream << qint32(_supportAllSilent ? 1 : 0);
@ -177,7 +177,8 @@ void SessionSettings::addFromSerialized(const QByteArray &serialized) {
"Bad data for SessionSettings::addFromSerialized()")); "Bad data for SessionSettings::addFromSerialized()"));
return; return;
} }
groupStickersSectionHidden.insert(peerId); groupStickersSectionHidden.emplace(
DeserializePeerId(peerId));
} }
} }
} }
@ -316,7 +317,7 @@ void SessionSettings::addFromSerialized(const QByteArray &serialized) {
"Bad data for SessionSettings::addFromSerialized()")); "Bad data for SessionSettings::addFromSerialized()"));
return; return;
} }
hiddenPinnedMessages.emplace(key, value); hiddenPinnedMessages.emplace(DeserializePeerId(key), value);
} }
} }
} }

View file

@ -39,15 +39,15 @@ using Context = GroupThumbs::Context;
using Key = GroupThumbs::Key; using Key = GroupThumbs::Key;
[[nodiscard]] QString DebugSerializeMsgId(FullMsgId itemId) { [[nodiscard]] QString DebugSerializeMsgId(FullMsgId itemId) {
return QString("msg%1_%2").arg(itemId.channel).arg(itemId.msg); return QString("msg%1_%2").arg(itemId.channel.bare).arg(itemId.msg);
} }
[[nodiscard]] QString DebugSerializePeer(PeerId peerId) { [[nodiscard]] QString DebugSerializePeer(PeerId peerId) {
return peerIsUser(peerId) return peerIsUser(peerId)
? QString("user%1").arg(peerToUser(peerId)) ? QString("user%1").arg(peerToUser(peerId).bare)
: peerIsChat(peerId) : peerIsChat(peerId)
? QString("chat%1").arg(peerToChat(peerId)) ? QString("chat%1").arg(peerToChat(peerId).bare)
: QString("channel%1").arg(peerToChannel(peerId)); : QString("channel%1").arg(peerToChannel(peerId).bare);
} }
[[nodiscard]] QString DebugSerializeKey(const Key &key) { [[nodiscard]] QString DebugSerializeKey(const Key &key) {

View file

@ -1779,7 +1779,7 @@ Data::FileOrigin OverlayWidget::fileOrigin() const {
if (_msgid) { if (_msgid) {
return _msgid; return _msgid;
} else if (_photo && _user) { } else if (_photo && _user) {
return Data::FileOriginUserPhoto(_user->bareId(), _photo->id); return Data::FileOriginUserPhoto(peerToUser(_user->id), _photo->id);
} else if (_photo && _peer && _peer->userpicPhotoId() == _photo->id) { } else if (_photo && _peer && _peer->userpicPhotoId() == _photo->id) {
return Data::FileOriginPeerPhoto(_peer->id); return Data::FileOriginPeerPhoto(_peer->id);
} }
@ -1794,7 +1794,7 @@ Data::FileOrigin OverlayWidget::fileOrigin(const Entity &entity) const {
} }
const auto photo = v::get<not_null<PhotoData*>>(entity.data); const auto photo = v::get<not_null<PhotoData*>>(entity.data);
if (_user) { if (_user) {
return Data::FileOriginUserPhoto(_user->bareId(), photo->id); return Data::FileOriginUserPhoto(peerToUser(_user->id), photo->id);
} else if (_peer && _peer->userpicPhotoId() == photo->id) { } else if (_peer && _peer->userpicPhotoId() == photo->id) {
return Data::FileOriginPeerPhoto(_peer->id); return Data::FileOriginPeerPhoto(_peer->id);
} }
@ -1875,10 +1875,7 @@ void OverlayWidget::handleSharedMediaUpdate(SharedMediaWithLastSlice &&update) {
std::optional<OverlayWidget::UserPhotosKey> OverlayWidget::userPhotosKey() const { std::optional<OverlayWidget::UserPhotosKey> OverlayWidget::userPhotosKey() const {
if (!_msgid && _user && _photo) { if (!_msgid && _user && _photo) {
return UserPhotosKey { return UserPhotosKey{ peerToUser(_user->id), _photo->id };
_user->bareId(),
_photo->id
};
} }
return std::nullopt; return std::nullopt;
} }

View file

@ -751,7 +751,7 @@ std::vector<not_null<const Value*>> FormController::submitGetErrors() {
bytes::make_span(_request.publicKey.toUtf8())); bytes::make_span(_request.publicKey.toUtf8()));
_submitRequestId = _api.request(MTPaccount_AcceptAuthorization( _submitRequestId = _api.request(MTPaccount_AcceptAuthorization(
MTP_int(_request.botId), MTP_int(_request.botId.bare), // #TODO ids
MTP_string(_request.scope), MTP_string(_request.scope),
MTP_string(_request.publicKey), MTP_string(_request.publicKey),
MTP_vector<MTPSecureValueHash>(prepared.hashes), MTP_vector<MTPSecureValueHash>(prepared.hashes),
@ -2290,7 +2290,7 @@ void FormController::requestForm() {
return; return;
} }
_formRequestId = _api.request(MTPaccount_GetAuthorizationForm( _formRequestId = _api.request(MTPaccount_GetAuthorizationForm(
MTP_int(_request.botId), MTP_int(_request.botId.bare), // #TODO ids
MTP_string(_request.scope), MTP_string(_request.scope),
MTP_string(_request.publicKey) MTP_string(_request.publicKey)
)).done([=](const MTPaccount_AuthorizationForm &result) { )).done([=](const MTPaccount_AuthorizationForm &result) {

View file

@ -91,7 +91,7 @@ void BlockPeerBoxController::prepareViewHook() {
session().changes().peerUpdates( session().changes().peerUpdates(
Data::PeerUpdate::Flag::IsBlocked Data::PeerUpdate::Flag::IsBlocked
) | rpl::start_with_next([=](const Data::PeerUpdate &update) { ) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
if (auto row = delegate()->peerListFindRow(update.peer->id)) { if (auto row = delegate()->peerListFindRow(update.peer->id.value)) {
updateIsBlocked(row, update.peer); updateIsBlocked(row, update.peer);
delegate()->peerListUpdateRow(row); delegate()->peerListUpdateRow(row);
} }
@ -286,7 +286,7 @@ void BlockedBoxController::handleBlockedEvent(not_null<PeerData*> user) {
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
delegate()->peerListScrollToTop(); delegate()->peerListScrollToTop();
} }
} else if (auto row = delegate()->peerListFindRow(user->id)) { } else if (auto row = delegate()->peerListFindRow(user->id.value)) {
delegate()->peerListRemoveRow(row); delegate()->peerListRemoveRow(row);
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
} }
@ -310,7 +310,7 @@ void BlockedBoxController::BlockNewPeer(
} }
bool BlockedBoxController::appendRow(not_null<PeerData*> peer) { bool BlockedBoxController::appendRow(not_null<PeerData*> peer) {
if (delegate()->peerListFindRow(peer->id)) { if (delegate()->peerListFindRow(peer->id.value)) {
return false; return false;
} }
delegate()->peerListAppendRow(createRow(peer)); delegate()->peerListAppendRow(createRow(peer));
@ -318,7 +318,7 @@ bool BlockedBoxController::appendRow(not_null<PeerData*> peer) {
} }
bool BlockedBoxController::prependRow(not_null<PeerData*> peer) { bool BlockedBoxController::prependRow(not_null<PeerData*> peer) {
if (delegate()->peerListFindRow(peer->id)) { if (delegate()->peerListFindRow(peer->id.value)) {
return false; return false;
} }
delegate()->peerListPrependRow(createRow(peer)); delegate()->peerListPrependRow(createRow(peer));
@ -746,7 +746,7 @@ object_ptr<Ui::RpWidget> ForwardsPrivacyController::setupAboveWidget(
auto message = GenerateForwardedItem( auto message = GenerateForwardedItem(
delegate(), delegate(),
_controller->session().data().history( _controller->session().data().history(
peerFromUser(PeerData::kServiceNotificationsId)), PeerData::kServiceNotificationsId),
tr::lng_edit_privacy_forwards_sample_message(tr::now)); tr::lng_edit_privacy_forwards_sample_message(tr::now));
const auto view = message.get(); const auto view = message.get();

View file

@ -1039,13 +1039,13 @@ bool ReadSetting(
} break; } break;
case dbiHiddenPinnedMessagesOld: { case dbiHiddenPinnedMessagesOld: {
auto v = QMap<PeerId, MsgId>(); auto v = QMap<uint64, MsgId>();
stream >> v; stream >> v;
if (!CheckStreamStatus(stream)) return false; if (!CheckStreamStatus(stream)) return false;
for (auto i = v.begin(), e = v.end(); i != e; ++i) { for (auto i = v.begin(), e = v.end(); i != e; ++i) {
context.sessionSettings().setHiddenPinnedMessageId( context.sessionSettings().setHiddenPinnedMessageId(
i.key(), DeserializePeerId(i.key()),
i.value()); i.value());
} }
context.legacyRead = true; context.legacyRead = true;

View file

@ -903,10 +903,11 @@ Window::Theme::Saved readThemeUsingKey(FileKey key) {
auto result = Saved(); auto result = Saved();
auto &object = result.object; auto &object = result.object;
auto &cache = result.cache; auto &cache = result.cache;
auto field1 = qint32();
auto field2 = quint32();
theme.stream >> object.content; theme.stream >> object.content;
theme.stream >> tag >> object.pathAbsolute; theme.stream >> tag >> object.pathAbsolute;
if (tag == kThemeNewPathRelativeTag) { if (tag == kThemeNewPathRelativeTag) {
auto creator = qint32();
theme.stream theme.stream
>> object.pathRelative >> object.pathRelative
>> object.cloud.id >> object.cloud.id
@ -914,8 +915,7 @@ Window::Theme::Saved readThemeUsingKey(FileKey key) {
>> object.cloud.slug >> object.cloud.slug
>> object.cloud.title >> object.cloud.title
>> object.cloud.documentId >> object.cloud.documentId
>> creator; >> field1;
object.cloud.createdBy = creator;
} else { } else {
object.pathRelative = tag; object.pathRelative = tag;
} }
@ -947,18 +947,29 @@ Window::Theme::Saved readThemeUsingKey(FileKey key) {
} }
} }
} }
int32 cachePaletteChecksum = 0;
int32 cacheContentChecksum = 0;
QByteArray cacheColors;
QByteArray cacheBackground;
theme.stream
>> cachePaletteChecksum
>> cacheContentChecksum
>> cacheColors
>> cacheBackground
>> field2;
if (!ignoreCache) { if (!ignoreCache) {
quint32 backgroundIsTiled = 0;
theme.stream
>> cache.paletteChecksum
>> cache.contentChecksum
>> cache.colors
>> cache.background
>> backgroundIsTiled;
cache.tiled = (backgroundIsTiled == 1);
if (theme.stream.status() != QDataStream::Ok) { if (theme.stream.status() != QDataStream::Ok) {
return {}; return {};
} }
cache.paletteChecksum = cachePaletteChecksum;
cache.contentChecksum = cacheContentChecksum;
cache.colors = std::move(cacheColors);
cache.background = std::move(cacheBackground);
cache.tiled = ((field2 & quint32(0xFF)) == 1);
}
if (tag == kThemeNewPathRelativeTag) {
object.cloud.createdBy = UserId(
((quint64(field2) >> 8) << 32) | quint64(quint32(field1)));
} }
return result; return result;
} }
@ -1011,6 +1022,11 @@ void writeTheme(const Window::Theme::Saved &saved) {
+ Serialize::bytearraySize(cache.colors) + Serialize::bytearraySize(cache.colors)
+ Serialize::bytearraySize(cache.background) + Serialize::bytearraySize(cache.background)
+ sizeof(quint32); + sizeof(quint32);
const auto bareCreatedById = object.cloud.createdBy.bare;
Assert((bareCreatedById & PeerId::kChatTypeMask) == bareCreatedById);
const auto field1 = qint32(quint32(bareCreatedById & 0xFFFFFFFFULL));
const auto field2 = quint32(cache.tiled ? 1 : 0)
| (quint32(bareCreatedById >> 32) << 8);
EncryptedDescriptor data(size); EncryptedDescriptor data(size);
data.stream data.stream
<< object.content << object.content
@ -1022,12 +1038,12 @@ void writeTheme(const Window::Theme::Saved &saved) {
<< object.cloud.slug << object.cloud.slug
<< object.cloud.title << object.cloud.title
<< object.cloud.documentId << object.cloud.documentId
<< qint32(object.cloud.createdBy) << field1
<< cache.paletteChecksum << cache.paletteChecksum
<< cache.contentChecksum << cache.contentChecksum
<< cache.colors << cache.colors
<< cache.background << cache.background
<< quint32(cache.tiled ? 1 : 0); << field2;
FileWriteDescriptor file(themeKey, _basePath); FileWriteDescriptor file(themeKey, _basePath);
file.writeEncrypted(data, SettingsKey); file.writeEncrypted(data, SettingsKey);

View file

@ -43,7 +43,7 @@ std::optional<StorageImageLocation> readLegacyStorageImageLocationOrTag(
return StorageImageLocation( return StorageImageLocation(
StorageFileLocation( StorageFileLocation(
dc, dc,
UserId(0), UserId(0), // self
MTP_inputFileLocation( MTP_inputFileLocation(
MTP_long(volume), MTP_long(volume),
MTP_int(local), MTP_int(local),
@ -139,8 +139,8 @@ uint32 peerSize(not_null<PeerData*> peer) {
return result; return result;
} }
void writePeer(QDataStream &stream, PeerData *peer) { void writePeer(QDataStream &stream, not_null<PeerData*> peer) {
stream << quint64(peer->id) << quint64(peer->userpicPhotoId()); stream << SerializePeerId(peer->id) << quint64(peer->userpicPhotoId());
writeImageLocation(stream, peer->userpicLocation()); writeImageLocation(stream, peer->userpicLocation());
if (const auto user = peer->asUser()) { if (const auto user = peer->asUser()) {
stream stream
@ -163,13 +163,15 @@ void writePeer(QDataStream &stream, PeerData *peer) {
<< qint32(user->isContact() ? 1 : 0) << qint32(user->isContact() ? 1 : 0)
<< qint32(user->isBot() ? user->botInfo->version : -1); << qint32(user->isBot() ? user->botInfo->version : -1);
} else if (const auto chat = peer->asChat()) { } else if (const auto chat = peer->asChat()) {
auto field1 = qint32(uint32(chat->creator.bare & 0xFFFFFFFFULL));
auto field2 = qint32(uint32(chat->creator.bare >> 32) << 8);
stream stream
<< chat->name << chat->name
<< qint32(chat->count) << qint32(chat->count)
<< qint32(chat->date) << qint32(chat->date)
<< qint32(chat->version()) << qint32(chat->version())
<< qint32(chat->creator) << field1
<< qint32(0) << field2
<< quint32(chat->flags()) << quint32(chat->flags())
<< chat->inviteLink(); << chat->inviteLink();
} else if (const auto channel = peer->asChannel()) { } else if (const auto channel = peer->asChannel()) {
@ -188,8 +190,9 @@ PeerData *readPeer(
not_null<Main::Session*> session, not_null<Main::Session*> session,
int streamAppVersion, int streamAppVersion,
QDataStream &stream) { QDataStream &stream) {
quint64 peerId = 0, photoId = 0; quint64 peerIdSerialized = 0, photoId = 0;
stream >> peerId >> photoId; stream >> peerIdSerialized >> photoId;
const auto peerId = DeserializePeerId(peerIdSerialized);
if (!peerId) { if (!peerId) {
return nullptr; return nullptr;
} }
@ -248,15 +251,20 @@ PeerData *readPeer(
user->input = MTP_inputPeerSelf(); user->input = MTP_inputPeerSelf();
user->inputUser = MTP_inputUserSelf(); user->inputUser = MTP_inputUserSelf();
} else { } else {
user->input = MTP_inputPeerUser(MTP_int(peerToUser(user->id)), MTP_long(user->accessHash())); // #TODO ids
user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id)), MTP_long(user->accessHash())); user->input = MTP_inputPeerUser(MTP_int(peerToUser(user->id).bare), MTP_long(user->accessHash()));
user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id).bare), MTP_long(user->accessHash()));
} }
} }
} else if (const auto chat = result->asChat()) { } else if (const auto chat = result->asChat()) {
QString name, inviteLink; QString name, inviteLink;
qint32 count, date, version, creator, oldForbidden; qint32 count, date, version, field1, field2;
quint32 flagsData, flags; quint32 flagsData, flags;
stream >> name >> count >> date >> version >> creator >> oldForbidden >> flagsData >> inviteLink; stream >> name >> count >> date >> version >> field1 >> field2 >> flagsData >> inviteLink;
const auto creator = UserId(
BareId(uint32(field1)) | (BareId(uint32(field2) >> 8) << 32));
const auto oldForbidden = ((uint32(field2) & 0xFF) == 1);
if (streamAppVersion >= 9012) { if (streamAppVersion >= 9012) {
flags = flagsData; flags = flagsData;
@ -282,7 +290,8 @@ PeerData *readPeer(
chat->setFlags(MTPDchat::Flags::from_raw(flags)); chat->setFlags(MTPDchat::Flags::from_raw(flags));
chat->setInviteLink(inviteLink); chat->setInviteLink(inviteLink);
chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id))); // #TODO ids
chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id).bare));
} }
} else if (const auto channel = result->asChannel()) { } else if (const auto channel = result->asChannel()) {
QString name, inviteLink; QString name, inviteLink;
@ -308,8 +317,9 @@ PeerData *readPeer(
channel->setFlags(MTPDchannel::Flags::from_raw(flags)); channel->setFlags(MTPDchannel::Flags::from_raw(flags));
channel->setInviteLink(inviteLink); channel->setInviteLink(inviteLink);
channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); // #TODO ids
channel->inputChannel = MTP_inputChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access)); channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id).bare), MTP_long(access));
channel->inputChannel = MTP_inputChannel(MTP_int(peerToChannel(channel->id).bare), MTP_long(access));
} }
} }
if (apply) { if (apply) {
@ -317,7 +327,7 @@ PeerData *readPeer(
const auto location = (userpic->valid() && userpic->isLegacy()) const auto location = (userpic->valid() && userpic->isLegacy())
? userpic->convertToModern( ? userpic->convertToModern(
LocationType::PeerPhoto, LocationType::PeerPhoto,
result->id, result->id.value,
userpicAccessHash) userpicAccessHash)
: *userpic; : *userpic;
result->setUserpic(photoId, location); result->setUserpic(photoId, location);
@ -326,9 +336,10 @@ PeerData *readPeer(
} }
QString peekUserPhone(int streamAppVersion, QDataStream &stream) { QString peekUserPhone(int streamAppVersion, QDataStream &stream) {
quint64 peerId = 0, photoId = 0; quint64 peerIdSerialized = 0, photoId = 0;
stream >> peerId >> photoId; stream >> peerIdSerialized >> photoId;
DEBUG_LOG(("peekUserPhone.id: %1").arg(peerId)); const auto peerId = DeserializePeerId(peerIdSerialized);
DEBUG_LOG(("peekUserPhone.id: %1").arg(peerId.value));
if (!peerId if (!peerId
|| !peerIsUser(peerId) || !peerIsUser(peerId)
|| !readStorageImageLocation(streamAppVersion, stream)) { || !readStorageImageLocation(streamAppVersion, stream)) {

View file

@ -30,7 +30,7 @@ std::optional<ImageLocation> readImageLocation(
QDataStream &stream); QDataStream &stream);
uint32 peerSize(not_null<PeerData*> peer); uint32 peerSize(not_null<PeerData*> peer);
void writePeer(QDataStream &stream, PeerData *peer); void writePeer(QDataStream &stream, not_null<PeerData*> peer);
PeerData *readPeer( PeerData *readPeer(
not_null<Main::Session*> session, not_null<Main::Session*> session,
int streamAppVersion, int streamAppVersion,

View file

@ -276,10 +276,11 @@ Account::ReadMapResult Account::readMapWith(
map.stream >> count; map.stream >> count;
for (quint32 i = 0; i < count; ++i) { for (quint32 i = 0; i < count; ++i) {
FileKey key; FileKey key;
quint64 p; quint64 peerIdSerialized;
map.stream >> key >> p; map.stream >> key >> peerIdSerialized;
draftsMap.emplace(p, key); const auto peerId = DeserializePeerId(peerIdSerialized);
draftsNotReadMap.emplace(p, true); draftsMap.emplace(peerId, key);
draftsNotReadMap.emplace(peerId, true);
} }
} break; } break;
case lskSelfSerialized: { case lskSelfSerialized: {
@ -290,9 +291,10 @@ Account::ReadMapResult Account::readMapWith(
map.stream >> count; map.stream >> count;
for (quint32 i = 0; i < count; ++i) { for (quint32 i = 0; i < count; ++i) {
FileKey key; FileKey key;
quint64 p; quint64 peerIdSerialized;
map.stream >> key >> p; map.stream >> key >> peerIdSerialized;
draftCursorsMap.emplace(p, key); const auto peerId = DeserializePeerId(peerIdSerialized);
draftCursorsMap.emplace(peerId, key);
} }
} break; } break;
case lskLegacyImages: case lskLegacyImages:
@ -494,13 +496,13 @@ void Account::writeMap() {
if (!_draftsMap.empty()) { if (!_draftsMap.empty()) {
mapData.stream << quint32(lskDraft) << quint32(_draftsMap.size()); mapData.stream << quint32(lskDraft) << quint32(_draftsMap.size());
for (const auto &[key, value] : _draftsMap) { for (const auto &[key, value] : _draftsMap) {
mapData.stream << quint64(value) << quint64(key); mapData.stream << quint64(value) << SerializePeerId(key);
} }
} }
if (!_draftCursorsMap.empty()) { if (!_draftCursorsMap.empty()) {
mapData.stream << quint32(lskDraftPosition) << quint32(_draftCursorsMap.size()); mapData.stream << quint32(lskDraftPosition) << quint32(_draftCursorsMap.size());
for (const auto &[key, value] : _draftCursorsMap) { for (const auto &[key, value] : _draftCursorsMap) {
mapData.stream << quint64(value) << quint64(key); mapData.stream << quint64(value) << SerializePeerId(key);
} }
} }
if (_locationsKey) { if (_locationsKey) {
@ -1036,7 +1038,7 @@ void Account::writeDrafts(
EncryptedDescriptor data(size); EncryptedDescriptor data(size);
data.stream data.stream
<< quint64(kMultiDraftTag) << quint64(kMultiDraftTag)
<< quint64(peerId) << SerializePeerId(peerId)
<< quint32(count); << quint32(count);
const auto writeCallback = [&]( const auto writeCallback = [&](
@ -1102,7 +1104,7 @@ void Account::writeDraftCursors(
EncryptedDescriptor data(size); EncryptedDescriptor data(size);
data.stream data.stream
<< quint64(kMultiDraftTag) << quint64(kMultiDraftTag)
<< quint64(peerId) << SerializePeerId(peerId)
<< quint32(count); << quint32(count);
const auto writeCallback = [&]( const auto writeCallback = [&](
@ -1155,9 +1157,10 @@ void Account::readDraftCursors(PeerId peerId, Data::HistoryDrafts &map) {
readDraftCursorsLegacy(peerId, draft, tag, map); readDraftCursorsLegacy(peerId, draft, tag, map);
return; return;
} }
quint64 draftPeer = 0; quint64 draftPeerSerialized = 0;
quint32 count = 0; quint32 count = 0;
draft.stream >> draftPeer >> count; draft.stream >> draftPeerSerialized >> count;
const auto draftPeer = DeserializePeerId(draftPeerSerialized);
if (!count || count > 1000 || draftPeer != peerId) { if (!count || count > 1000 || draftPeer != peerId) {
clearDraftCursors(peerId); clearDraftCursors(peerId);
return; return;
@ -1174,15 +1177,16 @@ void Account::readDraftCursors(PeerId peerId, Data::HistoryDrafts &map) {
void Account::readDraftCursorsLegacy( void Account::readDraftCursorsLegacy(
PeerId peerId, PeerId peerId,
details::FileReadDescriptor &draft, details::FileReadDescriptor &draft,
quint64 draftPeer, quint64 draftPeerSerialized,
Data::HistoryDrafts &map) { Data::HistoryDrafts &map) {
qint32 localPosition = 0, localAnchor = 0, localScroll = QFIXED_MAX; qint32 localPosition = 0, localAnchor = 0, localScroll = QFIXED_MAX;
qint32 editPosition = 0, editAnchor = 0, editScroll = QFIXED_MAX; qint32 editPosition = 0, editAnchor = 0, editScroll = QFIXED_MAX;
draft.stream >> draftPeer >> localPosition >> localAnchor >> localScroll; draft.stream >> localPosition >> localAnchor >> localScroll;
if (!draft.stream.atEnd()) { if (!draft.stream.atEnd()) {
draft.stream >> editPosition >> editAnchor >> editScroll; draft.stream >> editPosition >> editAnchor >> editScroll;
} }
const auto draftPeer = DeserializePeerId(draftPeerSerialized);
if (draftPeer != peerId) { if (draftPeer != peerId) {
clearDraftCursors(peerId); clearDraftCursors(peerId);
return; return;
@ -1237,8 +1241,9 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
return; return;
} }
quint32 count = 0; quint32 count = 0;
quint64 draftPeer = 0; quint64 draftPeerSerialized = 0;
draft.stream >> draftPeer >> count; draft.stream >> draftPeerSerialized >> count;
const auto draftPeer = DeserializePeerId(draftPeerSerialized);
if (!count || count > 1000 || draftPeer != peerId) { if (!count || count > 1000 || draftPeer != peerId) {
ClearKey(j->second, _basePath); ClearKey(j->second, _basePath);
_draftsMap.erase(j); _draftsMap.erase(j);
@ -1287,7 +1292,7 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
void Account::readDraftsWithCursorsLegacy( void Account::readDraftsWithCursorsLegacy(
not_null<History*> history, not_null<History*> history,
details::FileReadDescriptor &draft, details::FileReadDescriptor &draft,
quint64 draftPeer) { quint64 draftPeerSerialized) {
TextWithTags msgData, editData; TextWithTags msgData, editData;
QByteArray msgTagsSerialized, editTagsSerialized; QByteArray msgTagsSerialized, editTagsSerialized;
qint32 msgReplyTo = 0, msgPreviewCancelled = 0, editMsgId = 0, editPreviewCancelled = 0; qint32 msgReplyTo = 0, msgPreviewCancelled = 0, editMsgId = 0, editPreviewCancelled = 0;
@ -1309,6 +1314,7 @@ void Account::readDraftsWithCursorsLegacy(
} }
} }
const auto peerId = history->peer->id; const auto peerId = history->peer->id;
const auto draftPeer = DeserializePeerId(draftPeerSerialized);
if (draftPeer != peerId) { if (draftPeer != peerId) {
const auto j = _draftsMap.find(peerId); const auto j = _draftsMap.find(peerId);
if (j != _draftsMap.cend()) { if (j != _draftsMap.cend()) {
@ -2511,7 +2517,7 @@ void Account::writeTrustedBots() {
data.stream << qint32(_trustedBots.size()); data.stream << qint32(_trustedBots.size());
for (const auto &[peerId, mask] : _trustedBots) { for (const auto &[peerId, mask] : _trustedBots) {
// value: 8 bit mask, 56 bit bot peer_id. // value: 8 bit mask, 56 bit bot peer_id.
auto value = quint64(peerId); auto value = SerializePeerId(peerId);
Assert((value >> 56) == 0); Assert((value >> 56) == 0);
value |= (quint64(mask) << 56); value |= (quint64(mask) << 56);
data.stream << value; data.stream << value;
@ -2539,7 +2545,8 @@ void Account::readTrustedBots() {
trusted.stream >> value; trusted.stream >> value;
const auto mask = base::flags<BotTrustFlag>::from_raw( const auto mask = base::flags<BotTrustFlag>::from_raw(
uchar(value >> 56)); uchar(value >> 56));
const auto peerId = value & ~(0xFFULL << 56); const auto peerIdSerialized = value & ~(0xFFULL << 56);
const auto peerId = DeserializePeerId(peerIdSerialized);
_trustedBots.emplace(peerId, mask); _trustedBots.emplace(peerId, mask);
} }
} }

View file

@ -195,13 +195,13 @@ private:
void readDraftCursorsLegacy( void readDraftCursorsLegacy(
PeerId peerId, PeerId peerId,
details::FileReadDescriptor &draft, details::FileReadDescriptor &draft,
quint64 draftPeer, quint64 draftPeerSerialized,
Data::HistoryDrafts &map); Data::HistoryDrafts &map);
void clearDraftCursors(PeerId peerId); void clearDraftCursors(PeerId peerId);
void readDraftsWithCursorsLegacy( void readDraftsWithCursorsLegacy(
not_null<History*> history, not_null<History*> history,
details::FileReadDescriptor &draft, details::FileReadDescriptor &draft,
quint64 draftPeer); quint64 draftPeerSerialized);
void writeStickerSet( void writeStickerSet(
QDataStream &stream, QDataStream &stream,

View file

@ -42,8 +42,8 @@ struct UserPhotosRemoveOne {
UserPhotosRemoveOne( UserPhotosRemoveOne(
UserId userId, UserId userId,
PhotoId photoId) PhotoId photoId)
: userId(userId) : userId(userId)
, photoId(photoId) { , photoId(photoId) {
} }
UserId userId = 0; UserId userId = 0;

View file

@ -576,11 +576,13 @@ QString InterpretSendPath(
auto caption = QString(); auto caption = QString();
for (const auto &line : lines) { for (const auto &line : lines) {
if (line.startsWith(qstr("from: "))) { if (line.startsWith(qstr("from: "))) {
if (window->session().userId() != line.midRef(qstr("from: ").size()).toInt()) { if (window->session().userId().bare
!= line.midRef(qstr("from: ").size()).toULongLong()) {
return "App Error: Wrong current user."; return "App Error: Wrong current user.";
} }
} else if (line.startsWith(qstr("channel: "))) { } else if (line.startsWith(qstr("channel: "))) {
const auto channelId = line.midRef(qstr("channel: ").size()).toInt(); const auto channelId = line.midRef(
qstr("channel: ").size()).toULongLong();
toId = peerFromChannel(channelId); toId = peerFromChannel(channelId);
} else if (line.startsWith(qstr("file: "))) { } else if (line.startsWith(qstr("file: "))) {
const auto path = line.mid(qstr("file: ").size()); const auto path = line.mid(qstr("file: ").size());
@ -598,7 +600,8 @@ QString InterpretSendPath(
} }
const auto history = window->session().data().historyLoaded(toId); const auto history = window->session().data().historyLoaded(toId);
if (!history) { if (!history) {
return "App Error: Could not find channel with id: " + QString::number(peerToChannel(toId)); return "App Error: Could not find channel with id: "
+ QString::number(peerToChannel(toId).bare);
} }
Ui::showPeerHistory(history, ShowAtUnreadMsgId); Ui::showPeerHistory(history, ShowAtUnreadMsgId);
history->session().api().sendFiles( history->session().api().sendFiles(

View file

@ -18,7 +18,7 @@ namespace Ui {
struct GroupCallUser { struct GroupCallUser {
QImage userpic; QImage userpic;
std::pair<uint64, uint64> userpicKey = {}; std::pair<uint64, uint64> userpicKey = {};
int32 id = 0; uint64 id = 0;
bool speaking = false; bool speaking = false;
}; };

View file

@ -23,8 +23,11 @@ constexpr auto kDocumentBaseCacheTag = 0x0000000000010000ULL;
constexpr auto kDocumentBaseCacheMask = 0x000000000000FF00ULL; constexpr auto kDocumentBaseCacheMask = 0x000000000000FF00ULL;
constexpr auto kPhotoBaseCacheTag = 0x0000000000020000ULL; constexpr auto kPhotoBaseCacheTag = 0x0000000000020000ULL;
constexpr auto kPhotoBaseCacheMask = 0x000000000000FF00ULL; constexpr auto kPhotoBaseCacheMask = 0x000000000000FF00ULL;
constexpr auto kSerializeTypeShift = quint8(0x08);
constexpr auto kNonStorageLocationToken = quint8(0x10); constexpr auto kNonStorageLocationToken = quint8(0x10);
constexpr auto kLegacyInMessagePeerIdFlag = quint8(0x08);
constexpr auto kModernLocationFlag = quint8(0x20);
constexpr auto kInMessageFieldsFlag = quint8(0x40);
enum class NonStorageLocationType : quint8 { enum class NonStorageLocationType : quint8 {
Web, Web,
@ -34,24 +37,24 @@ enum class NonStorageLocationType : quint8 {
}; };
MTPInputPeer GenerateInputPeer( MTPInputPeer GenerateInputPeer(
uint64 id, PeerId id,
uint64 accessHash, uint64 accessHash,
int32 inMessagePeerId, PeerId inMessagePeerId,
int32 inMessageId, int32 inMessageId,
int32 self) { UserId self) {
const auto bareId = [&] { const auto bareId = [&] {
return peerToBareMTPInt(id); return peerToBareMTPInt(id);
}; };
if (inMessagePeerId > 0 && inMessageId) { if (inMessageId && peerIsUser(inMessagePeerId)) {
return MTP_inputPeerUserFromMessage( return MTP_inputPeerUserFromMessage(
GenerateInputPeer(id, accessHash, 0, 0, self), GenerateInputPeer(id, accessHash, 0, 0, self),
MTP_int(inMessageId), MTP_int(inMessageId),
MTP_int(inMessagePeerId)); MTP_int(peerToUser(inMessagePeerId).bare)); // #TODO ids
} else if (inMessagePeerId < 0 && inMessageId) { } else if (inMessageId && peerIsChannel(inMessagePeerId)) {
return MTP_inputPeerChannelFromMessage( return MTP_inputPeerChannelFromMessage(
GenerateInputPeer(id, accessHash, 0, 0, self), GenerateInputPeer(id, accessHash, 0, 0, self),
MTP_int(inMessageId), MTP_int(inMessageId),
MTP_int(-inMessagePeerId)); MTP_int(peerToChannel(inMessagePeerId).bare)); // #TODO ids
} else if (!id) { } else if (!id) {
return MTP_inputPeerEmpty(); return MTP_inputPeerEmpty();
} else if (id == peerFromUser(self)) { } else if (id == peerFromUser(self)) {
@ -73,7 +76,7 @@ WebFileLocation WebFileLocation::Null;
StorageFileLocation::StorageFileLocation( StorageFileLocation::StorageFileLocation(
int32 dcId, int32 dcId,
int32 self, UserId self,
const MTPInputFileLocation &tl) const MTPInputFileLocation &tl)
: _dcId(dcId) { : _dcId(dcId) {
tl.match([&](const MTPDinputFileLocation &data) { tl.match([&](const MTPDinputFileLocation &data) {
@ -120,14 +123,14 @@ StorageFileLocation::StorageFileLocation(
const MTPDinputPeerEmpty &data) { const MTPDinputPeerEmpty &data) {
_id = 0; _id = 0;
}, [&](const MTPDinputPeerSelf &data) { }, [&](const MTPDinputPeerSelf &data) {
_id = peerFromUser(self); _id = peerFromUser(self).value;
}, [&](const MTPDinputPeerChat &data) { }, [&](const MTPDinputPeerChat &data) {
_id = peerFromChat(data.vchat_id()); _id = peerFromChat(data.vchat_id()).value;
}, [&](const MTPDinputPeerUser &data) { }, [&](const MTPDinputPeerUser &data) {
_id = peerFromUser(data.vuser_id()); _id = peerFromUser(data.vuser_id()).value;
_accessHash = data.vaccess_hash().v; _accessHash = data.vaccess_hash().v;
}, [&](const MTPDinputPeerChannel &data) { }, [&](const MTPDinputPeerChannel &data) {
_id = peerFromChannel(data.vchannel_id()); _id = peerFromChannel(data.vchannel_id()).value;
_accessHash = data.vaccess_hash().v; _accessHash = data.vaccess_hash().v;
}); });
data.vpeer().match(fillPeer, [&]( data.vpeer().match(fillPeer, [&](
@ -136,19 +139,21 @@ StorageFileLocation::StorageFileLocation(
// Bad data provided. // Bad data provided.
_id = _accessHash = 0; _id = _accessHash = 0;
}); });
_inMessagePeerId = data.vuser_id().v; _inMessagePeerId = peerFromUser(data.vuser_id());
_inMessageId = data.vmsg_id().v; _inMessageId = data.vmsg_id().v;
}, [&](const MTPDinputPeerChannelFromMessage &data) { }, [&](const MTPDinputPeerChannelFromMessage &data) {
data.vpeer().match(fillPeer, [&](auto &&) { data.vpeer().match(fillPeer, [&](auto &&) {
// Bad data provided. // Bad data provided.
_id = _accessHash = 0; _id = _accessHash = 0;
}); });
_inMessagePeerId = -data.vchannel_id().v; _inMessagePeerId = peerFromChannel(data.vchannel_id());
_inMessageId = data.vmsg_id().v; _inMessageId = data.vmsg_id().v;
}); });
_volumeId = data.vphoto_id().v; _volumeId = data.vphoto_id().v;
_localId = 0;
_sizeLetter = data.is_big() ? 'c' : 'a'; _sizeLetter = data.is_big() ? 'c' : 'a';
// _localId place is used in serialization.
Ensures(_localId == 0);
}, [&](const MTPDinputStickerSetThumb &data) { }, [&](const MTPDinputStickerSetThumb &data) {
_type = Type::StickerSetThumb; _type = Type::StickerSetThumb;
data.vstickerset().match([&](const MTPDinputStickerSetEmpty &data) { data.vstickerset().match([&](const MTPDinputStickerSetEmpty &data) {
@ -195,7 +200,7 @@ uint64 StorageFileLocation::objectId() const {
return _id; return _id;
} }
MTPInputFileLocation StorageFileLocation::tl(int32 self) const { MTPInputFileLocation StorageFileLocation::tl(UserId self) const {
switch (_type) { switch (_type) {
case Type::Legacy: case Type::Legacy:
return MTP_inputFileLocation( return MTP_inputFileLocation(
@ -239,7 +244,7 @@ MTPInputFileLocation StorageFileLocation::tl(int32 self) const {
? MTPDinputPeerPhotoFileLocation::Flag::f_big ? MTPDinputPeerPhotoFileLocation::Flag::f_big
: MTPDinputPeerPhotoFileLocation::Flag(0)), : MTPDinputPeerPhotoFileLocation::Flag(0)),
GenerateInputPeer( GenerateInputPeer(
_id, PeerId(_id),
_accessHash, _accessHash,
_inMessagePeerId, _inMessagePeerId,
_inMessageId, _inMessageId,
@ -269,15 +274,28 @@ QByteArray StorageFileLocation::serialize() const {
buffer.open(QIODevice::WriteOnly); buffer.open(QIODevice::WriteOnly);
auto stream = QDataStream(&buffer); auto stream = QDataStream(&buffer);
stream.setVersion(QDataStream::Qt_5_1); stream.setVersion(QDataStream::Qt_5_1);
Assert(!(quint8(_type) & kModernLocationFlag)
&& !(quint8(_type) & kInMessageFieldsFlag));
auto typeWithFlags = quint8(_type) | kModernLocationFlag;
auto field1 = qint32(_localId);
auto field2 = qint32(0);
if (_inMessagePeerId != 0) {
Assert(field1 == 0);
typeWithFlags |= kInMessageFieldsFlag;
field1 = qint32(uint32(_inMessagePeerId.value >> 32));
field2 = qint32(uint32(_inMessagePeerId.value & 0xFFFFFFFFULL));
}
Assert(typeWithFlags != kNonStorageLocationToken);
stream stream
<< quint16(_dcId) << quint16(_dcId)
<< quint8(kSerializeTypeShift | quint8(_type)) << typeWithFlags
<< quint8(_sizeLetter) << quint8(_sizeLetter)
<< qint32(_localId) << field1
<< quint64(_id) << quint64(_id)
<< quint64(_accessHash) << quint64(_accessHash)
<< quint64(_volumeId) << quint64(_volumeId)
<< qint32(_inMessagePeerId) << field2
<< qint32(_inMessageId) << qint32(_inMessageId)
<< _fileReference; << _fileReference;
} }
@ -297,46 +315,73 @@ std::optional<StorageFileLocation> StorageFileLocation::FromSerialized(
} }
quint16 dcId = 0; quint16 dcId = 0;
quint8 type = 0; quint8 typeWithFlags = 0;
quint8 sizeLetter = 0; quint8 sizeLetter = 0;
qint32 localId = 0; qint32 field1 = 0;
quint64 id = 0; quint64 id = 0;
quint64 accessHash = 0; quint64 accessHash = 0;
quint64 volumeId = 0; quint64 volumeId = 0;
qint32 inMessagePeerId = 0; qint32 field2 = 0;
qint32 inMessageId = 0; qint32 inMessageId = 0;
QByteArray fileReference; QByteArray fileReference;
auto stream = QDataStream(serialized); auto stream = QDataStream(serialized);
stream.setVersion(QDataStream::Qt_5_1); stream.setVersion(QDataStream::Qt_5_1);
stream stream
>> dcId >> dcId
>> type; >> typeWithFlags;
if (type == kNonStorageLocationToken) { if (typeWithFlags == kNonStorageLocationToken) {
return std::nullopt; return std::nullopt;
} }
stream stream
>> sizeLetter >> sizeLetter
>> localId >> field1
>> id >> id
>> accessHash >> accessHash
>> volumeId; >> volumeId;
if (type & kSerializeTypeShift) { const auto modern = ((typeWithFlags & kModernLocationFlag) != 0);
type &= ~kSerializeTypeShift; const auto inMessageFields
stream >> inMessagePeerId >> inMessageId; = ((typeWithFlags & kInMessageFieldsFlag) != 0);
if (modern) {
stream >> field2 >> inMessageId;
typeWithFlags &= ~kModernLocationFlag;
if (inMessageFields) {
typeWithFlags &= ~kInMessageFieldsFlag;
}
} else if (typeWithFlags & kLegacyInMessagePeerIdFlag) {
typeWithFlags &= ~kLegacyInMessagePeerIdFlag;
stream >> field2 >> inMessageId;
} }
stream >> fileReference; stream >> fileReference;
auto result = StorageFileLocation(); auto result = StorageFileLocation();
result._dcId = dcId; result._dcId = dcId;
result._type = Type(type); result._type = Type(typeWithFlags);
result._sizeLetter = sizeLetter; result._sizeLetter = sizeLetter;
result._localId = localId;
result._id = id;
result._accessHash = accessHash; result._accessHash = accessHash;
result._volumeId = volumeId; result._volumeId = volumeId;
result._inMessagePeerId = inMessagePeerId;
result._inMessageId = inMessageId; result._inMessageId = inMessageId;
result._fileReference = fileReference; result._fileReference = fileReference;
if (modern) {
result._id = id;
if (inMessageFields) {
result._localId = 0;
result._inMessagePeerId = PeerId(
(uint64(uint32(field1)) << 32) | uint64(uint32(field2)));
} else {
result._localId = field1;
result._inMessagePeerId = 0;
}
} else {
result._id = (result._type == Type::PeerPhoto)
? DeserializePeerId(id).value
: id;
result._localId = field1;
result._inMessagePeerId = (field2 > 0)
? peerFromUser(UserId(field2))
: peerFromChannel(ChannelId(-field2));
}
return (stream.status() == QDataStream::Ok && result.valid()) return (stream.status() == QDataStream::Ok && result.valid())
? std::make_optional(result) ? std::make_optional(result)
: std::nullopt; : std::nullopt;

View file

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
#include "data/data_peer_id.h"
class FileLoader; class FileLoader;
namespace Storage { namespace Storage {
@ -65,7 +67,7 @@ public:
StorageFileLocation() = default; StorageFileLocation() = default;
StorageFileLocation( StorageFileLocation(
int32 dcId, int32 dcId,
int32 self, UserId self,
const MTPInputFileLocation &tl); const MTPInputFileLocation &tl);
[[nodiscard]] StorageFileLocation convertToModern( [[nodiscard]] StorageFileLocation convertToModern(
@ -75,7 +77,7 @@ public:
[[nodiscard]] int32 dcId() const; [[nodiscard]] int32 dcId() const;
[[nodiscard]] uint64 objectId() const; [[nodiscard]] uint64 objectId() const;
[[nodiscard]] MTPInputFileLocation tl(int32 self) const; [[nodiscard]] MTPInputFileLocation tl(UserId self) const;
[[nodiscard]] QByteArray serialize() const; [[nodiscard]] QByteArray serialize() const;
[[nodiscard]] int serializeSize() const; [[nodiscard]] int serializeSize() const;
@ -112,7 +114,7 @@ private:
uint64 _id = 0; uint64 _id = 0;
uint64 _accessHash = 0; uint64 _accessHash = 0;
uint64 _volumeId = 0; uint64 _volumeId = 0;
uint32 _inMessagePeerId = 0; // > 0 'userId', < 0 '-channelId'. PeerId _inMessagePeerId = 0;
uint32 _inMessageId = 0; uint32 _inMessageId = 0;
QByteArray _fileReference; QByteArray _fileReference;

View file

@ -506,7 +506,7 @@ bool UserpicButton::createStreamingObjects(not_null<PhotoData*> photo) {
using namespace Media::Streaming; using namespace Media::Streaming;
const auto origin = _peer->isUser() const auto origin = _peer->isUser()
? Data::FileOriginUserPhoto(_peer->asUser()->bareId(), photo->id) ? Data::FileOriginUserPhoto(peerToUser(_peer->id), photo->id)
: Data::FileOrigin(Data::FileOriginPeerPhoto(_peer->id)); : Data::FileOrigin(Data::FileOriginPeerPhoto(_peer->id));
_streamed = std::make_unique<Instance>( _streamed = std::make_unique<Instance>(
photo->owner().streaming().sharedDocument(photo, origin), photo->owner().streaming().sharedDocument(photo, origin),

View file

@ -160,7 +160,7 @@ void SessionNavigation::resolveChannelById(
_resolveRequestId = _session->api().request(MTPchannels_GetChannels( _resolveRequestId = _session->api().request(MTPchannels_GetChannels(
MTP_vector<MTPInputChannel>( MTP_vector<MTPInputChannel>(
1, 1,
MTP_inputChannel(MTP_int(channelId), MTP_long(0))) MTP_inputChannel(MTP_int(channelId.bare), MTP_long(0))) // #TODO ids
)).done([=](const MTPmessages_Chats &result) { )).done([=](const MTPmessages_Chats &result) {
result.match([&](const auto &data) { result.match([&](const auto &data) {
const auto peer = _session->data().processChats(data.vchats()); const auto peer = _session->data().processChats(data.vchats());

@ -1 +1 @@
Subproject commit a51db55ef278b949e184a241bed03b04b0acba77 Subproject commit 51b4074cc9fba089d01f6f27835f15b05bec83fb