summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/Telegram/src/avatars.cpp2
-rw-r--r--protocols/Telegram/src/proto.cpp221
-rw-r--r--protocols/Telegram/src/proto.h3
-rw-r--r--protocols/Telegram/src/utils.cpp31
-rw-r--r--protocols/Telegram/src/utils.h4
5 files changed, 174 insertions, 87 deletions
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<FileItem> 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<TD::InputMessageContent> pPart;
- if (pTransfer->m_type == TG_FILE_REQUEST::FILE) {
+ if (iFileType == TG_FILE_REQUEST::FILE) {
auto pContent = TD::make_object<TD::inputMessageDocument>();
- 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<TD::inputMessagePhoto>();
- 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<TD::inputMessageVoiceNote>();
- 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<TD::inputMessageVideo>();
- 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<CTelegramProto>
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<TD::formattedText> 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<TD::inputFileLocal> makeFile(const CMStringW &wszFile)
+TD::object_ptr<TD::inputFileLocal> makeFile(const wchar_t *pwszFilename)
{
- std::string szPath = T2Utf(wszFile);
+ std::string szPath = T2Utf(pwszFilename);
return TD::make_object<TD::inputFileLocal>(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<TD::inputFileLocal> makeFile(const CMStringW &wszFile);
+TD::object_ptr<TD::inputFileLocal> makeFile(const wchar_t *pwszFilename);
TD::object_ptr<TD::formattedText> formatBbcodes(const char *pszText);
+
+TG_FILE_REQUEST::Type AutoDetectType(const wchar_t *pwszFilename);