2020-02-23 14:02:47 +01:00
|
|
|
#include "account-data.h"
|
2020-07-25 12:49:38 +02:00
|
|
|
#include "client-utils.h"
|
2020-02-23 14:02:47 +01:00
|
|
|
#include "config.h"
|
|
|
|
#include <purple.h>
|
|
|
|
#include <algorithm>
|
|
|
|
|
2020-05-13 11:21:19 +02:00
|
|
|
static bool isCanonicalPhoneNumber(const char *s)
|
2020-05-04 17:32:33 +02:00
|
|
|
{
|
|
|
|
if (*s == '\0')
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (const char *c = s; *c; c++)
|
|
|
|
if (!isdigit(*c))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isPhoneNumber(const char *s)
|
|
|
|
{
|
|
|
|
if (*s == '+') s++;
|
|
|
|
return isCanonicalPhoneNumber(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *getCanonicalPhoneNumber(const char *s)
|
|
|
|
{
|
|
|
|
if (*s == '+')
|
|
|
|
return s+1;
|
|
|
|
else
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
UserId purpleBuddyNameToUserId(const char *s)
|
2020-05-13 11:21:19 +02:00
|
|
|
{
|
|
|
|
if (strncmp(s, "id", 2))
|
2020-10-04 15:17:04 +02:00
|
|
|
return UserId::invalid;
|
|
|
|
return stringToUserId(s+2);
|
2020-05-13 11:21:19 +02:00
|
|
|
}
|
|
|
|
|
2020-05-04 17:32:33 +02:00
|
|
|
static bool isPhoneEqual(const std::string &n1, const std::string &n2)
|
|
|
|
{
|
|
|
|
const char *s1 = n1.c_str();
|
|
|
|
const char *s2 = n2.c_str();
|
|
|
|
if (*s1 == '+') s1++;
|
|
|
|
if (*s2 == '+') s2++;
|
|
|
|
return !strcmp(s1, s2);
|
|
|
|
}
|
|
|
|
|
2020-05-20 15:13:06 +02:00
|
|
|
bool isPrivateChat(const td::td_api::chat &chat)
|
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
return getUserIdByPrivateChat(chat).valid();
|
2020-05-20 15:13:06 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
UserId getUserIdByPrivateChat(const td::td_api::chat &chat)
|
2020-05-20 15:13:06 +02:00
|
|
|
{
|
|
|
|
if (chat.type_ && (chat.type_->get_id() == td::td_api::chatTypePrivate::ID)) {
|
|
|
|
const td::td_api::chatTypePrivate &privType = static_cast<const td::td_api::chatTypePrivate &>(*chat.type_);
|
2020-10-04 15:17:04 +02:00
|
|
|
return getUserId(privType);
|
2020-05-20 15:13:06 +02:00
|
|
|
}
|
2020-10-04 15:17:04 +02:00
|
|
|
return UserId::invalid;
|
2020-05-20 15:13:06 +02:00
|
|
|
}
|
|
|
|
|
2020-05-29 21:29:07 +02:00
|
|
|
bool isChatInContactList(const td::td_api::chat &chat, const td::td_api::user *privateChatUser)
|
|
|
|
{
|
|
|
|
return (chat.chat_list_ != nullptr) || (privateChatUser && privateChatUser->is_contact_);
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
BasicGroupId getBasicGroupId(const td::td_api::chat &chat)
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
|
|
|
if (chat.type_ && (chat.type_->get_id() == td::td_api::chatTypeBasicGroup::ID))
|
2020-10-04 15:17:04 +02:00
|
|
|
return getBasicGroupId(static_cast<const td::td_api::chatTypeBasicGroup &>(*chat.type_));
|
2020-05-09 14:07:21 +02:00
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
return BasicGroupId::invalid;
|
2020-05-09 14:07:21 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
SupergroupId getSupergroupId(const td::td_api::chat &chat)
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
|
|
|
if (chat.type_ && (chat.type_->get_id() == td::td_api::chatTypeSupergroup::ID))
|
2020-10-04 15:17:04 +02:00
|
|
|
return getSupergroupId(static_cast<const td::td_api::chatTypeSupergroup &>(*chat.type_));
|
2020-05-09 14:07:21 +02:00
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
return SupergroupId::invalid;
|
2020-05-09 14:07:21 +02:00
|
|
|
}
|
|
|
|
|
2020-05-10 14:24:15 +02:00
|
|
|
bool isGroupMember(const td::td_api::object_ptr<td::td_api::ChatMemberStatus> &status)
|
|
|
|
{
|
2020-05-22 14:02:48 +02:00
|
|
|
if (!status)
|
|
|
|
return false;
|
|
|
|
else if ((status->get_id() == td::td_api::chatMemberStatusLeft::ID) ||
|
|
|
|
(status->get_id() == td::td_api::chatMemberStatusBanned::ID))
|
|
|
|
return false;
|
|
|
|
else if (status->get_id() == td::td_api::chatMemberStatusRestricted::ID)
|
|
|
|
return static_cast<const td::td_api::chatMemberStatusRestricted &>(*status).is_member_;
|
|
|
|
else if (status->get_id() == td::td_api::chatMemberStatusCreator::ID)
|
|
|
|
return static_cast<const td::td_api::chatMemberStatusCreator &>(*status).is_member_;
|
|
|
|
else
|
|
|
|
return true;
|
2020-05-10 14:24:15 +02:00
|
|
|
}
|
|
|
|
|
2020-05-29 19:39:22 +02:00
|
|
|
static std::string makeDisplayName(const td::td_api::user &user)
|
|
|
|
{
|
2020-07-25 12:49:38 +02:00
|
|
|
std::string result = makeBasicDisplayName(user);
|
2020-05-29 19:39:22 +02:00
|
|
|
|
|
|
|
// If some sneaky user sets their name equal to someone else's libpurple username, or to our
|
|
|
|
// phone number which is libpurple account name, make sure display name is different, because
|
|
|
|
// of how it is used for group chat members
|
2020-10-04 15:17:04 +02:00
|
|
|
if ((purpleBuddyNameToUserId(result.c_str()).valid()) || isPhoneNumber(result.c_str()))
|
2020-05-29 19:39:22 +02:00
|
|
|
result += ' ';
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-05-29 21:29:07 +02:00
|
|
|
void TdAccountData::updateUser(TdUserPtr userPtr)
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
2020-05-29 21:29:07 +02:00
|
|
|
const td::td_api::user *user = userPtr.get();
|
2020-05-29 19:39:22 +02:00
|
|
|
if (user) {
|
2020-10-04 15:17:04 +02:00
|
|
|
UserId userId = getId(*user);
|
2020-05-29 21:29:07 +02:00
|
|
|
auto it = m_userInfo.find(userId);
|
|
|
|
|
|
|
|
if (it == m_userInfo.end()) {
|
|
|
|
auto ret = m_userInfo.emplace(std::make_pair(userId, UserInfo()));
|
|
|
|
it = ret.first;
|
|
|
|
}
|
|
|
|
|
|
|
|
UserInfo &entry = it->second;
|
|
|
|
entry.user = std::move(userPtr);
|
2020-06-07 01:14:06 +02:00
|
|
|
entry.displayName = makeDisplayName(*user);
|
|
|
|
for (unsigned n = 0; n != UINT32_MAX; n++) {
|
|
|
|
std::string displayName = entry.displayName;
|
|
|
|
if (n != 0) {
|
|
|
|
displayName += " #";
|
|
|
|
displayName += std::to_string(n);
|
|
|
|
}
|
2020-05-29 21:29:07 +02:00
|
|
|
|
2020-06-07 01:14:06 +02:00
|
|
|
std::vector<const td::td_api::user *> existingUsers;
|
|
|
|
getUsersByDisplayName(displayName.c_str(), existingUsers);
|
|
|
|
if (std::none_of(existingUsers.begin(), existingUsers.end(),
|
|
|
|
[user](const td::td_api::user *otherUser) {
|
|
|
|
return (otherUser != user);
|
|
|
|
}))
|
|
|
|
{
|
|
|
|
entry.displayName = std::move(displayName);
|
|
|
|
break;
|
2020-05-29 21:29:07 +02:00
|
|
|
}
|
2020-05-29 19:39:22 +02:00
|
|
|
}
|
|
|
|
}
|
2020-05-09 14:07:21 +02:00
|
|
|
}
|
2020-05-07 21:15:32 +02:00
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::setUserStatus(UserId userId, td::td_api::object_ptr<td::td_api::UserStatus> status)
|
2020-05-16 21:08:05 +02:00
|
|
|
{
|
|
|
|
auto it = m_userInfo.find(userId);
|
|
|
|
if (it != m_userInfo.end())
|
2020-05-29 19:39:22 +02:00
|
|
|
it->second.user->status_ = std::move(status);
|
2020-05-16 21:08:05 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateSmallProfilePhoto(UserId userId, td::td_api::object_ptr<td::td_api::file> photo)
|
2020-06-04 22:57:01 +02:00
|
|
|
{
|
|
|
|
auto it = m_userInfo.find(userId);
|
|
|
|
if (it != m_userInfo.end()) {
|
|
|
|
td::td_api::user &user = *it->second.user;
|
|
|
|
if (user.profile_photo_)
|
|
|
|
user.profile_photo_->small_ = std::move(photo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-09 14:07:21 +02:00
|
|
|
void TdAccountData::updateBasicGroup(TdGroupPtr group)
|
|
|
|
{
|
|
|
|
if (group)
|
2020-10-04 15:17:04 +02:00
|
|
|
m_groups[getId(*group)].group = std::move(group);
|
2020-05-11 19:35:27 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::setBasicGroupInfoRequested(BasicGroupId groupId)
|
2020-05-20 21:31:58 +02:00
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
|
|
|
it->second.fullInfoRequested = true;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
bool TdAccountData::isBasicGroupInfoRequested(BasicGroupId groupId)
|
2020-05-20 21:31:58 +02:00
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
|
|
|
return it->second.fullInfoRequested;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateBasicGroupInfo(BasicGroupId groupId, TdGroupInfoPtr groupInfo)
|
2020-05-11 19:35:27 +02:00
|
|
|
{
|
|
|
|
if (groupInfo)
|
|
|
|
m_groups[groupId].fullInfo = std::move(groupInfo);
|
2020-05-09 14:07:21 +02:00
|
|
|
}
|
2020-02-23 14:02:47 +01:00
|
|
|
|
2020-05-09 14:07:21 +02:00
|
|
|
void TdAccountData::updateSupergroup(TdSupergroupPtr group)
|
|
|
|
{
|
|
|
|
if (group)
|
2020-10-04 15:17:04 +02:00
|
|
|
m_supergroups[getId(*group)].group = std::move(group);
|
2020-06-01 11:12:26 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::setSupergroupInfoRequested(SupergroupId groupId)
|
2020-06-01 11:12:26 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
it->second.fullInfoRequested = true;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
bool TdAccountData::isSupergroupInfoRequested(SupergroupId groupId)
|
2020-06-01 11:12:26 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
return it->second.fullInfoRequested;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateSupergroupInfo(SupergroupId groupId, TdSupergroupInfoPtr groupInfo)
|
2020-06-01 11:12:26 +02:00
|
|
|
{
|
|
|
|
if (groupInfo)
|
|
|
|
m_supergroups[groupId].fullInfo = std::move(groupInfo);
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateSupergroupMembers(SupergroupId groupId, TdChatMembersPtr members)
|
2020-07-05 15:01:24 +02:00
|
|
|
{
|
|
|
|
if (members)
|
|
|
|
m_supergroups[groupId].members = std::move(members);
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:35:31 +02:00
|
|
|
void TdAccountData::addChat(TdChatPtr chat)
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
2020-05-08 19:50:55 +02:00
|
|
|
if (!chat)
|
2020-02-23 14:02:47 +01:00
|
|
|
return;
|
|
|
|
|
2020-05-02 12:35:31 +02:00
|
|
|
if (chat->type_->get_id() == td::td_api::chatTypePrivate::ID) {
|
|
|
|
const td::td_api::chatTypePrivate &privType = static_cast<const td::td_api::chatTypePrivate &>(*chat->type_);
|
|
|
|
auto pContact = std::find(m_contactUserIdsNoChat.begin(), m_contactUserIdsNoChat.end(),
|
2020-10-04 15:17:04 +02:00
|
|
|
getUserId(privType));
|
2020-05-02 12:35:31 +02:00
|
|
|
if (pContact != m_contactUserIdsNoChat.end()) {
|
2020-05-20 23:36:28 +02:00
|
|
|
purple_debug_misc(config::pluginId, "Private chat (id %" G_GINT64_FORMAT ") now known for user %d\n",
|
2020-10-04 15:17:04 +02:00
|
|
|
chat->id_, privType.user_id_);
|
2020-05-02 12:35:31 +02:00
|
|
|
m_contactUserIdsNoChat.erase(pContact);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
auto it = m_chatInfo.find(getId(*chat));
|
2020-05-09 18:58:04 +02:00
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat = std::move(chat);
|
|
|
|
else {
|
2020-10-04 15:17:04 +02:00
|
|
|
auto entry = m_chatInfo.emplace(getId(*chat), ChatInfo());
|
2020-05-09 18:58:04 +02:00
|
|
|
entry.first->second.chat = std::move(chat);
|
|
|
|
entry.first->second.purpleId = ++m_lastChatPurpleId;
|
|
|
|
}
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateChatChatList(ChatId chatId, td::td_api::object_ptr<td::td_api::ChatList> list)
|
2020-05-19 16:36:58 +02:00
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat->chat_list_ = std::move(list);
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateChatTitle(ChatId chatId, const std::string &title)
|
2020-05-20 13:33:47 +02:00
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat->title_ = title;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateSmallChatPhoto(ChatId chatId, td::td_api::object_ptr<td::td_api::file> photo)
|
2020-06-04 22:57:01 +02:00
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end()) {
|
|
|
|
td::td_api::chat &chat = *it->second.chat;
|
|
|
|
if (chat.photo_)
|
|
|
|
chat.photo_->small_ = std::move(photo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::updateChatOrder(ChatId chatId, int64_t order)
|
2020-06-05 23:20:44 +02:00
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat->order_ = order;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::setContacts(const td::td_api::users &users)
|
2020-05-02 12:35:31 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
for (unsigned i = 0; i < users.user_ids_.size(); i++) {
|
|
|
|
UserId userId = getUserId(users, i);
|
2020-05-02 12:35:31 +02:00
|
|
|
if (getPrivateChatByUserId(userId) == nullptr) {
|
2020-10-04 15:17:04 +02:00
|
|
|
purple_debug_misc(config::pluginId, "Private chat not yet known for user %d\n", userId.value());
|
2020-05-02 12:35:31 +02:00
|
|
|
m_contactUserIdsNoChat.push_back(userId);
|
|
|
|
}
|
2020-10-04 15:17:04 +02:00
|
|
|
}
|
2020-05-02 12:35:31 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::getContactsWithNoChat(std::vector<UserId> &userIds)
|
2020-05-02 12:35:31 +02:00
|
|
|
{
|
|
|
|
userIds = m_contactUserIdsNoChat;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getChat(ChatId chatId) const
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
|
|
|
auto pChatInfo = m_chatInfo.find(chatId);
|
|
|
|
if (pChatInfo == m_chatInfo.end())
|
|
|
|
return nullptr;
|
|
|
|
else
|
2020-05-09 18:58:04 +02:00
|
|
|
return pChatInfo->second.chat.get();
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
int TdAccountData::getPurpleChatId(ChatId tdChatId)
|
2020-05-09 18:58:04 +02:00
|
|
|
{
|
|
|
|
auto pChatInfo = m_chatInfo.find(tdChatId);
|
|
|
|
if (pChatInfo == m_chatInfo.end())
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return pChatInfo->second.purpleId;
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-05-10 14:24:15 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getChatByPurpleId(int32_t purpleChatId) const
|
|
|
|
{
|
|
|
|
auto pChatInfo = std::find_if(m_chatInfo.begin(), m_chatInfo.end(),
|
|
|
|
[purpleChatId](const ChatMap::value_type &entry) {
|
|
|
|
return (entry.second.purpleId == purpleChatId);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (pChatInfo != m_chatInfo.end())
|
|
|
|
return pChatInfo->second.chat.get();
|
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
static bool isPrivateChat(const td::td_api::chat &chat, UserId userId)
|
2020-02-27 21:49:02 +01:00
|
|
|
{
|
|
|
|
if (chat.type_->get_id() == td::td_api::chatTypePrivate::ID) {
|
|
|
|
const td::td_api::chatTypePrivate &privType = static_cast<const td::td_api::chatTypePrivate &>(*chat.type_);
|
2020-10-04 15:17:04 +02:00
|
|
|
return (getUserId(privType) == userId);
|
2020-02-27 21:49:02 +01:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getPrivateChatByUserId(UserId userId) const
|
2020-02-27 21:49:02 +01:00
|
|
|
{
|
|
|
|
auto pChatInfo = std::find_if(m_chatInfo.begin(), m_chatInfo.end(),
|
2020-05-10 14:24:15 +02:00
|
|
|
[userId](const ChatMap::value_type &entry) {
|
2020-05-09 18:58:04 +02:00
|
|
|
return isPrivateChat(*entry.second.chat, userId);
|
2020-02-27 21:49:02 +01:00
|
|
|
});
|
|
|
|
if (pChatInfo == m_chatInfo.end())
|
|
|
|
return nullptr;
|
|
|
|
else
|
2020-05-09 18:58:04 +02:00
|
|
|
return pChatInfo->second.chat.get();
|
2020-02-27 21:49:02 +01:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::user *TdAccountData::getUser(UserId userId) const
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
|
|
|
auto pUser = m_userInfo.find(userId);
|
|
|
|
if (pUser == m_userInfo.end())
|
|
|
|
return nullptr;
|
|
|
|
else
|
2020-05-29 19:39:22 +02:00
|
|
|
return pUser->second.user.get();
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-02-27 21:49:02 +01:00
|
|
|
const td::td_api::user *TdAccountData::getUserByPhone(const char *phoneNumber) const
|
|
|
|
{
|
|
|
|
auto pUser = std::find_if(m_userInfo.begin(), m_userInfo.end(),
|
2020-05-10 14:24:15 +02:00
|
|
|
[phoneNumber](const UserMap::value_type &entry) {
|
2020-05-29 19:39:22 +02:00
|
|
|
return isPhoneEqual(entry.second.user->phone_number_, phoneNumber);
|
2020-02-27 21:49:02 +01:00
|
|
|
});
|
|
|
|
if (pUser == m_userInfo.end())
|
|
|
|
return nullptr;
|
|
|
|
else
|
2020-05-29 19:39:22 +02:00
|
|
|
return pUser->second.user.get();
|
2020-02-27 21:49:02 +01:00
|
|
|
}
|
|
|
|
|
2020-05-04 14:08:57 +02:00
|
|
|
const td::td_api::user *TdAccountData::getUserByPrivateChat(const td::td_api::chat &chat)
|
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
UserId userId = getUserIdByPrivateChat(chat);
|
|
|
|
if (userId.valid())
|
2020-05-20 15:13:06 +02:00
|
|
|
return getUser(userId);
|
2020-05-04 14:08:57 +02:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-05-29 19:39:22 +02:00
|
|
|
std::string TdAccountData::getDisplayName(const td::td_api::user &user) const
|
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
return getDisplayName(getId(user));
|
2020-05-29 19:39:22 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
std::string TdAccountData::getDisplayName(UserId userId) const
|
2020-05-29 19:39:22 +02:00
|
|
|
{
|
|
|
|
auto it = m_userInfo.find(userId);
|
|
|
|
if (it != m_userInfo.end())
|
|
|
|
return it->second.displayName;
|
|
|
|
else
|
|
|
|
return std::string();
|
|
|
|
}
|
|
|
|
|
2020-05-16 20:38:58 +02:00
|
|
|
void TdAccountData::getUsersByDisplayName(const char *displayName,
|
2020-05-29 21:29:07 +02:00
|
|
|
std::vector<const td::td_api::user*> &users)
|
2020-05-16 20:38:58 +02:00
|
|
|
{
|
|
|
|
users.clear();
|
|
|
|
if (!displayName || (*displayName == '\0'))
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (const UserMap::value_type &entry: m_userInfo)
|
2020-05-29 19:39:22 +02:00
|
|
|
if (entry.second.displayName == displayName)
|
|
|
|
users.push_back(entry.second.user.get());
|
2020-05-16 20:38:58 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::basicGroup *TdAccountData::getBasicGroup(BasicGroupId groupId) const
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
2020-05-11 19:35:27 +02:00
|
|
|
return it->second.group.get();
|
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::basicGroupFullInfo *TdAccountData::getBasicGroupInfo(BasicGroupId groupId) const
|
2020-05-11 19:35:27 +02:00
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
|
|
|
return it->second.fullInfo.get();
|
2020-05-09 14:07:21 +02:00
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::supergroup *TdAccountData::getSupergroup(SupergroupId groupId) const
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
2020-06-01 11:12:26 +02:00
|
|
|
return it->second.group.get();
|
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::supergroupFullInfo *TdAccountData::getSupergroupInfo(SupergroupId groupId) const
|
2020-06-01 11:12:26 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
return it->second.fullInfo.get();
|
2020-05-09 14:07:21 +02:00
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chatMembers *TdAccountData::getSupergroupMembers(SupergroupId groupId) const
|
2020-07-05 15:01:24 +02:00
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
return it->second.members.get();
|
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getBasicGroupChatByGroup(BasicGroupId groupId) const
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
if (!groupId.valid())
|
2020-05-09 14:07:21 +02:00
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto it = std::find_if(m_chatInfo.begin(), m_chatInfo.end(),
|
2020-05-10 14:24:15 +02:00
|
|
|
[groupId](const ChatMap::value_type &entry) {
|
2020-05-09 18:58:04 +02:00
|
|
|
return (getBasicGroupId(*entry.second.chat) == groupId);
|
2020-05-09 14:07:21 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_chatInfo.end())
|
2020-05-09 18:58:04 +02:00
|
|
|
return it->second.chat.get();
|
2020-05-09 14:07:21 +02:00
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const td::td_api::chat *TdAccountData::getSupergroupChatByGroup(SupergroupId groupId) const
|
2020-05-09 14:07:21 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
if (!groupId.valid())
|
2020-05-09 14:07:21 +02:00
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto it = std::find_if(m_chatInfo.begin(), m_chatInfo.end(),
|
2020-05-10 14:24:15 +02:00
|
|
|
[groupId](const ChatMap::value_type &entry) {
|
2020-05-09 18:58:04 +02:00
|
|
|
return (getSupergroupId(*entry.second.chat) == groupId);
|
2020-05-09 14:07:21 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_chatInfo.end())
|
2020-05-09 18:58:04 +02:00
|
|
|
return it->second.chat.get();
|
2020-05-09 14:07:21 +02:00
|
|
|
else
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-06-11 00:04:29 +02:00
|
|
|
bool TdAccountData::isGroupChatWithMembership(const td::td_api::chat &chat) const
|
2020-05-10 14:24:15 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
BasicGroupId groupId = getBasicGroupId(chat);
|
|
|
|
if (groupId.valid()) {
|
2020-05-10 14:24:15 +02:00
|
|
|
const td::td_api::basicGroup *group = getBasicGroup(groupId);
|
|
|
|
return (group && isGroupMember(group->status_));
|
|
|
|
}
|
2020-10-04 15:17:04 +02:00
|
|
|
SupergroupId supergroupId = getSupergroupId(chat);
|
|
|
|
if (supergroupId.valid()) {
|
|
|
|
const td::td_api::supergroup *group = getSupergroup(supergroupId);
|
2020-05-10 14:24:15 +02:00
|
|
|
return (group && isGroupMember(group->status_));
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-05-20 21:31:58 +02:00
|
|
|
void TdAccountData::getChats(std::vector<const td::td_api::chat *> &chats) const
|
2020-02-23 14:02:47 +01:00
|
|
|
{
|
|
|
|
chats.clear();
|
2020-05-20 21:31:58 +02:00
|
|
|
for (const ChatMap::value_type &item: m_chatInfo)
|
|
|
|
chats.push_back(item.second.chat.get());
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::deleteChat(ChatId id)
|
2020-05-21 14:51:52 +02:00
|
|
|
{
|
|
|
|
m_chatInfo.erase(id);
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::getSmallestOrderChat(const td::td_api::ChatList &list, ChatId &chatId, int64_t &order)
|
2020-06-05 23:20:44 +02:00
|
|
|
{
|
|
|
|
int64_t minOrder = INT64_MAX;
|
2020-10-04 15:17:04 +02:00
|
|
|
ChatId id = ChatId::invalid;
|
2020-06-05 23:20:44 +02:00
|
|
|
for (const ChatMap::value_type &entry: m_chatInfo) {
|
|
|
|
int64_t order = entry.second.chat->order_;
|
|
|
|
if (entry.second.chat->chat_list_ && (entry.second.chat->chat_list_->get_id() == list.get_id()) &&
|
|
|
|
(order < minOrder))
|
|
|
|
{
|
|
|
|
minOrder = order;
|
|
|
|
id = entry.first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
chatId = id;
|
|
|
|
order = minOrder;
|
|
|
|
}
|
|
|
|
|
2020-05-11 19:35:27 +02:00
|
|
|
std::unique_ptr<PendingRequest> TdAccountData::getPendingRequestImpl(uint64_t requestId)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(m_requests.begin(), m_requests.end(),
|
|
|
|
[requestId](const std::unique_ptr<PendingRequest> &req) {
|
|
|
|
return (req->requestId == requestId);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_requests.end()) {
|
|
|
|
auto result = std::move(*it);
|
|
|
|
m_requests.erase(it);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
2020-05-13 12:31:03 +02:00
|
|
|
|
2020-06-02 18:42:19 +02:00
|
|
|
PendingRequest *TdAccountData::findPendingRequestImpl(uint64_t requestId)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(m_requests.begin(), m_requests.end(),
|
|
|
|
[requestId](const std::unique_ptr<PendingRequest> &req) {
|
|
|
|
return (req->requestId == requestId);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_requests.end())
|
|
|
|
return it->get();
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
const ContactRequest *TdAccountData::findContactRequest(UserId userId)
|
2020-05-13 12:31:03 +02:00
|
|
|
{
|
|
|
|
auto it = std::find_if(m_requests.begin(), m_requests.end(),
|
|
|
|
[userId](const std::unique_ptr<PendingRequest> &req) {
|
|
|
|
const ContactRequest *contactReq = dynamic_cast<const ContactRequest *>(req.get());
|
|
|
|
return (contactReq && (contactReq->userId == userId));
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_requests.end())
|
|
|
|
return static_cast<const ContactRequest *>(it->get());
|
|
|
|
return nullptr;
|
|
|
|
}
|
2020-05-16 00:16:06 +02:00
|
|
|
|
2020-06-04 01:28:49 +02:00
|
|
|
DownloadRequest* TdAccountData::findDownloadRequest(int32_t fileId)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(m_requests.begin(), m_requests.end(),
|
|
|
|
[fileId](const std::unique_ptr<PendingRequest> &req) {
|
|
|
|
DownloadRequest *downloadReq = dynamic_cast<DownloadRequest *>(req.get());
|
|
|
|
return (downloadReq && (downloadReq->fileId == fileId));
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it != m_requests.end())
|
|
|
|
return static_cast<DownloadRequest *>(it->get());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-05-16 00:16:06 +02:00
|
|
|
void TdAccountData::addTempFileUpload(int64_t messageId, const std::string &path)
|
|
|
|
{
|
|
|
|
m_sentMessages.emplace_back();
|
|
|
|
m_sentMessages.back().messageId = messageId;
|
|
|
|
m_sentMessages.back().tempFile = path;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string TdAccountData::extractTempFileUpload(int64_t messageId)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(m_sentMessages.begin(), m_sentMessages.end(),
|
|
|
|
[messageId](const SendMessageInfo &item) {
|
|
|
|
return (item.messageId == messageId);
|
|
|
|
});
|
|
|
|
|
|
|
|
std::string result;
|
|
|
|
if (it != m_sentMessages.end()) {
|
|
|
|
result = it->tempFile;
|
|
|
|
m_sentMessages.erase(it);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2020-05-16 13:38:00 +02:00
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
void TdAccountData::addFileTransfer(int32_t fileId, PurpleXfer *xfer, ChatId chatId)
|
2020-05-28 21:29:58 +02:00
|
|
|
{
|
2020-06-02 18:42:19 +02:00
|
|
|
if (std::find_if(m_fileTransfers.begin(), m_fileTransfers.end(),
|
|
|
|
[fileId](const FileTransferInfo &upload) {
|
|
|
|
return (upload.fileId == fileId);
|
|
|
|
}) == m_fileTransfers.end()) {
|
|
|
|
m_fileTransfers.emplace_back();
|
|
|
|
m_fileTransfers.back().fileId = fileId;
|
|
|
|
m_fileTransfers.back().xfer = xfer;
|
|
|
|
m_fileTransfers.back().chatId = chatId;
|
2020-05-28 21:29:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-02 18:42:19 +02:00
|
|
|
void TdAccountData::addPurpleFileTransfer(int32_t fileId, PurpleXfer *xfer)
|
2020-05-28 21:29:58 +02:00
|
|
|
{
|
2020-06-02 18:42:19 +02:00
|
|
|
auto it = std::find_if(m_fileTransfers.begin(), m_fileTransfers.end(),
|
|
|
|
[fileId](const FileTransferInfo &upload) {
|
|
|
|
return (upload.fileId == fileId);
|
|
|
|
});
|
|
|
|
if (it != m_fileTransfers.end())
|
|
|
|
it->xfer = xfer;
|
2020-05-28 21:29:58 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
bool TdAccountData::getFileTransfer(int32_t fileId, PurpleXfer *&xfer, ChatId &chatId)
|
2020-05-28 21:29:58 +02:00
|
|
|
{
|
2020-06-02 18:42:19 +02:00
|
|
|
auto it = std::find_if(m_fileTransfers.begin(), m_fileTransfers.end(),
|
|
|
|
[fileId](const FileTransferInfo &upload) { return (upload.fileId == fileId); });
|
|
|
|
if (it != m_fileTransfers.end()) {
|
2020-05-28 21:29:58 +02:00
|
|
|
xfer = it->xfer;
|
|
|
|
chatId = it->chatId;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-06-02 18:42:19 +02:00
|
|
|
bool TdAccountData::getFileIdForTransfer(PurpleXfer *xfer, int &fileId)
|
2020-05-28 21:29:58 +02:00
|
|
|
{
|
2020-06-02 18:42:19 +02:00
|
|
|
auto it = std::find_if(m_fileTransfers.begin(), m_fileTransfers.end(),
|
|
|
|
[xfer](const FileTransferInfo &upload) { return (upload.xfer == xfer); });
|
|
|
|
if (it != m_fileTransfers.end()) {
|
2020-05-28 21:29:58 +02:00
|
|
|
fileId = it->fileId;
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-06-02 18:42:19 +02:00
|
|
|
void TdAccountData::removeFileTransfer(int32_t fileId)
|
2020-05-28 21:29:58 +02:00
|
|
|
{
|
2020-06-02 18:42:19 +02:00
|
|
|
auto it = std::find_if(m_fileTransfers.begin(), m_fileTransfers.end(),
|
|
|
|
[fileId](const FileTransferInfo &upload) { return (upload.fileId == fileId); });
|
|
|
|
if (it != m_fileTransfers.end())
|
|
|
|
m_fileTransfers.erase(it);
|
2020-05-28 21:29:58 +02:00
|
|
|
}
|
2020-05-31 15:55:28 +02:00
|
|
|
|
|
|
|
void TdAccountData::addSecretChat(td::td_api::object_ptr<td::td_api::secretChat> secretChat)
|
|
|
|
{
|
|
|
|
if (secretChat)
|
2020-10-04 15:17:04 +02:00
|
|
|
m_secretChats.insert(getId(*secretChat));
|
2020-05-31 15:55:28 +02:00
|
|
|
}
|
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
bool TdAccountData::getSecretChat(SecretChatId id)
|
2020-05-31 15:55:28 +02:00
|
|
|
{
|
|
|
|
return (m_secretChats.find(id) != m_secretChats.end());
|
|
|
|
}
|
2020-06-06 22:33:56 +02:00
|
|
|
|
2020-10-04 15:17:04 +02:00
|
|
|
std::vector<std::pair<BasicGroupId, const td::td_api::basicGroupFullInfo *>>
|
|
|
|
TdAccountData::getBasicGroupsWithMember(UserId userId)
|
2020-06-06 22:33:56 +02:00
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
std::vector<std::pair<BasicGroupId, const td::td_api::basicGroupFullInfo *>> result;
|
2020-06-06 22:33:56 +02:00
|
|
|
|
|
|
|
for (const auto &item: m_groups)
|
|
|
|
if (item.second.fullInfo) {
|
|
|
|
auto &members = item.second.fullInfo->members_;
|
|
|
|
if (std::any_of(members.begin(), members.end(),
|
|
|
|
[userId](const td::td_api::object_ptr<td::td_api::chatMember> &member) {
|
2020-10-04 15:17:04 +02:00
|
|
|
return (member && (getUserId(*member) == userId));
|
2020-06-06 22:33:56 +02:00
|
|
|
}))
|
|
|
|
{
|
2020-10-04 15:17:04 +02:00
|
|
|
result.push_back(std::make_pair(getId(*item.second.group), item.second.fullInfo.get()));
|
2020-06-06 22:33:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2020-07-26 23:44:51 +02:00
|
|
|
|
|
|
|
bool TdAccountData::hasActiveCall()
|
|
|
|
{
|
|
|
|
return (m_callData != nullptr);
|
|
|
|
}
|
|
|
|
|
2020-07-27 16:56:42 +02:00
|
|
|
void TdAccountData::setActiveCall(int32_t callId)
|
2020-07-26 23:44:51 +02:00
|
|
|
{
|
2020-07-27 16:56:42 +02:00
|
|
|
if (!m_callData) {
|
2020-07-26 23:44:51 +02:00
|
|
|
m_callData = std::make_unique<tgvoip::VoIPController>();
|
2020-07-27 16:56:42 +02:00
|
|
|
m_callId = callId;
|
|
|
|
}
|
2020-07-26 23:44:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
tgvoip::VoIPController *TdAccountData::getCallData()
|
|
|
|
{
|
|
|
|
return m_callData.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TdAccountData::removeActiveCall()
|
|
|
|
{
|
|
|
|
m_callData.reset();
|
2020-07-27 16:56:42 +02:00
|
|
|
m_callId = 0;
|
2020-07-26 23:44:51 +02:00
|
|
|
}
|