2020-02-23 14:02:47 +01:00
|
|
|
#include "account-data.h"
|
|
|
|
#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-05-13 11:21:19 +02:00
|
|
|
int32_t stringToUserId(const char *s)
|
|
|
|
{
|
|
|
|
if (strncmp(s, "id", 2))
|
|
|
|
return 0;
|
|
|
|
s += 2;
|
|
|
|
|
|
|
|
const char *c = s;
|
|
|
|
if (*c == '-')
|
|
|
|
c++;
|
|
|
|
if ((*c == '\0') || (*c == '0'))
|
|
|
|
return 0;
|
|
|
|
for (; *c; c++)
|
|
|
|
if ((c >= s+12) || !isdigit(*c))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
long long x;
|
|
|
|
static_assert(sizeof(x) > 4, "need more than int32 here");
|
|
|
|
x = atoll(s);
|
|
|
|
if ((x < INT32_MIN) || (x > INT32_MAX))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
return (getUserIdByPrivateChat(chat) != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t getUserIdByPrivateChat(const td::td_api::chat &chat)
|
|
|
|
{
|
|
|
|
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_);
|
|
|
|
return privType.user_id_;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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-05-09 14:07:21 +02:00
|
|
|
int32_t getBasicGroupId(const td::td_api::chat &chat)
|
|
|
|
{
|
|
|
|
if (chat.type_ && (chat.type_->get_id() == td::td_api::chatTypeBasicGroup::ID))
|
|
|
|
return static_cast<const td::td_api::chatTypeBasicGroup &>(*chat.type_).basic_group_id_;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t getSupergroupId(const td::td_api::chat &chat)
|
|
|
|
{
|
|
|
|
if (chat.type_ && (chat.type_->get_id() == td::td_api::chatTypeSupergroup::ID))
|
|
|
|
return static_cast<const td::td_api::chatTypeSupergroup &>(*chat.type_).supergroup_id_;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
std::string result = user.first_name_;
|
|
|
|
if (!result.empty() && !user.last_name_.empty())
|
|
|
|
result += ' ';
|
|
|
|
result += user.last_name_;
|
|
|
|
|
|
|
|
// 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
|
|
|
|
if ((stringToUserId(result.c_str()) != 0) || isPhoneNumber(result.c_str()))
|
|
|
|
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-05-29 21:29:07 +02:00
|
|
|
int32_t userId = user->id_;
|
|
|
|
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-05-16 21:08:05 +02:00
|
|
|
void TdAccountData::setUserStatus(int32_t userId, td::td_api::object_ptr<td::td_api::UserStatus> status)
|
|
|
|
{
|
|
|
|
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-06-04 22:57:01 +02:00
|
|
|
void TdAccountData::updateSmallProfilePhoto(int32_t userId, td::td_api::object_ptr<td::td_api::file> photo)
|
|
|
|
{
|
|
|
|
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-05-11 19:35:27 +02:00
|
|
|
m_groups[group->id_].group = std::move(group);
|
|
|
|
}
|
|
|
|
|
2020-05-20 21:31:58 +02:00
|
|
|
void TdAccountData::setBasicGroupInfoRequested(int32_t groupId)
|
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
|
|
|
it->second.fullInfoRequested = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TdAccountData::isBasicGroupInfoRequested(int32_t groupId)
|
|
|
|
{
|
|
|
|
auto it = m_groups.find(groupId);
|
|
|
|
if (it != m_groups.end())
|
|
|
|
return it->second.fullInfoRequested;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-05-11 19:35:27 +02:00
|
|
|
void TdAccountData::updateBasicGroupInfo(int32_t groupId, TdGroupInfoPtr groupInfo)
|
|
|
|
{
|
|
|
|
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-06-01 11:12:26 +02:00
|
|
|
m_supergroups[group->id_].group = std::move(group);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TdAccountData::setSupergroupInfoRequested(int32_t groupId)
|
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
it->second.fullInfoRequested = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TdAccountData::isSupergroupInfoRequested(int32_t groupId)
|
|
|
|
{
|
|
|
|
auto it = m_supergroups.find(groupId);
|
|
|
|
if (it != m_supergroups.end())
|
|
|
|
return it->second.fullInfoRequested;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TdAccountData::updateSupergroupInfo(int32_t groupId, TdSupergroupInfoPtr groupInfo)
|
|
|
|
{
|
|
|
|
if (groupInfo)
|
|
|
|
m_supergroups[groupId].fullInfo = std::move(groupInfo);
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
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(),
|
|
|
|
privType.user_id_);
|
|
|
|
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-05-13 15:59:45 +12:00
|
|
|
chat->id_, (int)privType.user_id_);
|
2020-05-02 12:35:31 +02:00
|
|
|
m_contactUserIdsNoChat.erase(pContact);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-09 18:58:04 +02:00
|
|
|
auto it = m_chatInfo.find(chat->id_);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat = std::move(chat);
|
|
|
|
else {
|
|
|
|
auto entry = m_chatInfo.emplace(chat->id_, ChatInfo());
|
|
|
|
entry.first->second.chat = std::move(chat);
|
|
|
|
entry.first->second.purpleId = ++m_lastChatPurpleId;
|
|
|
|
}
|
2020-02-23 14:02:47 +01:00
|
|
|
}
|
|
|
|
|
2020-05-19 16:36:58 +02:00
|
|
|
void TdAccountData::updateChatChatList(int64_t chatId, td::td_api::object_ptr<td::td_api::ChatList> list)
|
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat->chat_list_ = std::move(list);
|
|
|
|
}
|
|
|
|
|
2020-05-20 13:33:47 +02:00
|
|
|
void TdAccountData::updateChatTitle(int64_t chatId, const std::string &title)
|
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat->title_ = title;
|
|
|
|
}
|
|
|
|
|
2020-06-04 22:57:01 +02:00
|
|
|
void TdAccountData::updateSmallChatPhoto(int64_t chatId, td::td_api::object_ptr<td::td_api::file> photo)
|
|
|
|
{
|
|
|
|
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-06-05 23:20:44 +02:00
|
|
|
void TdAccountData::updateChatOrder(int64_t chatId, int64_t order)
|
|
|
|
{
|
|
|
|
auto it = m_chatInfo.find(chatId);
|
|
|
|
if (it != m_chatInfo.end())
|
|
|
|
it->second.chat->order_ = order;
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:35:31 +02:00
|
|
|
void TdAccountData::setContacts(const std::vector<std::int32_t> &userIds)
|
|
|
|
{
|
|
|
|
for (int32_t userId: userIds)
|
|
|
|
if (getPrivateChatByUserId(userId) == nullptr) {
|
|
|
|
purple_debug_misc(config::pluginId, "Private chat not yet known for user %d\n", (int)userId);
|
|
|
|
m_contactUserIdsNoChat.push_back(userId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TdAccountData::getContactsWithNoChat(std::vector<std::int32_t> &userIds)
|
|
|
|
{
|
|
|
|
userIds = m_contactUserIdsNoChat;
|
|
|
|
}
|
|
|
|
|
2020-02-23 14:02:47 +01:00
|
|
|
const td::td_api::chat *TdAccountData::getChat(int64_t chatId) const
|
|
|
|
{
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
int TdAccountData::getPurpleChatId(int64_t tdChatId)
|
|
|
|
{
|
|
|
|
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-02-27 21:49:02 +01:00
|
|
|
static bool isPrivateChat(const td::td_api::chat &chat, int32_t userId)
|
|
|
|
{
|
|
|
|
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_);
|
|
|
|
return (privType.user_id_ == userId);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const td::td_api::chat *TdAccountData::getPrivateChatByUserId(int32_t userId) const
|
|
|
|
{
|
|
|
|
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-02-23 14:02:47 +01:00
|
|
|
const td::td_api::user *TdAccountData::getUser(int32_t userId) const
|
|
|
|
{
|
|
|
|
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-05-20 15:13:06 +02:00
|
|
|
int32_t userId = getUserIdByPrivateChat(chat);
|
|
|
|
if (userId != 0)
|
|
|
|
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
|
|
|
|
{
|
|
|
|
return getDisplayName(user.id_);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string TdAccountData::getDisplayName(int32_t userId) const
|
|
|
|
{
|
|
|
|
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-05-09 14:07:21 +02:00
|
|
|
const td::td_api::basicGroup *TdAccountData::getBasicGroup(int32_t groupId) const
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
const td::td_api::basicGroupFullInfo *TdAccountData::getBasicGroupInfo(int32_t groupId) const
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
const td::td_api::supergroup *TdAccountData::getSupergroup(int32_t groupId) const
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
const td::td_api::supergroupFullInfo *TdAccountData::getSupergroupInfo(int32_t groupId) const
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
const td::td_api::chat *TdAccountData::getBasicGroupChatByGroup(int32_t groupId) const
|
|
|
|
{
|
|
|
|
if (groupId == 0)
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
const td::td_api::chat *TdAccountData::getSupergroupChatByGroup(int32_t groupId) const
|
|
|
|
{
|
|
|
|
if (groupId == 0)
|
|
|
|
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
|
|
|
{
|
|
|
|
int groupId = getBasicGroupId(chat);
|
|
|
|
if (groupId) {
|
|
|
|
const td::td_api::basicGroup *group = getBasicGroup(groupId);
|
|
|
|
return (group && isGroupMember(group->status_));
|
|
|
|
}
|
|
|
|
groupId = getSupergroupId(chat);
|
|
|
|
if (groupId) {
|
|
|
|
const td::td_api::supergroup *group = getSupergroup(groupId);
|
|
|
|
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-05-21 14:51:52 +02:00
|
|
|
void TdAccountData::deleteChat(int64_t id)
|
|
|
|
{
|
|
|
|
m_chatInfo.erase(id);
|
|
|
|
}
|
|
|
|
|
2020-06-05 23:20:44 +02:00
|
|
|
void TdAccountData::getSmallestOrderChat(const td::td_api::ChatList &list, int64_t &chatId, int64_t &order)
|
|
|
|
{
|
|
|
|
int64_t minOrder = INT64_MAX;
|
|
|
|
int64_t id = 0;
|
|
|
|
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-05-13 12:31:03 +02:00
|
|
|
const ContactRequest *TdAccountData::findContactRequest(int32_t userId)
|
|
|
|
{
|
|
|
|
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-06-02 18:42:19 +02:00
|
|
|
void TdAccountData::addFileTransfer(int32_t fileId, PurpleXfer *xfer, int64_t 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-06-02 18:42:19 +02:00
|
|
|
bool TdAccountData::getFileTransfer(int32_t fileId, PurpleXfer *&xfer, int64_t &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)
|
|
|
|
m_secretChats.insert(secretChat->id_);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TdAccountData::getSecretChat(int32_t id)
|
|
|
|
{
|
|
|
|
return (m_secretChats.find(id) != m_secretChats.end());
|
|
|
|
}
|
2020-06-06 22:33:56 +02:00
|
|
|
|
|
|
|
std::vector<std::pair<int32_t, const td::td_api::basicGroupFullInfo *>>
|
|
|
|
TdAccountData::getBasicGroupsWithMember(int32_t userId)
|
|
|
|
{
|
|
|
|
std::vector<std::pair<int32_t, const td::td_api::basicGroupFullInfo *>> result;
|
|
|
|
|
|
|
|
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) {
|
|
|
|
return (member && (member->user_id_ == userId));
|
|
|
|
}))
|
|
|
|
{
|
|
|
|
result.push_back(std::make_pair(item.second.group->id_, item.second.fullInfo.get()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|