diff options
author | George Hazan <ghazan@miranda.im> | 2020-08-16 14:54:26 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-08-16 14:54:26 +0300 |
commit | afa6a68cca2865a4d974143dc1a289e4f83a5e1c (patch) | |
tree | 60deb305af0207f31fd5f62da5b160c25668dbfb /protocols/ICQ-WIM/src | |
parent | 8e0f6324331fa9ac7425bb155321cbe2726e0161 (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.cpp | 5 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/proto.h | 15 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/server.cpp | 116 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/stdafx.h | 1 |
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> |