Use data_peer_id in export.

This commit is contained in:
John Preston 2021-04-09 20:47:28 +04:00
parent a100048cce
commit 4625e7613b
7 changed files with 202 additions and 175 deletions

View file

@ -49,26 +49,22 @@ QString PreparePhotoFileName(int index, TimeId date) {
} // namespace } // namespace
PeerId UserPeerId(int32 userId) { int PeerColorIndex(BareId bareId) {
return kUserPeerIdShift | uint32(userId); const auto index = bareId % 7;
}
PeerId ChatPeerId(int32 chatId) {
return kChatPeerIdShift | uint32(chatId);
}
int32 BarePeerId(PeerId peerId) {
return int32(peerId & 0xFFFFFFFFULL);
}
int PeerColorIndex(int32 bareId) {
const auto index = std::abs(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 StringBarePeerId(const Utf8String &data) { BareId PeerToBareId(PeerId peerId) {
auto result = 0xFF; return (peerId.value & PeerId::kChatTypeMask);
}
int PeerColorIndex(PeerId peerId) {
return PeerColorIndex(PeerToBareId(peerId));
}
BareId StringBarePeerId(const Utf8String &data) {
auto result = BareId(0xFF);
for (const auto ch : data) { for (const auto ch : data) {
result *= 239; result *= 239;
result += ch; result += ch;
@ -98,22 +94,8 @@ int DomainApplicationId(const Utf8String &data) {
return 0x1000 + StringBarePeerId(data); return 0x1000 + StringBarePeerId(data);
} }
bool IsChatPeerId(PeerId peerId) {
return (peerId & kChatPeerIdShift) == kChatPeerIdShift;
}
bool IsUserPeerId(PeerId peerId) {
return (peerId & kUserPeerIdShift) == kUserPeerIdShift;
}
PeerId ParsePeerId(const MTPPeer &data) { PeerId ParsePeerId(const MTPPeer &data) {
return data.match([](const MTPDpeerUser &data) { return peerFromMTP(data);
return UserPeerId(data.vuser_id().v);
}, [](const MTPDpeerChat &data) {
return ChatPeerId(data.vchat_id().v);
}, [](const MTPDpeerChannel &data) {
return ChatPeerId(data.vchannel_id().v);
});
} }
Utf8String ParseString(const MTPstring &data) { Utf8String ParseString(const MTPstring &data) {
@ -516,7 +498,7 @@ Venue ParseVenue(const MTPDmessageMediaVenue &data) {
return result; return result;
} }
Game ParseGame(const MTPGame &data, int32 botId) { Game ParseGame(const MTPGame &data, UserId botId) {
return data.match([&](const MTPDgame &data) { return data.match([&](const MTPDgame &data) {
auto result = Game(); auto result = Game();
result.id = data.vid().v; result.id = data.vid().v;
@ -687,16 +669,20 @@ ContactInfo ParseContactInfo(const MTPUser &data) {
int ContactColorIndex(const ContactInfo &data) { int ContactColorIndex(const ContactInfo &data) {
if (data.userId != 0) { if (data.userId != 0) {
return PeerColorIndex(data.userId); return PeerColorIndex(data.userId.bare);
} }
return PeerColorIndex(StringBarePeerId(data.phoneNumber)); return PeerColorIndex(StringBarePeerId(data.phoneNumber));
} }
PeerId User::id() const {
return UserId(bareId);
}
User ParseUser(const MTPUser &data) { User ParseUser(const MTPUser &data) {
auto result = User(); auto result = User();
result.info = ParseContactInfo(data); result.info = ParseContactInfo(data);
data.match([&](const MTPDuser &data) { data.match([&](const MTPDuser &data) {
result.id = data.vid().v; result.bareId = data.vid().v;
if (const auto username = data.vusername()) { if (const auto username = data.vusername()) {
result.username = ParseString(*username); result.username = ParseString(*username);
} }
@ -715,8 +701,8 @@ User ParseUser(const MTPUser &data) {
return result; return result;
} }
std::map<int32, User> ParseUsersList(const MTPVector<MTPUser> &data) { std::map<UserId, User> ParseUsersList(const MTPVector<MTPUser> &data) {
auto result = std::map<int32, User>(); auto result = std::map<UserId, User>();
for (const auto &user : data.v) { for (const auto &user : data.v) {
auto parsed = ParseUser(user); auto parsed = ParseUser(user);
result.emplace(parsed.info.userId, std::move(parsed)); result.emplace(parsed.info.userId, std::move(parsed));
@ -724,12 +710,18 @@ std::map<int32, User> ParseUsersList(const MTPVector<MTPUser> &data) {
return result; return result;
} }
PeerId Chat::id() const {
return (isBroadcast || isSupergroup)
? PeerId(ChannelId(bareId))
: ChatId(bareId);
}
Chat ParseChat(const MTPChat &data) { Chat ParseChat(const MTPChat &data) {
auto result = Chat(); auto result = Chat();
data.match([&](const MTPDchat &data) { data.match([&](const MTPDchat &data) {
result.id = data.vid().v; result.bareId = data.vid().v;
result.title = ParseString(data.vtitle()); result.title = ParseString(data.vtitle());
result.input = MTP_inputPeerChat(MTP_int(result.id)); result.input = MTP_inputPeerChat(MTP_int(result.bareId)); // #TODO ids
if (const auto migratedTo = data.vmigrated_to()) { if (const auto migratedTo = data.vmigrated_to()) {
result.migratedToChannelId = migratedTo->match( result.migratedToChannelId = migratedTo->match(
[](const MTPDinputChannel &data) { [](const MTPDinputChannel &data) {
@ -737,14 +729,14 @@ Chat ParseChat(const MTPChat &data) {
}, [](auto&&) { return 0; }); }, [](auto&&) { return 0; });
} }
}, [&](const MTPDchatEmpty &data) { }, [&](const MTPDchatEmpty &data) {
result.id = data.vid().v; result.bareId = data.vid().v;
result.input = MTP_inputPeerChat(MTP_int(result.id)); result.input = MTP_inputPeerChat(MTP_int(result.bareId)); // #TODO ids
}, [&](const MTPDchatForbidden &data) { }, [&](const MTPDchatForbidden &data) {
result.id = data.vid().v; result.bareId = data.vid().v;
result.title = ParseString(data.vtitle()); result.title = ParseString(data.vtitle());
result.input = MTP_inputPeerChat(MTP_int(result.id)); result.input = MTP_inputPeerChat(MTP_int(result.bareId)); // #TODO ids
}, [&](const MTPDchannel &data) { }, [&](const MTPDchannel &data) {
result.id = data.vid().v; result.bareId = data.vid().v;
result.isBroadcast = data.is_broadcast(); result.isBroadcast = data.is_broadcast();
result.isSupergroup = data.is_megagroup(); result.isSupergroup = data.is_megagroup();
result.title = ParseString(data.vtitle()); result.title = ParseString(data.vtitle());
@ -752,25 +744,25 @@ Chat ParseChat(const MTPChat &data) {
result.username = ParseString(*username); result.username = ParseString(*username);
} }
result.input = MTP_inputPeerChannel( result.input = MTP_inputPeerChannel(
MTP_int(result.id), MTP_int(result.bareId), // #TODO ids
MTP_long(data.vaccess_hash().value_or_empty())); MTP_long(data.vaccess_hash().value_or_empty()));
}, [&](const MTPDchannelForbidden &data) { }, [&](const MTPDchannelForbidden &data) {
result.id = data.vid().v; result.bareId = data.vid().v;
result.isBroadcast = data.is_broadcast(); result.isBroadcast = data.is_broadcast();
result.isSupergroup = data.is_megagroup(); result.isSupergroup = data.is_megagroup();
result.title = ParseString(data.vtitle()); result.title = ParseString(data.vtitle());
result.input = MTP_inputPeerChannel( result.input = MTP_inputPeerChannel( // #TODO ids
MTP_int(result.id), MTP_int(result.bareId),
data.vaccess_hash()); data.vaccess_hash());
}); });
return result; return result;
} }
std::map<int32, Chat> ParseChatsList(const MTPVector<MTPChat> &data) { std::map<PeerId, Chat> ParseChatsList(const MTPVector<MTPChat> &data) {
auto result = std::map<int32, Chat>(); auto result = std::map<PeerId, Chat>();
for (const auto &chat : data.v) { for (const auto &chat : data.v) {
auto parsed = ParseChat(chat); auto parsed = ParseChat(chat);
result.emplace(parsed.id, std::move(parsed)); result.emplace(parsed.id(), std::move(parsed));
} }
return result; return result;
} }
@ -799,9 +791,9 @@ const Chat *Peer::chat() const {
PeerId Peer::id() const { PeerId Peer::id() const {
if (const auto user = this->user()) { if (const auto user = this->user()) {
return UserPeerId(user->info.userId); return peerFromUser(user->info.userId);
} else if (const auto chat = this->chat()) { } else if (const auto chat = this->chat()) {
return ChatPeerId(chat->id); return chat->id();
} }
Unexpected("Variant in Peer::id."); Unexpected("Variant in Peer::id.");
} }
@ -835,29 +827,31 @@ std::map<PeerId, Peer> ParsePeersLists(
for (const auto &user : users.v) { for (const auto &user : users.v) {
auto parsed = ParseUser(user); auto parsed = ParseUser(user);
result.emplace( result.emplace(
UserPeerId(parsed.info.userId), PeerId(parsed.info.userId),
Peer{ std::move(parsed) }); Peer{ std::move(parsed) });
} }
for (const auto &chat : chats.v) { for (const auto &chat : chats.v) {
auto parsed = ParseChat(chat); auto parsed = ParseChat(chat);
result.emplace(ChatPeerId(parsed.id), Peer{ std::move(parsed) }); result.emplace(parsed.id(), Peer{ std::move(parsed) });
} }
return result; return result;
} }
User EmptyUser(int32 userId) { User EmptyUser(UserId userId) {
return ParseUser(MTP_userEmpty(MTP_int(userId))); return ParseUser(MTP_userEmpty(MTP_int(userId.bare))); // #TODO ids
} }
Chat EmptyChat(int32 chatId) { Chat EmptyChat(ChatId chatId) {
return ParseChat(MTP_chatEmpty(MTP_int(chatId))); return ParseChat(MTP_chatEmpty(MTP_int(chatId.bare))); // #TODO ids
} }
Peer EmptyPeer(PeerId peerId) { Peer EmptyPeer(PeerId peerId) {
if (IsUserPeerId(peerId)) { if (peerIsUser(peerId)) {
return Peer{ EmptyUser(BarePeerId(peerId)) }; return Peer{ EmptyUser(peerToUser(peerId)) };
} else if (IsChatPeerId(peerId)) { } else if (peerIsChat(peerId)) {
return Peer{ EmptyChat(BarePeerId(peerId)) }; return Peer{ EmptyChat(peerToChat(peerId)) };
} else if (peerIsChannel(peerId)) {
return Peer{ EmptyChat(peerToChat(peerId)) };
} }
Unexpected("PeerId in EmptyPeer."); Unexpected("PeerId in EmptyPeer.");
} }
@ -1177,9 +1171,6 @@ Message ParseMessage(
result.selfId = context.selfPeerId; result.selfId = context.selfPeerId;
result.peerId = ParsePeerId(data.vpeer_id()); result.peerId = ParsePeerId(data.vpeer_id());
const auto fromId = data.vfrom_id(); const auto fromId = data.vfrom_id();
if (IsChatPeerId(result.peerId)) {
result.chatId = BarePeerId(result.peerId);
}
if (fromId) { if (fromId) {
result.fromId = ParsePeerId(*fromId); result.fromId = ParsePeerId(*fromId);
} else { } else {
@ -1247,11 +1238,11 @@ Message ParseMessage(
result.viaBotId = viaBotId->v; result.viaBotId = viaBotId->v;
} }
if (const auto media = data.vmedia()) { if (const auto media = data.vmedia()) {
context.botId = (result.viaBotId context.botId = result.viaBotId
? result.viaBotId ? result.viaBotId
: IsUserPeerId(result.forwardedFromId) : peerIsUser(result.forwardedFromId)
? BarePeerId(result.forwardedFromId) ? peerToUser(result.forwardedFromId)
: result.fromId); : peerToUser(result.fromId);
result.media = ParseMedia( result.media = ParseMedia(
context, context,
*media, *media,
@ -1278,16 +1269,17 @@ Message ParseMessage(
return result; return result;
} }
std::map<uint64, Message> ParseMessagesList( std::map<MessageId, Message> ParseMessagesList(
PeerId selfId, PeerId selfId,
const MTPVector<MTPMessage> &data, const MTPVector<MTPMessage> &data,
const QString &mediaFolder) { const QString &mediaFolder) {
auto context = ParseMediaContext{ .selfPeerId = selfId }; auto context = ParseMediaContext{ .selfPeerId = selfId };
auto result = std::map<uint64, Message>(); auto result = std::map<MessageId, Message>();
for (const auto &message : data.v) { for (const auto &message : data.v) {
auto parsed = ParseMessage(context, message, mediaFolder); auto parsed = ParseMessage(context, message, mediaFolder);
const auto shift = uint64(uint32(parsed.chatId)) << 32; result.emplace(
result.emplace(shift | uint32(parsed.id), std::move(parsed)); MessageId{ peerToChannel(parsed.peerId), parsed.id },
std::move(parsed));
} }
return result; return result;
} }
@ -1439,7 +1431,7 @@ SessionsList ParseSessionsList(const MTPaccount_Authorizations &data) {
WebSession ParseWebSession( WebSession ParseWebSession(
const MTPWebAuthorization &data, const MTPWebAuthorization &data,
const std::map<int32, User> &users) { const std::map<UserId, User> &users) {
return data.match([&](const MTPDwebAuthorization &data) { return data.match([&](const MTPDwebAuthorization &data) {
auto result = WebSession(); auto result = WebSession();
const auto i = users.find(data.vbot_id().v); const auto i = users.find(data.vbot_id().v);
@ -1555,11 +1547,10 @@ DialogsInfo ParseDialogsInfo(const MTPmessages_Dialogs &data) {
: 0; : 0;
} }
info.topMessageId = fields.vtop_message().v; info.topMessageId = fields.vtop_message().v;
const auto shift = IsChatPeerId(info.peerId) const auto messageIt = messages.find(MessageId{
? (uint64(uint32(BarePeerId(info.peerId))) << 32) peerToChannel(info.peerId),
: 0; info.topMessageId,
const auto messageIt = messages.find( });
shift | uint32(info.topMessageId));
if (messageIt != end(messages)) { if (messageIt != end(messages)) {
const auto &message = messageIt->second; const auto &message = messageIt->second;
info.topMessageDate = message.date; info.topMessageDate = message.date;
@ -1575,7 +1566,7 @@ DialogInfo DialogInfoFromUser(const User &data) {
result.input = (Peer{ data }).input(); result.input = (Peer{ data }).input();
result.name = data.info.firstName; result.name = data.info.firstName;
result.lastName = data.info.lastName; result.lastName = data.info.lastName;
result.peerId = UserPeerId(data.info.userId); result.peerId = data.id();
result.topMessageDate = 0; result.topMessageDate = 0;
result.topMessageId = 0; result.topMessageId = 0;
result.type = DialogTypeFromUser(data); result.type = DialogTypeFromUser(data);
@ -1587,7 +1578,7 @@ DialogInfo DialogInfoFromChat(const Chat &data) {
auto result = DialogInfo(); auto result = DialogInfo();
result.input = data.input; result.input = data.input;
result.name = data.title; result.name = data.title;
result.peerId = ChatPeerId(data.id); result.peerId = data.id();
result.topMessageDate = 0; result.topMessageDate = 0;
result.topMessageId = 0; result.topMessageId = 0;
result.type = DialogTypeFromChat(data); result.type = DialogTypeFromChat(data);
@ -1613,17 +1604,17 @@ DialogsInfo ParseDialogsInfo(
const MTPVector<MTPUser> &data) { const MTPVector<MTPUser> &data) {
const auto singleId = singlePeer.match( const auto singleId = singlePeer.match(
[](const MTPDinputPeerUser &data) { [](const MTPDinputPeerUser &data) {
return data.vuser_id().v; return UserId(data.vuser_id());
}, [](const MTPDinputPeerSelf &data) { }, [](const MTPDinputPeerSelf &data) {
return 0; return UserId();
}, [](const auto &data) -> int { }, [](const auto &data) -> UserId {
Unexpected("Single peer type in ParseDialogsInfo(users)."); Unexpected("Single peer type in ParseDialogsInfo(users).");
}); });
auto result = DialogsInfo(); auto result = DialogsInfo();
result.chats.reserve(data.v.size()); result.chats.reserve(data.v.size());
for (const auto &single : data.v) { for (const auto &single : data.v) {
const auto userId = single.match([&](const auto &data) { const auto userId = single.match([&](const auto &data) {
return data.vid().v; return peerFromUser(data.vid());
}); });
if (userId != singleId if (userId != singleId
&& (singleId != 0 && (singleId != 0
@ -1642,20 +1633,24 @@ DialogsInfo ParseDialogsInfo(
const MTPmessages_Chats &data) { const MTPmessages_Chats &data) {
const auto singleId = singlePeer.match( const auto singleId = singlePeer.match(
[](const MTPDinputPeerChat &data) { [](const MTPDinputPeerChat &data) {
return data.vchat_id().v; return peerFromChat(data.vchat_id());
}, [](const MTPDinputPeerChannel &data) { }, [](const MTPDinputPeerChannel &data) {
return data.vchannel_id().v; return peerFromChannel(data.vchannel_id());
}, [](const auto &data) -> int { }, [](const auto &data) -> PeerId {
Unexpected("Single peer type in ParseDialogsInfo(chats)."); Unexpected("Single peer type in ParseDialogsInfo(chats).");
}); });
auto result = DialogsInfo(); auto result = DialogsInfo();
data.match([&](const auto &data) { //MTPDmessages_chats &data) { data.match([&](const auto &data) { //MTPDmessages_chats &data) {
result.chats.reserve(data.vchats().v.size()); result.chats.reserve(data.vchats().v.size());
for (const auto &single : data.vchats().v) { for (const auto &single : data.vchats().v) {
const auto chatId = single.match([&](const auto &data) { const auto peerId = single.match([](const MTPDchannel &data) {
return data.vid().v; return peerFromChannel(data.vid());
}, [](const MTPDchannelForbidden &data) {
return peerFromChannel(data.vid());
}, [](const auto &data) {
return peerFromChat(data.vid());
}); });
if (chatId != singleId) { if (peerId != singleId) {
continue; continue;
} }
const auto chat = ParseChat(single); const auto chat = ParseChat(single);
@ -1677,8 +1672,8 @@ bool AddMigrateFromSlice(
const auto good = to.migratedFromInput.match([]( const auto good = to.migratedFromInput.match([](
const MTPDinputPeerEmpty &) { const MTPDinputPeerEmpty &) {
return true; return true;
}, [&](const MTPDinputPeerChat & data) { }, [&](const MTPDinputPeerChat &data) {
return (ChatPeerId(data.vchat_id().v) == from.peerId); return (peerFromChat(data.vchat_id()) == from.peerId);
}, [](auto&&) { return false; }); }, [](auto&&) { return false; });
if (!good) { if (!good) {
return false; return false;

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "scheme.h" #include "scheme.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/variant.h" #include "base/variant.h"
#include "data/data_peer_id.h"
#include <QtCore/QSize> #include <QtCore/QSize>
#include <QtCore/QString> #include <QtCore/QString>
@ -22,14 +23,10 @@ struct Settings;
namespace Data { namespace Data {
using Utf8String = QByteArray; using Utf8String = QByteArray;
using PeerId = uint64;
PeerId UserPeerId(int32 userId); int PeerColorIndex(BareId bareId);
PeerId ChatPeerId(int32 chatId); BareId PeerToBareId(PeerId peerId);
int32 BarePeerId(PeerId peerId); int PeerColorIndex(PeerId peerId);
bool IsChatPeerId(PeerId peerId);
bool IsUserPeerId(PeerId peerId);
int PeerColorIndex(int32 bareId);
int ApplicationColorIndex(int applicationId); int ApplicationColorIndex(int applicationId);
int DomainApplicationId(const Utf8String &data); int DomainApplicationId(const Utf8String &data);
@ -102,7 +99,7 @@ QString WriteImageThumb(
const QString &postfix = "_thumb"); const QString &postfix = "_thumb");
struct ContactInfo { struct ContactInfo {
int32 userId = 0; UserId userId = 0;
Utf8String firstName; Utf8String firstName;
Utf8String lastName; Utf8String lastName;
Utf8String phoneNumber; Utf8String phoneNumber;
@ -169,7 +166,7 @@ struct Game {
Utf8String title; Utf8String title;
Utf8String description; Utf8String description;
int32 botId = 0; UserId botId = 0;
}; };
struct Invoice { struct Invoice {
@ -204,9 +201,11 @@ UserpicsSlice ParseUserpicsSlice(
int baseIndex); int baseIndex);
struct User { struct User {
PeerId id() const;
BareId bareId = 0;
ContactInfo info; ContactInfo info;
Utf8String username; Utf8String username;
int32 id;
bool isBot = false; bool isBot = false;
bool isSelf = false; bool isSelf = false;
bool isReplies = false; bool isReplies = false;
@ -217,11 +216,13 @@ struct User {
}; };
User ParseUser(const MTPUser &data); User ParseUser(const MTPUser &data);
std::map<int32, User> ParseUsersList(const MTPVector<MTPUser> &data); std::map<UserId, User> ParseUsersList(const MTPVector<MTPUser> &data);
struct Chat { struct Chat {
int32 id = 0; PeerId id() const;
int32 migratedToChannelId = 0;
BareId bareId = 0;
ChannelId migratedToChannelId = 0;
Utf8String title; Utf8String title;
Utf8String username; Utf8String username;
bool isBroadcast = false; bool isBroadcast = false;
@ -231,7 +232,7 @@ struct Chat {
}; };
Chat ParseChat(const MTPChat &data); Chat ParseChat(const MTPChat &data);
std::map<int32, Chat> ParseChatsList(const MTPVector<MTPChat> &data); std::map<PeerId, Chat> ParseChatsList(const MTPVector<MTPChat> &data);
struct Peer { struct Peer {
PeerId id() const; PeerId id() const;
@ -336,7 +337,7 @@ struct ParseMediaContext {
int videos = 0; int videos = 0;
int files = 0; int files = 0;
int contacts = 0; int contacts = 0;
int32 botId = 0; UserId botId = 0;
}; };
Media ParseMedia( Media ParseMedia(
@ -347,7 +348,7 @@ Media ParseMedia(
struct ActionChatCreate { struct ActionChatCreate {
Utf8String title; Utf8String title;
std::vector<int32> userIds; std::vector<UserId> userIds;
}; };
struct ActionChatEditTitle { struct ActionChatEditTitle {
@ -362,15 +363,15 @@ struct ActionChatDeletePhoto {
}; };
struct ActionChatAddUser { struct ActionChatAddUser {
std::vector<int32> userIds; std::vector<UserId> userIds;
}; };
struct ActionChatDeleteUser { struct ActionChatDeleteUser {
int32 userId = 0; UserId userId = 0;
}; };
struct ActionChatJoinedByLink { struct ActionChatJoinedByLink {
int32 inviterId = 0; UserId inviterId = 0;
}; };
struct ActionChannelCreate { struct ActionChannelCreate {
@ -378,12 +379,12 @@ struct ActionChannelCreate {
}; };
struct ActionChatMigrateTo { struct ActionChatMigrateTo {
int32 channelId = 0; ChannelId channelId = 0;
}; };
struct ActionChannelMigrateFrom { struct ActionChannelMigrateFrom {
Utf8String title; Utf8String title;
int32 chatId = 0; ChatId chatId = 0;
}; };
struct ActionPinMessage { struct ActionPinMessage {
@ -463,7 +464,7 @@ struct ActionGroupCall {
}; };
struct ActionInviteToGroupCall { struct ActionInviteToGroupCall {
std::vector<int32> userIds; std::vector<UserId> userIds;
}; };
struct ActionSetMessagesTTL { struct ActionSetMessagesTTL {
@ -537,9 +538,33 @@ struct TextPart {
Utf8String additional; Utf8String additional;
}; };
struct MessageId {
ChannelId channelId;
int32 msgId = 0;
};
inline bool operator==(MessageId a, MessageId b) {
return (a.channelId == b.channelId) && (a.msgId == b.msgId);
}
inline bool operator!=(MessageId a, MessageId b) {
return !(a == b);
}
inline bool operator<(MessageId a, MessageId b) {
return (a.channelId < b.channelId)
|| (a.channelId == b.channelId && a.msgId < b.msgId);
}
inline bool operator>(MessageId a, MessageId b) {
return (b < a);
}
inline bool operator<=(MessageId a, MessageId b) {
return !(b < a);
}
inline bool operator>=(MessageId a, MessageId b) {
return !(a < b);
}
struct Message { struct Message {
int32 id = 0; int32 id = 0;
int32 chatId = 0;
TimeId date = 0; TimeId date = 0;
TimeId edited = 0; TimeId edited = 0;
PeerId fromId = 0; PeerId fromId = 0;
@ -552,7 +577,7 @@ struct Message {
bool showForwardedAsOriginal = false; bool showForwardedAsOriginal = false;
PeerId savedFromChatId = 0; PeerId savedFromChatId = 0;
Utf8String signature; Utf8String signature;
int32 viaBotId = 0; UserId viaBotId = 0;
int32 replyToMsgId = 0; int32 replyToMsgId = 0;
PeerId replyToPeerId = 0; PeerId replyToPeerId = 0;
std::vector<TextPart> text; std::vector<TextPart> text;
@ -576,7 +601,7 @@ Message ParseMessage(
ParseMediaContext &context, ParseMediaContext &context,
const MTPMessage &data, const MTPMessage &data,
const QString &mediaFolder); const QString &mediaFolder);
std::map<uint64, Message> ParseMessagesList( std::map<MessageId, Message> ParseMessagesList(
PeerId selfId, PeerId selfId,
const MTPVector<MTPMessage> &data, const MTPVector<MTPMessage> &data,
const QString &mediaFolder); const QString &mediaFolder);
@ -604,7 +629,7 @@ struct DialogInfo {
PeerId peerId = 0; PeerId peerId = 0;
MTPInputPeer migratedFromInput = MTP_inputPeerEmpty(); MTPInputPeer migratedFromInput = MTP_inputPeerEmpty();
int32 migratedToChannelId = 0; ChannelId migratedToChannelId = 0;
// User messages splits which contained that dialog. // User messages splits which contained that dialog.
std::vector<int> splits; std::vector<int> splits;

View file

@ -184,7 +184,7 @@ struct ApiWrap::ChatsProcess {
Data::DialogsInfo info; Data::DialogsInfo info;
int processedCount = 0; int processedCount = 0;
std::map<Data::PeerId, int> indexByPeer; std::map<PeerId, int> indexByPeer;
}; };
struct ApiWrap::LeftChannelsProcess : ChatsProcess { struct ApiWrap::LeftChannelsProcess : ChatsProcess {
@ -651,7 +651,7 @@ void ApiWrap::startMainSession(FnMut<void()> done) {
for (const auto &user : result.v) { for (const auto &user : result.v) {
user.match([&](const MTPDuser &data) { user.match([&](const MTPDuser &data) {
if (data.is_self()) { if (data.is_self()) {
_selfId = data.vid().v; _selfId.emplace(data.vid());
} }
}, [&](const MTPDuserEmpty&) { }, [&](const MTPDuserEmpty&) {
}); });
@ -950,7 +950,7 @@ void ApiWrap::requestMessages(
Expects(_selfId.has_value()); Expects(_selfId.has_value());
_chatProcess = std::make_unique<ChatProcess>(); _chatProcess = std::make_unique<ChatProcess>();
_chatProcess->context.selfPeerId = Data::UserPeerId(*_selfId); _chatProcess->context.selfPeerId = peerFromUser(*_selfId);
_chatProcess->info = info; _chatProcess->info = info;
_chatProcess->start = std::move(start); _chatProcess->start = std::move(start);
_chatProcess->fileProgress = std::move(progress); _chatProcess->fileProgress = std::move(progress);
@ -1342,7 +1342,7 @@ void ApiWrap::appendChatsSlice(
for (auto &info : filtered) { for (auto &info : filtered) {
const auto nextIndex = to.size(); const auto nextIndex = to.size();
if (info.migratedToChannelId) { if (info.migratedToChannelId) {
const auto toPeerId = Data::ChatPeerId(info.migratedToChannelId); const auto toPeerId = PeerId(info.migratedToChannelId);
const auto i = process.indexByPeer.find(toPeerId); const auto i = process.indexByPeer.find(toPeerId);
if (i != process.indexByPeer.end() if (i != process.indexByPeer.end()
&& Data::AddMigrateFromSlice( && Data::AddMigrateFromSlice(
@ -1915,7 +1915,7 @@ void ApiWrap::filePartExtractReference(
Expects(_selfId.has_value()); Expects(_selfId.has_value());
auto context = Data::ParseMediaContext(); auto context = Data::ParseMediaContext();
context.selfPeerId = Data::UserPeerId(*_selfId); context.selfPeerId = peerFromUser(*_selfId);
const auto messages = Data::ParseMessagesSlice( const auto messages = Data::ParseMessagesSlice(
context, context,
data.vmessages(), data.vmessages(),

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "mtproto/mtproto_concurrent_sender.h" #include "mtproto/mtproto_concurrent_sender.h"
#include "data/data_peer_id.h"
namespace Export { namespace Export {
namespace Data { namespace Data {
@ -211,7 +212,7 @@ private:
MTP::ConcurrentSender _mtp; MTP::ConcurrentSender _mtp;
std::optional<uint64> _takeoutId; std::optional<uint64> _takeoutId;
std::optional<int32> _selfId; std::optional<UserId> _selfId;
Output::Stats *_stats = nullptr; Output::Stats *_stats = nullptr;
std::unique_ptr<Settings> _settings; std::unique_ptr<Settings> _settings;

View file

@ -131,7 +131,7 @@ Stats AbstractWriter::produceTestExample(
topUser.rating = 0.5; topUser.rating = 0.5;
auto topChat = Data::TopPeer(); auto topChat = Data::TopPeer();
auto chat = Data::Chat(); auto chat = Data::Chat();
chat.id = counter(); chat.bareId = counter();
chat.title = "Group chat"; chat.title = "Group chat";
auto peerChat = Data::Peer{ chat }; auto peerChat = Data::Peer{ chat };
topChat.peer = peerChat; topChat.peer = peerChat;
@ -148,7 +148,7 @@ Stats AbstractWriter::produceTestExample(
topBot.peer = peerBot; topBot.peer = peerBot;
topBot.rating = 0.125; topBot.rating = 0.125;
auto peers = std::map<Data::PeerId, Data::Peer>(); auto peers = std::map<PeerId, Data::Peer>();
peers.emplace(peerUser.id(), peerUser); peers.emplace(peerUser.id(), peerUser);
peers.emplace(peerBot.id(), peerBot); peers.emplace(peerBot.id(), peerBot);
peers.emplace(peerChat.id(), peerChat); peers.emplace(peerChat.id(), peerChat);
@ -197,7 +197,7 @@ Stats AbstractWriter::produceTestExample(
message.edited = date(); message.edited = date();
static auto count = 0; static auto count = 0;
if (++count % 3 == 0) { if (++count % 3 == 0) {
message.forwardedFromId = Data::UserPeerId(user.info.userId); message.forwardedFromId = peerFromUser(user.info.userId);
message.forwardedDate = date(); message.forwardedDate = date();
} else if (count % 3 == 2) { } else if (count % 3 == 2) {
message.forwardedFromName = "Test hidden forward"; message.forwardedFromName = "Test hidden forward";
@ -357,14 +357,14 @@ Stats AbstractWriter::produceTestExample(
sliceChat1.list.push_back([&] { sliceChat1.list.push_back([&] {
auto message = serviceMessage(); auto message = serviceMessage();
auto action = Data::ActionChatMigrateTo(); auto action = Data::ActionChatMigrateTo();
action.channelId = chat.id; action.channelId = ChannelId(chat.bareId);
message.action.content = action; message.action.content = action;
return message; return message;
}()); }());
sliceChat1.list.push_back([&] { sliceChat1.list.push_back([&] {
auto message = serviceMessage(); auto message = serviceMessage();
auto action = Data::ActionChannelMigrateFrom(); auto action = Data::ActionChannelMigrateFrom();
action.chatId = chat.id; action.chatId = ChatId(chat.bareId);
action.title = "Supergroup now"; action.title = "Supergroup now";
message.action.content = action; message.action.content = action;
return message; return message;

View file

@ -340,7 +340,6 @@ struct UserpicData {
class PeersMap { class PeersMap {
public: public:
using PeerId = Data::PeerId;
using Peer = Data::Peer; using Peer = Data::Peer;
using User = Data::User; using User = Data::User;
using Chat = Data::Chat; using Chat = Data::Chat;
@ -348,15 +347,14 @@ public:
PeersMap(const std::map<PeerId, Peer> &data); PeersMap(const std::map<PeerId, Peer> &data);
const Peer &peer(PeerId peerId) const; const Peer &peer(PeerId peerId) const;
const User &user(int32 userId) const; const User &user(UserId userId) const;
const Chat &chat(int32 chatId) const;
QByteArray wrapPeerName(PeerId peerId) const; QByteArray wrapPeerName(PeerId peerId) const;
QByteArray wrapUserName(int32 userId) const; QByteArray wrapUserName(UserId userId) const;
QByteArray wrapUserNames(const std::vector<int32> &data) const; QByteArray wrapUserNames(const std::vector<UserId> &data) const;
private: private:
const std::map<Data::PeerId, Data::Peer> &_data; const std::map<PeerId, Data::Peer> &_data;
}; };
@ -380,22 +378,14 @@ auto PeersMap::peer(PeerId peerId) const -> const Peer & {
return empty; return empty;
} }
auto PeersMap::user(int32 userId) const -> const User & { auto PeersMap::user(UserId userId) const -> const User & {
if (const auto result = peer(Data::UserPeerId(userId)).user()) { if (const auto result = peer(peerFromUser(userId)).user()) {
return *result; return *result;
} }
static auto empty = User(); static auto empty = User();
return empty; return empty;
} }
auto PeersMap::chat(int32 chatId) const -> const Chat & {
if (const auto result = peer(Data::ChatPeerId(chatId)).chat()) {
return *result;
}
static auto empty = Chat();
return empty;
}
QByteArray PeersMap::wrapPeerName(PeerId peerId) const { QByteArray PeersMap::wrapPeerName(PeerId peerId) const {
const auto result = peer(peerId).name(); const auto result = peer(peerId).name();
return result.isEmpty() return result.isEmpty()
@ -403,14 +393,14 @@ QByteArray PeersMap::wrapPeerName(PeerId peerId) const {
: SerializeString(result); : SerializeString(result);
} }
QByteArray PeersMap::wrapUserName(int32 userId) const { QByteArray PeersMap::wrapUserName(UserId userId) const {
const auto result = user(userId).name(); const auto result = user(userId).name();
return result.isEmpty() return result.isEmpty()
? QByteArray("Deleted Account") ? QByteArray("Deleted Account")
: SerializeString(result); : SerializeString(result);
} }
QByteArray PeersMap::wrapUserNames(const std::vector<int32> &data) const { QByteArray PeersMap::wrapUserNames(const std::vector<UserId> &data) const {
auto list = std::vector<QByteArray>(); auto list = std::vector<QByteArray>();
for (const auto userId : data) { for (const auto userId : data) {
list.push_back(wrapUserName(userId)); list.push_back(wrapUserName(userId));
@ -469,12 +459,12 @@ struct HtmlWriter::MessageInfo {
Service, Service,
Default, Default,
}; };
int32 id = 0; int id = 0;
Type type = Type::Service; Type type = Type::Service;
Data::PeerId fromId = 0; PeerId fromId = 0;
int32 viaBotId = 0; UserId viaBotId = 0;
TimeId date = 0; TimeId date = 0;
Data::PeerId forwardedFromId = 0; PeerId forwardedFromId = 0;
QString forwardedFromName; QString forwardedFromName;
bool forwarded = false; bool forwarded = false;
bool showForwardedAsOriginal = false; bool showForwardedAsOriginal = false;
@ -895,8 +885,7 @@ QByteArray HtmlWriter::Wrap::pushServiceMessage(
result.append(popTag()); result.append(popTag());
if (photo) { if (photo) {
auto userpic = UserpicData(); auto userpic = UserpicData();
userpic.colorIndex = Data::PeerColorIndex( userpic.colorIndex = Data::PeerColorIndex(dialog.peerId);
Data::BarePeerId(dialog.peerId));
userpic.firstName = dialog.name; userpic.firstName = dialog.name;
userpic.lastName = dialog.lastName; userpic.lastName = dialog.lastName;
userpic.pixelSize = kServiceMessagePhotoSize; userpic.pixelSize = kServiceMessagePhotoSize;
@ -1136,7 +1125,7 @@ auto HtmlWriter::Wrap::pushMessage(
auto forwardedUserpic = UserpicData(); auto forwardedUserpic = UserpicData();
if (message.forwarded) { if (message.forwarded) {
forwardedUserpic.colorIndex = message.forwardedFromId forwardedUserpic.colorIndex = message.forwardedFromId
? PeerColorIndex(BarePeerId(message.forwardedFromId)) ? PeerColorIndex(message.forwardedFromId)
: PeerColorIndex(message.id); : PeerColorIndex(message.id);
forwardedUserpic.pixelSize = kHistoryUserpicSize; forwardedUserpic.pixelSize = kHistoryUserpicSize;
if (message.forwardedFromId) { if (message.forwardedFromId) {
@ -1151,7 +1140,7 @@ auto HtmlWriter::Wrap::pushMessage(
if (message.showForwardedAsOriginal) { if (message.showForwardedAsOriginal) {
userpic = forwardedUserpic; userpic = forwardedUserpic;
} else { } else {
userpic.colorIndex = PeerColorIndex(BarePeerId(fromPeerId)); userpic.colorIndex = PeerColorIndex(fromPeerId);
userpic.pixelSize = kHistoryUserpicSize; userpic.pixelSize = kHistoryUserpicSize;
FillUserpicNames(userpic, peers.peer(fromPeerId)); FillUserpicNames(userpic, peers.peer(fromPeerId));
} }
@ -1805,7 +1794,7 @@ bool HtmlWriter::Wrap::forwardedNeedsWrap(
} else if (!message.forwardedFromId } else if (!message.forwardedFromId
|| message.forwardedFromId != previous->forwardedFromId) { || message.forwardedFromId != previous->forwardedFromId) {
return true; return true;
} else if (Data::IsChatPeerId(message.forwardedFromId)) { } else if (!peerIsUser(message.forwardedFromId)) {
return true; return true;
} else if (abs(message.forwardedDate - previous->forwardedDate) } else if (abs(message.forwardedDate - previous->forwardedDate)
> kJoinWithinSeconds) { > kJoinWithinSeconds) {
@ -2203,7 +2192,7 @@ Result HtmlWriter::writeFrequentContacts(const Data::ContactsList &data) {
return {}; return {};
}(); }();
auto userpic = UserpicData{ auto userpic = UserpicData{
Data::PeerColorIndex(Data::BarePeerId(top.peer.id())), Data::PeerColorIndex(top.peer.id()),
kEntryUserpicSize kEntryUserpicSize
}; };
userpic.firstName = name; userpic.firstName = name;
@ -2558,7 +2547,7 @@ Result HtmlWriter::writeDialogEnd() {
auto userpic = UserpicData{ auto userpic = UserpicData{
((_dialog.type == Type::Self || _dialog.type == Type::Replies) ((_dialog.type == Type::Self || _dialog.type == Type::Replies)
? kSavedMessagesColorIndex ? kSavedMessagesColorIndex
: Data::PeerColorIndex(Data::BarePeerId(_dialog.peerId))), : Data::PeerColorIndex(_dialog.peerId)),
kEntryUserpicSize kEntryUserpicSize
}; };
userpic.firstName = NameString(_dialog); userpic.firstName = NameString(_dialog);

View file

@ -217,7 +217,7 @@ QByteArray FormatFilePath(const Data::File &file) {
QByteArray SerializeMessage( QByteArray SerializeMessage(
Context &context, Context &context,
const Data::Message &message, const Data::Message &message,
const std::map<Data::PeerId, Data::Peer> &peers, const std::map<PeerId, Data::Peer> &peers,
const QString &internalLinksDomain) { const QString &internalLinksDomain) {
using namespace Data; using namespace Data;
@ -235,20 +235,13 @@ QByteArray SerializeMessage(
static auto empty = Peer{ User() }; static auto empty = Peer{ User() };
return empty; return empty;
}; };
const auto user = [&](int32 userId) -> const User& { const auto user = [&](UserId userId) -> const User& {
if (const auto result = peer(UserPeerId(userId)).user()) { if (const auto result = peer(userId).user()) {
return *result; return *result;
} }
static auto empty = User(); static auto empty = User();
return empty; return empty;
}; };
const auto chat = [&](int32 chatId) -> const Chat& {
if (const auto result = peer(ChatPeerId(chatId)).chat()) {
return *result;
}
static auto empty = Chat();
return empty;
};
auto values = std::vector<std::pair<QByteArray, QByteArray>>{ auto values = std::vector<std::pair<QByteArray, QByteArray>>{
{ "id", NumberToString(message.id) }, { "id", NumberToString(message.id) },
@ -280,6 +273,25 @@ QByteArray SerializeMessage(
const auto push = [&](const QByteArray &key, const auto &value) { const auto push = [&](const QByteArray &key, const auto &value) {
if constexpr (std::is_arithmetic_v<std::decay_t<decltype(value)>>) { if constexpr (std::is_arithmetic_v<std::decay_t<decltype(value)>>) {
pushBare(key, Data::NumberToString(value)); pushBare(key, Data::NumberToString(value));
} else if constexpr (std::is_same_v<
std::decay_t<decltype(value)>,
PeerId>) {
if (const auto chat = peerToChat(value)) {
pushBare(
key,
SerializeString("chat"
+ Data::NumberToString(chat.bare)));
} else if (const auto channel = peerToChannel(value)) {
pushBare(
key,
SerializeString("channel"
+ Data::NumberToString(channel.bare)));
} else {
pushBare(
key,
SerializeString("user"
+ Data::NumberToString(peerToUser(value).bare)));
}
} else { } else {
const auto wrapped = QByteArray(value); const auto wrapped = QByteArray(value);
if (!wrapped.isEmpty()) { if (!wrapped.isEmpty()) {
@ -290,7 +302,7 @@ QByteArray SerializeMessage(
const auto wrapPeerName = [&](PeerId peerId) { const auto wrapPeerName = [&](PeerId peerId) {
return StringAllowNull(peer(peerId).name()); return StringAllowNull(peer(peerId).name());
}; };
const auto wrapUserName = [&](int32 userId) { const auto wrapUserName = [&](UserId userId) {
return StringAllowNull(user(userId).name()); return StringAllowNull(user(userId).name());
}; };
const auto pushFrom = [&](const QByteArray &label = "from") { const auto pushFrom = [&](const QByteArray &label = "from") {
@ -309,7 +321,7 @@ QByteArray SerializeMessage(
} }
}; };
const auto pushUserNames = [&]( const auto pushUserNames = [&](
const std::vector<int32> &data, const std::vector<UserId> &data,
const QByteArray &label = "members") { const QByteArray &label = "members") {
auto list = std::vector<QByteArray>(); auto list = std::vector<QByteArray>();
for (const auto userId : data) { for (const auto userId : data) {
@ -716,7 +728,7 @@ Result JsonWriter::writePersonal(const Data::PersonalInfo &data) {
return _output->writeBlock( return _output->writeBlock(
prepareObjectItemStart("personal_information") prepareObjectItemStart("personal_information")
+ SerializeObject(_context, { + SerializeObject(_context, {
{ "user_id", Data::NumberToString(data.user.id) }, { "user_id", Data::NumberToString(data.user.bareId) },
{ "first_name", SerializeString(info.firstName) }, { "first_name", SerializeString(info.firstName) },
{ "last_name", SerializeString(info.lastName) }, { "last_name", SerializeString(info.lastName) },
{ {
@ -822,7 +834,12 @@ Result JsonWriter::writeSavedContacts(const Data::ContactsList &data) {
})); }));
} else { } else {
block.append(SerializeObject(_context, { block.append(SerializeObject(_context, {
{ "user_id", Data::NumberToString(contact.userId) }, {
"user_id",
(contact.userId
? Data::NumberToString(contact.userId.bare)
: QByteArray())
},
{ "first_name", SerializeString(contact.firstName) }, { "first_name", SerializeString(contact.firstName) },
{ "last_name", SerializeString(contact.lastName) }, { "last_name", SerializeString(contact.lastName) },
{ {
@ -867,7 +884,7 @@ Result JsonWriter::writeFrequentContacts(const Data::ContactsList &data) {
}(); }();
block.append(prepareArrayItemStart()); block.append(prepareArrayItemStart());
block.append(SerializeObject(_context, { block.append(SerializeObject(_context, {
{ "id", Data::NumberToString(top.peer.id()) }, { "id", Data::NumberToString(Data::PeerToBareId(top.peer.id())) },
{ "category", SerializeString(category) }, { "category", SerializeString(category) },
{ "type", SerializeString(type) }, { "type", SerializeString(type) },
{ "name", StringAllowNull(top.peer.name()) }, { "name", StringAllowNull(top.peer.name()) },
@ -1066,7 +1083,7 @@ Result JsonWriter::writeDialogStart(const Data::DialogInfo &data) {
block.append(prepareObjectItemStart("type") block.append(prepareObjectItemStart("type")
+ StringAllowNull(TypeString(data.type))); + StringAllowNull(TypeString(data.type)));
block.append(prepareObjectItemStart("id") block.append(prepareObjectItemStart("id")
+ Data::NumberToString(data.peerId)); + Data::NumberToString(Data::PeerToBareId(data.peerId)));
block.append(prepareObjectItemStart("messages")); block.append(prepareObjectItemStart("messages"));
block.append(pushNesting(Context::kArray)); block.append(pushNesting(Context::kArray));
return _output->writeBlock(block); return _output->writeBlock(block);