summaryrefslogtreecommitdiff
path: root/protocols/ICQ-WIM/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-08-16 14:54:26 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-08-16 14:54:26 +0300
commitafa6a68cca2865a4d974143dc1a289e4f83a5e1c (patch)
tree60deb305af0207f31fd5f62da5b160c25668dbfb /protocols/ICQ-WIM/src
parent8e0f6324331fa9ac7425bb155321cbe2726e0161 (diff)
SmileyAdd:
- major update for custom smileys APIs (cause we have no MSN, there's no need to save MCONTACT for custom smileys); - added path type = 2 to download whole folder for custom smileys; - fixes #2524 (ICQ: стикеры должны приходить как custom smileys, а не как передачи файлов); - fixes #2533 (SmileyAdd не всегда распознаёт стикеры); - fixes #2532 (Полученные стикеры пропадают при переоткрытии окна); - version bump
Diffstat (limited to 'protocols/ICQ-WIM/src')
-rw-r--r--protocols/ICQ-WIM/src/proto.cpp5
-rw-r--r--protocols/ICQ-WIM/src/proto.h15
-rw-r--r--protocols/ICQ-WIM/src/server.cpp116
-rw-r--r--protocols/ICQ-WIM/src/stdafx.h1
4 files changed, 113 insertions, 24 deletions
diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp
index 77258fa674..30e98e9008 100644
--- a/protocols/ICQ-WIM/src/proto.cpp
+++ b/protocols/ICQ-WIM/src/proto.cpp
@@ -130,6 +130,11 @@ CIcqProto::~CIcqProto()
void CIcqProto::OnModulesLoaded()
{
HookProtoEvent(ME_USERINFO_INITIALISE, &CIcqProto::OnUserInfoInit);
+
+ // load custom smilies
+ CMStringW wszPath(FORMAT, L"%s\\%S\\Stickers\\*.png", VARSW(L"%miranda_avatarcache%").get(), m_szModuleName);
+ SMADD_CONT cont = { 2, m_szModuleName, wszPath };
+ CallService(MS_SMILEYADD_LOADCONTACTSMILEYS, 0, LPARAM(&cont));
}
void CIcqProto::OnShutdown()
diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h
index 81b8c82789..9bfb80c4a5 100644
--- a/protocols/ICQ-WIM/src/proto.h
+++ b/protocols/ICQ-WIM/src/proto.h
@@ -69,6 +69,20 @@ enum ChatMenuItems
IDM_INVITE = 10, IDM_LEAVE
};
+struct IcqFileInfo
+{
+ IcqFileInfo(const std::string &pszUrl, const CMStringW &pwszDescr, DWORD dwSize) :
+ szUrl(pszUrl.c_str()),
+ wszDescr(pwszDescr),
+ dwFileSize(dwSize)
+ {}
+
+ CMStringA szUrl;
+ CMStringW wszDescr;
+ DWORD dwFileSize;
+ bool bIsSticker = false;
+};
+
struct IcqGroup
{
IcqGroup(int _p1, const CMStringW &_p2) :
@@ -282,6 +296,7 @@ class CIcqProto : public PROTO<CIcqProto>
void OnGenToken(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
void OnGetChatInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
void OnGetPermitDeny(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
+ void OnGetSticker(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
void OnGetUserHistory(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
void OnGetUserInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
void OnLoginViaPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq);
diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp
index 14e7164477..3c27025714 100644
--- a/protocols/ICQ-WIM/src/server.cpp
+++ b/protocols/ICQ-WIM/src/server.cpp
@@ -441,15 +441,55 @@ void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNo
if (idx != -1)
wszUrl.Truncate(idx);
- CMStringA szUrl(FORMAT, ICQ_FILE_SERVER "/info/%S/", wszUrl.c_str());
- auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, szUrl, &CIcqProto::OnFileInfo);
- pReq->hContact = hContact;
- pReq->pUserInfo = (void*)iMsgTime;
- pReq << CHAR_PARAM("aimsid", m_aimsid) << CHAR_PARAM("previews", "600");
- Push(pReq);
-
- MarkAsRead(hContact);
- return;
+ // is it already downloaded sticker?
+ CMStringW wszLoadedPath(FORMAT, L"%s\\%S\\Stickers\\STK{%s}.png", VARSW(L"%miranda_avatarcache%").get(), m_szModuleName, wszUrl.c_str());
+ if (!_waccess(wszLoadedPath, 0))
+ wszText.Format(L"STK{%s}", wszUrl.c_str());
+ else {
+ // download file info
+ IcqFileInfo *pFileInfo = nullptr;
+
+ CMStringA szUrl(FORMAT, ICQ_FILE_SERVER "/info/%S/", wszUrl.c_str());
+ auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, szUrl, &CIcqProto::OnFileInfo);
+ pReq->hContact = hContact;
+ pReq->pUserInfo = &pFileInfo;
+ pReq << CHAR_PARAM("aimsid", m_aimsid) << CHAR_PARAM("previews", "192,600,xlarge");
+ if (!ExecuteRequest(pReq))
+ return;
+
+ // is it a sticker?
+ if (pFileInfo->bIsSticker) {
+ auto *pNew = new AsyncHttpRequest(CONN_NONE, REQUEST_GET, pFileInfo->szUrl, &CIcqProto::OnGetSticker);
+ pNew->flags |= NLHRF_NODUMP | NLHRF_SSL | NLHRF_HTTP11 | NLHRF_REDIRECT;
+ pNew->pUserInfo = wszUrl.GetBuffer();
+ pNew->AddHeader("Sec-Fetch-User", "?1");
+ pNew->AddHeader("Sec-Fetch-Site", "cross-site");
+ pNew->AddHeader("Sec-Fetch-Mode", "navigate");
+ if (!ExecuteRequest(pNew))
+ return;
+
+ wszText.Format(L"STK{%s}", wszUrl.c_str());
+ delete pFileInfo;
+ }
+ else {
+ // detach a file transfer
+ auto *ft = new IcqFileTransfer(hContact, pFileInfo->szUrl);
+ ft->pfts.totalBytes = ft->pfts.currentFileSize = pFileInfo->dwFileSize;
+ ft->pfts.szCurrentFile.w = ft->m_wszFileName.GetBuffer();
+
+ PROTORECVFILE pre = {};
+ pre.dwFlags = PRFF_UNICODE;
+ pre.fileCount = 1;
+ pre.timestamp = iMsgTime;
+ pre.files.w = &ft->m_wszShortName;
+ pre.descr.w = pFileInfo->wszDescr;
+ pre.lParam = (LPARAM)ft;
+ ProtoChainRecvFile(hContact, &pre);
+
+ delete pFileInfo;
+ return;
+ }
+ }
}
// suppress notifications for already loaded/processed messages
@@ -844,34 +884,62 @@ void CIcqProto::OnFileInit(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld)
}
/////////////////////////////////////////////////////////////////////////////////////////
+// Support for stickers
+
+void CIcqProto::OnGetSticker(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+{
+ if (pReply->resultCode != 200) {
+ debugLogA("Error getting sticker: %d", pReply->resultCode);
+ return;
+ }
+
+ CMStringW wszPath(FORMAT, L"%s\\%S\\Stickers", VARSW(L"%miranda_avatarcache%").get(), m_szModuleName);
+ CreateDirectoryTreeW(wszPath);
+
+ CMStringW wszFileName(FORMAT, L"%s\\STK{%s}.png", wszPath.c_str(), pReq->pUserInfo);
+ FILE *out = _wfopen(wszFileName, L"wb");
+ fwrite(pReply->pData, 1, pReply->dataLength, out);
+ fclose(out);
+
+ SMADD_CONT cont = { 1, m_szModuleName, wszFileName };
+ CallService(MS_SMILEYADD_LOADCONTACTSMILEYS, 0, LPARAM(&cont));
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// File info request
void CIcqProto::OnFileInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
{
+ IcqFileInfo **res = (IcqFileInfo **)pReq->pUserInfo;
+ *res = nullptr;
+
RobustReply root(pReply);
if (root.error() != 200)
return;
- auto &data = root.result()["info"];
- std::string szUrl(data["dlink"].as_string());
+ auto &pData = root.result();
+ auto &pInfo = pData["info"] ;
+ std::string szUrl(pInfo["dlink"].as_string());
if (szUrl.empty())
return;
- mir_urlDecode(&*szUrl.begin());
+ MarkAsRead(pReq->hContact);
- CMStringW wszDescr(data["file_name"].as_mstring());
+ bool bIsSticker;
+ CMStringW wszDescr(pInfo["file_name"].as_mstring());
+ if (!mir_wstrncmp(wszDescr, L"dnld", 4)) {
+ bIsSticker = true;
- auto *ft = new IcqFileTransfer(pReq->hContact, szUrl.c_str());
- ft->pfts.totalBytes = ft->pfts.currentFileSize = data["file_size"].as_int();
- ft->pfts.szCurrentFile.w = ft->m_wszFileName.GetBuffer();
+ std::string szPreview = pData["previews"]["192"].as_string();
+ if (!szPreview.empty())
+ szUrl = szPreview;
+ }
+ else bIsSticker = false;
+
+ mir_urlDecode(&*szUrl.begin());
- PROTORECVFILE pre = { 0 };
- pre.dwFlags = PRFF_UNICODE;
- pre.fileCount = 1;
- pre.timestamp = DWORD_PTR(pReq->pUserInfo);
- pre.files.w = &ft->m_wszShortName;
- pre.descr.w = wszDescr;
- pre.lParam = (LPARAM)ft;
- ProtoChainRecvFile(pReq->hContact, &pre);
+ *res = new IcqFileInfo(szUrl, wszDescr, pInfo["file_size"].as_int());
+ res[0]->bIsSticker = bIsSticker;
}
void CIcqProto::OnFileRecv(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
diff --git a/protocols/ICQ-WIM/src/stdafx.h b/protocols/ICQ-WIM/src/stdafx.h
index 6fba501966..56b81b0dae 100644
--- a/protocols/ICQ-WIM/src/stdafx.h
+++ b/protocols/ICQ-WIM/src/stdafx.h
@@ -62,6 +62,7 @@
#include <m_options.h>
#include <m_popup.h>
#include <m_skin.h>
+#include <m_smileyadd.h>
#include <m_system.h>
#include <m_timezones.h>
#include <m_userinfo.h>