From 7f73433ab8374b7456b29d3a607591029fe97c81 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 25 Nov 2023 21:05:25 +0300 Subject: =?UTF-8?q?fixes=20#3954=20(Telegram+NewStory:=20=D0=BE=D1=82?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20=D0=BD=D0=B5=D1=81=D0=BA?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=BA=D0=B8=D1=85=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- protocols/Telegram/src/avatars.cpp | 2 +- protocols/Telegram/src/proto.cpp | 221 +++++++++++++++++++++++++------------ protocols/Telegram/src/proto.h | 3 +- protocols/Telegram/src/utils.cpp | 31 +++--- protocols/Telegram/src/utils.h | 4 +- 5 files changed, 174 insertions(+), 87 deletions(-) (limited to 'protocols/Telegram/src') diff --git a/protocols/Telegram/src/avatars.cpp b/protocols/Telegram/src/avatars.cpp index 89d3ef98e0..c640478e14 100644 --- a/protocols/Telegram/src/avatars.cpp +++ b/protocols/Telegram/src/avatars.cpp @@ -105,7 +105,7 @@ void __cdecl CTelegramProto::OfflineFileThread(void *pParam) if (dbei && !strcmp(dbei.szModule, m_szModuleName) && dbei.eventType == EVENTTYPE_FILE) { JSONNode root = JSONNode::parse((const char *)dbei.pBlob); if (root) { - auto *ft = new TG_FILE_REQUEST(TG_FILE_REQUEST::Type(root["t"].as_int()), 0, ""); + auto *ft = new TG_FILE_REQUEST(TG_FILE_REQUEST::FILE, 0, ""); ft->ofd = ofd; m_arFiles.insert(ft); diff --git a/protocols/Telegram/src/proto.cpp b/protocols/Telegram/src/proto.cpp index d275c046d5..763db665e9 100644 --- a/protocols/Telegram/src/proto.cpp +++ b/protocols/Telegram/src/proto.cpp @@ -345,17 +345,9 @@ INT_PTR CTelegramProto::GetCaps(int type, MCONTACT) ///////////////////////////////////////////////////////////////////////////////////////// -MEVENT CTelegramProto::RecvFile(MCONTACT hContact, PROTORECVFILE *pre) +MEVENT CTelegramProto::RecvFile(MCONTACT, PROTORECVFILE *) { - MEVENT hEvent = CSuper::RecvFile(hContact, pre); - if (hEvent) - if (auto *ft = (TG_FILE_REQUEST *)pre->lParam) { - DBVARIANT dbv = { DBVT_DWORD }; - dbv.dVal = ft->m_type; - db_event_setJson(hEvent, "t", &dbv); - } - - return hEvent; + return 0; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -403,6 +395,91 @@ HANDLE CTelegramProto::SearchByName(const wchar_t *nick, const wchar_t *firstNam ///////////////////////////////////////////////////////////////////////////////////////// +void CTelegramProto::ProcessFileMessage(TG_FILE_REQUEST *ft, const TD::message *pMsg, bool bCreateEvent) +{ + if (auto *pUser = FindChat(pMsg->chat_id_)) { + const TD::MessageContent *pBody = pMsg->content_.get(); + + TD::file *pFile; + switch (pBody->get_id()) { + case TD::messagePhoto::ID: + pFile = ((TD::messagePhoto *)pBody)->photo_->sizes_[0]->photo_.get(); + break; + + case TD::messageAudio::ID: + pFile = ((TD::messageAudio *)pBody)->audio_->audio_.get(); + break; + + case TD::messageVideo::ID: + pFile = ((TD::messageVideo *)pBody)->video_->video_.get(); + break; + + case TD::messageDocument::ID: + pFile = ((TD::messageDocument *)pBody)->document_->document_.get(); + break; + + default: + return; + } + + auto *pOwnMsg = new TG_OWN_MESSAGE(pUser->hContact, 0, pMsg->id_); + pOwnMsg->tmpFileId = pFile->id_; + m_arOwnMsg.insert(pOwnMsg); + + char szMsgId[40], szUserId[100]; + _i64toa(pMsg->id_, szMsgId, 10); + + if (!GetGcUserId(pUser, pMsg, szUserId)) + szUserId[0] = 0; + + if (bCreateEvent) { + auto *pFileName = pFile->local_->path_.c_str(); + CMStringA szDescr = GetMessageText(pUser, pMsg); + + DB::EventInfo dbei; + 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(pFileName); + 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); + blob.write(dbei); + + db_event_add(ft->m_hContact, &dbei); + } + else { + ft->m_szUserId = szUserId; + ft->m_uniqueId = szMsgId; + } + } +} + +void CTelegramProto::OnSendFile(td::ClientManager::Response &response, void *pUserInfo) +{ + auto *ft = (TG_FILE_REQUEST *)pUserInfo; + + if (response.object->get_id() == TD::message::ID) + ProcessFileMessage(ft, (TD::message *)response.object.get(), false); + else if (response.object->get_id() == TD::messages::ID) { + int i = 0; + auto *pMessages = (TD::messages *)response.object.get(); + for (auto &it : pMessages->messages_) { + ProcessFileMessage(ft, it.get(), i != 0); + i++; + } + } + + ProtoBroadcastAck(ft->m_hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft); + delete ft; +} + HANDLE CTelegramProto::SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles) { auto *pUser = FindUser(GetId(hContact)); @@ -411,7 +488,17 @@ HANDLE CTelegramProto::SendFile(MCONTACT hContact, const wchar_t *szDescription, return nullptr; } - TG_FILE_REQUEST *pTransfer = nullptr; + struct FileItem + { + wchar_t *pwszName; + long iSize; + + FileItem(wchar_t *_1, long _2) : + pwszName(_1), iSize(_2) + {} + }; + + OBJLIST arFiles(1); for (int i = 0; ppszFiles[i] != 0; i++) { struct _stat statbuf; @@ -420,92 +507,90 @@ HANDLE CTelegramProto::SendFile(MCONTACT hContact, const wchar_t *szDescription, continue; } - pTransfer = new TG_FILE_REQUEST(TG_FILE_REQUEST::FILE, 0, ""); - pTransfer->m_fileName = ppszFiles[i]; - if (m_bCompressFiles) - pTransfer->AutoDetectType(); - - pTransfer->m_hContact = hContact; - pTransfer->m_fileSize = statbuf.st_size; - if (mir_wstrlen(szDescription)) - pTransfer->m_wszDescr = szDescription; - - // create a message with embedded file - auto *pMessage = new TD::sendMessage(); + arFiles.insert(new FileItem(ppszFiles[i], statbuf.st_size)); + } + + if (!arFiles.getCount()) { + debugLogA("No files to be sent"); + return nullptr; + } + + if (arFiles.getCount() > 10) { + debugLogA("Too many files to be sent"); + return nullptr; + } + + // create a message with embedded file + TD::sendMessage *pMessage = nullptr; + TD::sendMessageAlbum *pAlbum = nullptr; + + if (arFiles.getCount() == 1) { + pMessage = new TD::sendMessage(); pMessage->chat_id_ = pUser->chatId; + } + else { + pAlbum = new TD::sendMessageAlbum(); + pAlbum->chat_id_ = pUser->chatId; + } + + auto *ft = new TG_FILE_REQUEST(TG_FILE_REQUEST::FILE, 0, 0); + ft->m_hContact = hContact; + ft->m_fileName = arFiles[0].pwszName; + ft->m_fileSize = arFiles[0].iSize; + ft->m_wszDescr = szDescription; + + for (auto &it: arFiles) { + auto iFileType = (m_bCompressFiles) ? AutoDetectType(it->pwszName) : TG_FILE_REQUEST::FILE; auto caption = formatBbcodes(T2Utf(szDescription)); + TD::object_ptr pPart; - if (pTransfer->m_type == TG_FILE_REQUEST::FILE) { + if (iFileType == TG_FILE_REQUEST::FILE) { auto pContent = TD::make_object(); - pContent->document_= makeFile(pTransfer->m_fileName); + pContent->document_= makeFile(it->pwszName); pContent->caption_ = std::move(caption); pContent->thumbnail_ = 0; - pMessage->input_message_content_ = std::move(pContent); + pPart = std::move(pContent); } - else if (pTransfer->m_type == TG_FILE_REQUEST::PICTURE) { + else if (iFileType == TG_FILE_REQUEST::PICTURE) { auto pContent = TD::make_object(); - pContent->photo_ = makeFile(pTransfer->m_fileName); + pContent->photo_ = makeFile(it->pwszName); pContent->thumbnail_ = 0; pContent->caption_ = std::move(caption); pContent->height_ = 0; pContent->width_ = 0; - pMessage->input_message_content_ = std::move(pContent); + pPart = std::move(pContent); } - else if (pTransfer->m_type == TG_FILE_REQUEST::VOICE) { + else if (iFileType == TG_FILE_REQUEST::VOICE) { auto pContent = TD::make_object(); - pContent->voice_note_ = makeFile(pTransfer->m_fileName); + pContent->voice_note_ = makeFile(it->pwszName); pContent->caption_ = std::move(caption); pContent->duration_ = 0; - pMessage->input_message_content_ = std::move(pContent); + pPart = std::move(pContent); } - else if (pTransfer->m_type == TG_FILE_REQUEST::VIDEO) { + else if (iFileType == TG_FILE_REQUEST::VIDEO) { auto pContent = TD::make_object(); - pContent->video_ = makeFile(pTransfer->m_fileName); + pContent->video_ = makeFile(it->pwszName); pContent->caption_ = std::move(caption); pContent->duration_ = 0; pContent->height_ = 0; pContent->width_ = 0; - pMessage->input_message_content_ = std::move(pContent); + pPart = std::move(pContent); } else return nullptr; - SendQuery(pMessage, &CTelegramProto::OnSendFile, pTransfer); + if (pMessage) + pMessage->input_message_content_ = std::move(pPart); + else + pAlbum->input_message_contents_.push_back(std::move(pPart)); } - return pTransfer; -} - -void CTelegramProto::OnSendFile(td::ClientManager::Response &response, void *pUserInfo) -{ - auto *ft = (TG_FILE_REQUEST *)pUserInfo; - - if (response.object->get_id() == TD::message::ID) { - auto *pMsg = (TD::message *)response.object.get(); - ft->m_uniqueId.Format("%lld", pMsg->id_); - - if (auto *pUser = FindChat(pMsg->chat_id_)) { - char szUserId[100]; - if (this->GetGcUserId(pUser, pMsg, szUserId)) - ft->m_szUserId = szUserId; - - auto *pOwnMsg = new TG_OWN_MESSAGE(pUser->hContact, 0, pMsg->id_); - const TD::MessageContent *pBody = pMsg->content_.get(); - switch (pBody->get_id()) { - case TD::messagePhoto::ID: - pOwnMsg->tmpFileId = ((TD::messagePhoto*)pBody)->photo_->sizes_[0]->photo_->id_; - break; - - case TD::messageDocument::ID: - pOwnMsg->tmpFileId = ((TD::messageDocument *)pBody)->document_->document_->id_; - break; - } - m_arOwnMsg.insert(pOwnMsg); - } - } + if (pMessage) + SendQuery(pMessage, &CTelegramProto::OnSendFile, ft); + else + SendQuery(pAlbum, &CTelegramProto::OnSendFile, ft); - ProtoBroadcastAck(ft->m_hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft); - delete ft; + return ft; } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/protocols/Telegram/src/proto.h b/protocols/Telegram/src/proto.h index a11607fd02..f64492c8c2 100644 --- a/protocols/Telegram/src/proto.h +++ b/protocols/Telegram/src/proto.h @@ -73,8 +73,6 @@ struct TG_FILE_REQUEST : public MZeroedObject { delete ofd; } - void AutoDetectType(); - Type m_type; MCONTACT m_hContact = 0; TD::int53 m_fileId, m_fileSize = 0; @@ -250,6 +248,7 @@ class CTelegramProto : public PROTO void ProcessActiveEmoji(TD::updateActiveEmojiReactions *pObj); void ProcessDeleteMessage(TD::updateDeleteMessages *pObj); void ProcessFile(TD::updateFile *pObj); + void ProcessFileMessage(TG_FILE_REQUEST *ft, const TD::message *pMsg, bool); void ProcessGroups(TD::updateChatFolders *pObj); void ProcessMarkRead(TD::updateChatReadInbox *pObj); void ProcessMessage(const TD::message *pMsg); diff --git a/protocols/Telegram/src/utils.cpp b/protocols/Telegram/src/utils.cpp index e6f04f22e2..1ced9f9a6f 100644 --- a/protocols/Telegram/src/utils.cpp +++ b/protocols/Telegram/src/utils.cpp @@ -37,11 +37,11 @@ TD::object_ptr formatBbcodes(const char *pszText) std::wstring str = Utf2T(pszText).get(); for (auto &it : bbCodes) { while (true) { - int i1 = str.find(it.begin); + int i1 = (int)str.find(it.begin); if (i1 == str.npos) break; - int i2 = str.find(it.end, i1); + int i2 = (int)str.find(it.end, i1); if (i2 == str.npos) break; @@ -107,29 +107,30 @@ const char *getName(const TD::usernames *pName) return (pName == nullptr) ? TranslateU("none") : pName->editable_username_.c_str(); } -TD::object_ptr makeFile(const CMStringW &wszFile) +TD::object_ptr makeFile(const wchar_t *pwszFilename) { - std::string szPath = T2Utf(wszFile); + std::string szPath = T2Utf(pwszFilename); return TD::make_object(std::move(szPath)); } -void TG_FILE_REQUEST::AutoDetectType() +TG_FILE_REQUEST::Type AutoDetectType(const wchar_t *pwszFilename) { - if (ProtoGetAvatarFileFormat(m_fileName) != PA_FORMAT_UNKNOWN) { - m_type = this->PICTURE; - return; - } + if (ProtoGetAvatarFileFormat(pwszFilename) != PA_FORMAT_UNKNOWN) + return TG_FILE_REQUEST::PICTURE; - int idx = m_fileName.ReverseFind('.'); - if (idx == -1 || m_fileName.Find('\\', idx) != -1) - return; + CMStringW path(pwszFilename); + int idx = path.ReverseFind('.'); + if (idx == -1 || path.Find('\\', idx) != -1) + return TG_FILE_REQUEST::FILE; - auto wszExt = m_fileName.Right(m_fileName.GetLength() - idx); + auto wszExt = path.Right(path.GetLength() - idx); wszExt.MakeLower(); if (wszExt == L"mp4" || wszExt == L"webm") - m_type = this->VIDEO; + return TG_FILE_REQUEST::VIDEO; else if (wszExt == L"mp3" || wszExt == "ogg" || wszExt == "oga" || wszExt == "wav") - m_type = this->VOICE; + return TG_FILE_REQUEST::VOICE; + + return TG_FILE_REQUEST::FILE; } CMStringW TG_USER::getDisplayName() const diff --git a/protocols/Telegram/src/utils.h b/protocols/Telegram/src/utils.h index 914ac7d1d4..d924a4a137 100644 --- a/protocols/Telegram/src/utils.h +++ b/protocols/Telegram/src/utils.h @@ -2,6 +2,8 @@ const char *getName(const TD::usernames *pName); -TD::object_ptr makeFile(const CMStringW &wszFile); +TD::object_ptr makeFile(const wchar_t *pwszFilename); TD::object_ptr formatBbcodes(const char *pszText); + +TG_FILE_REQUEST::Type AutoDetectType(const wchar_t *pwszFilename); -- cgit v1.2.3