summaryrefslogtreecommitdiff
path: root/protocols/Telegram/src/proto.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/src/proto.cpp')
-rw-r--r--protocols/Telegram/src/proto.cpp122
1 files changed, 99 insertions, 23 deletions
diff --git a/protocols/Telegram/src/proto.cpp b/protocols/Telegram/src/proto.cpp
index efb92742fb..66fab24119 100644
--- a/protocols/Telegram/src/proto.cpp
+++ b/protocols/Telegram/src/proto.cpp
@@ -17,7 +17,10 @@ static int CompareRequests(const TG_REQUEST_BASE *p1, const TG_REQUEST_BASE *p2)
}
static int CompareChats(const TG_USER *p1, const TG_USER *p2)
-{ return CompareId(p1->chatId, p2->chatId);
+{
+ if (p1->chatId != p2->chatId)
+ return CompareId(p1->chatId, p2->chatId);
+ return CompareId(p1->forumId, p2->forumId);
}
static int CompareUsers(const TG_USER *p1, const TG_USER *p2)
@@ -57,6 +60,7 @@ CTelegramProto::CTelegramProto(const char* protoName, const wchar_t* userName) :
m_bUsePopups(this, "UsePopups", true),
m_bCompressFiles(this, "CompressFiles", true),
m_bHideGroupchats(this, "HideChats", true),
+ m_bDeleteContacts(this, "DeleteContacts", false),
m_bIncludePreviews(this, "IncludePreview", true),
m_bResidentChannels(this, "ResidentChannels", false)
{
@@ -108,6 +112,8 @@ CTelegramProto::CTelegramProto(const char* protoName, const wchar_t* userName) :
HookProtoEvent(ME_GC_MUTE, &CTelegramProto::GcMuteHook);
HookProtoEvent(ME_GC_EVENT, &CTelegramProto::GcEventHook);
HookProtoEvent(ME_GC_BUILDMENU, &CTelegramProto::GcMenuHook);
+
+ CheckCompatibility();
}
CTelegramProto::~CTelegramProto()
@@ -125,6 +131,12 @@ void CTelegramProto::OnCacheInit()
if (int64_t id = GetId(cc)) {
bool isGroupChat = isChatRoom(cc);
auto *pUser = new TG_USER(id, cc, isGroupChat);
+ if (auto iThreadId = GetId(cc, DBKEY_THREAD)) {
+ pUser->isForum = true;
+ pUser->chatId = pUser->id;
+ pUser->forumId = iThreadId;
+ m_arChats.insert(pUser);
+ }
pUser->szAvatarHash = getMStringA(cc, DBKEY_AVATAR_HASH);
m_arUsers.insert(pUser);
if (isGroupChat && iCompatLevel < 3)
@@ -174,6 +186,8 @@ void CTelegramProto::OnModulesLoaded()
{
InitPopups();
+ HookProtoEvent(ME_USERINFO_INITIALISE, &CTelegramProto::OnUserInfoInit);
+
m_bSmileyAdd = ServiceExists(MS_SMILEYADD_REPLACESMILEYS);
if (m_bSmileyAdd)
SmileyAdd_LoadContactSmileys(SMADD_FOLDER, m_szModuleName, GetAvatarPath() + L"\\Stickers\\*.*");
@@ -183,9 +197,10 @@ void CTelegramProto::OnShutdown()
{
m_bTerminated = true;
- for (auto &cc : m_arUsers)
- if (cc->isBot && !cc->chatId && cc->hContact != INVALID_CONTACT_ID)
- Contact::RemoveFromList(cc->hContact);
+ if (m_bDeleteContacts)
+ for (auto &cc : m_arUsers)
+ if (cc->isBot && !cc->chatId && cc->hContact != INVALID_CONTACT_ID)
+ Contact::RemoveFromList(cc->hContact);
}
int CTelegramProto::OnWindowEvent(WPARAM wParam, LPARAM lParam)
@@ -264,9 +279,9 @@ void CTelegramProto::OnEventEdited(MCONTACT hContact, MEVENT, const DBEVENTINFO
return;
if (dbei.szId && dbei.cbBlob && dbei.pBlob && dbei.eventType == EVENTTYPE_MESSAGE) {
- auto text = formatBbcodes((char*)dbei.pBlob);
- // auto content = TD::make_object<TD::inputMessageText>(std::move(text), 0, false);
- // SendQuery(new TD::editMessageText(pUser->chatId, dbei2id(dbei), 0, std::move(content)));
+ auto content = TD::make_object<TD::inputMessageText>();
+ content->text_ = formatBbcodes((char *)dbei.pBlob);
+ SendQuery(new TD::editMessageText(pUser->chatId, dbei2id(dbei), 0, std::move(content)));
}
}
@@ -377,6 +392,50 @@ INT_PTR CTelegramProto::GetCaps(int type, MCONTACT hContact)
/////////////////////////////////////////////////////////////////////////////////////////
+int CTelegramProto::GetInfo(MCONTACT hContact, int)
+{
+ if (auto *pUser = FindUser(GetId(hContact))) {
+ if (!pUser->isGroupChat)
+ SendQuery(new TD::getUserFullInfo(pUser->id), &CTelegramProto::OnGetUserInfo, pUser);
+ else {
+ if (FindSuperGroup(pUser->id))
+ SendQuery(new TD::getSupergroupFullInfo(pUser->id), &CTelegramProto::OnGetUserInfo, pUser);
+ else
+ SendQuery(new TD::getBasicGroupFullInfo(pUser->id), &CTelegramProto::OnGetUserInfo, pUser);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+void CTelegramProto::OnGetUserInfo(td::ClientManager::Response &response, void *pUserInfo)
+{
+ if (!response.object)
+ return;
+
+ auto *pUser = (TG_USER *)pUserInfo;
+
+ switch (response.object->get_id()) {
+ case TD::basicGroupFullInfo::ID:
+ ProcessBasicGroupInfo(pUser, (TD::basicGroupFullInfo *)response.object.get());
+ break;
+ case TD::supergroupFullInfo::ID:
+ ProcessSuperGroupInfo(pUser, (TD::supergroupFullInfo *)response.object.get());
+ break;
+ case TD::userFullInfo::ID:
+ ProcessUserInfo(pUser->id, (TD::userFullInfo *)response.object.get());
+ break;
+
+ default:
+ debugLogA("Gotten class ID %d instead of %d, exiting", response.object->get_id(), TD::chats::ID);
+ return;
+ }
+
+ ProtoBroadcastAck(pUser->hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, HANDLE(1));
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
void CTelegramProto::OnSearchResults(td::ClientManager::Response &response)
{
int iCount = ::InterlockedDecrement(&m_iSearchCount);
@@ -447,6 +506,16 @@ void CTelegramProto::ProcessFileMessage(TG_FILE_REQUEST *ft, const TD::message *
return;
}
+ // if that file was sent once, it might be cached at the server & reused
+ if (auto *pRemote = pFile->remote_.get()) {
+ if (pRemote->is_uploading_completed_) {
+ ShowFileProgress(pFile, ft);
+ ProtoBroadcastAck(ft->m_hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft);
+ delete ft;
+ return;
+ }
+ }
+
char szUserId[100];
auto szMsgId(msg2id(pMsg));
@@ -462,24 +531,32 @@ void CTelegramProto::ProcessFileMessage(TG_FILE_REQUEST *ft, const TD::message *
dbei.szModule = Proto_GetBaseAccountName(ft->m_hContact);
dbei.eventType = EVENTTYPE_FILE;
dbei.flags = DBEF_SENT | DBEF_UTF;
- dbei.timestamp = time(0);
-
- TG_FILE_REQUEST localft(TG_FILE_REQUEST::FILE, 0, 0);
- localft.m_fileName = Utf2T(pFile->local_->path_.c_str());
- localft.m_fileSize = pFile->size_;
- localft.m_uniqueId = szMsgId;
- localft.m_szUserId = szUserId;
-
- DB::FILE_BLOB blob(localft.m_fileName, ft->m_wszDescr);
- OnSendOfflineFile(dbei, blob, &localft);
+ dbei.iTimestamp = time(0);
+
+ auto *localft = new TG_FILE_REQUEST(TG_FILE_REQUEST::FILE, 0, 0);
+ localft->m_hContact = ft->m_hContact;
+ localft->m_fileName = Utf2T(pFile->local_->path_.c_str());
+ localft->m_fileSize = pFile->size_;
+ localft->m_uniqueId = szMsgId;
+ localft->m_szUserId = szUserId;
+ localft->m_fileId = pFile->id_;
+
+ DB::FILE_BLOB blob(localft->m_fileName, ft->m_wszDescr);
+ OnSendOfflineFile(dbei, blob, localft);
blob.write(dbei);
db_event_add(ft->m_hContact, &dbei);
+
+ mir_cslock lck(m_csFiles);
+ m_arFiles.insert(localft);
}
else {
ft->m_szUserId = szUserId;
ft->m_uniqueId = szMsgId;
- ProtoBroadcastAck(ft->m_hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft);
+ ft->m_fileId = pFile->id_;
+
+ mir_cslock lck(m_csFiles);
+ m_arFiles.insert(ft);
}
}
}
@@ -490,7 +567,6 @@ void CTelegramProto::OnSendFile(td::ClientManager::Response &response, void *pUs
if (response.object->get_id() == TD::message::ID) {
ProcessFileMessage(ft, (TD::message *)response.object.get(), false);
- ProtoBroadcastAck(ft->m_hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft);
}
else if (response.object->get_id() == TD::messages::ID) {
int i = 0;
@@ -500,8 +576,6 @@ void CTelegramProto::OnSendFile(td::ClientManager::Response &response, void *pUs
i++;
}
}
-
- delete ft;
}
HANDLE CTelegramProto::SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles)
@@ -586,8 +660,8 @@ HANDLE CTelegramProto::SendFile(MCONTACT hContact, const wchar_t *szDescription,
pPart = std::move(pContent);
}
else if (iFileType == TG_FILE_REQUEST::VOICE) {
- auto pContent = TD::make_object<TD::inputMessageVoiceNote>();
- pContent->voice_note_ = makeFile(it->pwszName);
+ auto pContent = TD::make_object<TD::inputMessageAudio>();
+ pContent->audio_ = makeFile(it->pwszName);
pContent->caption_ = std::move(caption);
pContent->duration_ = 0;
pPart = std::move(pContent);
@@ -654,6 +728,8 @@ int CTelegramProto::SetStatus(int iNewStatus)
// Routing statuses not supported by Telegram
switch (iNewStatus) {
case ID_STATUS_OFFLINE:
+ case ID_STATUS_AWAY:
+ case ID_STATUS_NA:
m_iDesiredStatus = iNewStatus;
break;