diff options
-rw-r--r-- | protocols/ICQ-WIM/src/http.cpp | 1 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/http.h | 6 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/proto.h | 67 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/server.cpp | 92 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/version.h | 2 |
5 files changed, 110 insertions, 58 deletions
diff --git a/protocols/ICQ-WIM/src/http.cpp b/protocols/ICQ-WIM/src/http.cpp index b41a45404b..0ebbabe950 100644 --- a/protocols/ICQ-WIM/src/http.cpp +++ b/protocols/ICQ-WIM/src/http.cpp @@ -336,6 +336,7 @@ RobustReply::RobustReply(NETLIBHTTPREQUEST *pReply) } m_errorCode = (*m_root)["status"]["code"].as_int(); + m_result = &(*m_root)["result"]; m_results = &(*m_root)["results"]; } diff --git a/protocols/ICQ-WIM/src/http.h b/protocols/ICQ-WIM/src/http.h index 9f9270486c..4f3c9cfb59 100644 --- a/protocols/ICQ-WIM/src/http.h +++ b/protocols/ICQ-WIM/src/http.h @@ -65,12 +65,14 @@ class RobustReply { JSONNode *m_root = nullptr; int m_errorCode = 0; - JSONNode* m_results = nullptr; + JSONNode *m_result = nullptr; + JSONNode *m_results = nullptr; public: RobustReply(NETLIBHTTPREQUEST*); ~RobustReply(); - __forceinline JSONNode& results() const { return *m_results; } + __forceinline JSONNode &result() const { return *m_result; } + __forceinline JSONNode &results() const { return *m_results; } __forceinline int error() const { return m_errorCode; } }; diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h index 040796bb87..95ea7b72bb 100644 --- a/protocols/ICQ-WIM/src/proto.h +++ b/protocols/ICQ-WIM/src/proto.h @@ -35,6 +35,7 @@ #define ICQ_APP_ID "ic1nmMjqg7Yu-0hL" #define ICQ_API_SERVER "https://u.icq.net/wim" +#define ICQ_FILE_SERVER "https://u.icq.net/files/api/v1.1" #define ICQ_FAKE_EVENT_ID 0xBABAEB #define ICQ_ROBUST_SERVER "https://u.icq.net/rapi" @@ -228,6 +229,7 @@ class CIcqProto : public PROTO<CIcqProto> void SetServerStatus(int iNewStatus); void ShutdownSession(void); void StartSession(void); + void TryFetchFileInfo(CMStringW &wszText); void CheckAvatarChange(MCONTACT hContact, const JSONNode&); void CheckLastId(MCONTACT hContact, const JSONNode&); @@ -248,38 +250,39 @@ class CIcqProto : public PROTO<CIcqProto> __int64 getId(MCONTACT hContact, const char *szSetting); void setId(MCONTACT hContact, const char *szSetting, __int64 iValue); - void OnAddBuddy(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnAddClient(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnCheckPassword(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnCheckPhone(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnFetchEvents(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnGenToken(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnGetChatInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnGetPermitDeny(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnGetUserHistory(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnGetUserInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnFileContinue(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnFileInit(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnLoginViaPhone(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnNormalizePhone(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnReceiveAvatar(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnSearchResults(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnSendMessage(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnStartSession(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnValidateSms(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - - void ProcessBuddyList(const JSONNode&); - void ProcessDiff(const JSONNode&); - void ProcessEvent(const JSONNode&); - void ProcessGroupChat(const JSONNode&); - void ProcessHistData(const JSONNode&); - void ProcessImState(const JSONNode&); - void ProcessMyInfo(const JSONNode&); - void ProcessNotification(const JSONNode&); - void ProcessPermissions(const JSONNode&); - void ProcessPresence(const JSONNode&); - void ProcessSessionEnd(const JSONNode&); - void ProcessTyping(const JSONNode&); + void OnAddBuddy(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnAddClient(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnCheckPassword(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnCheckPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnFetchEvents(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnFileContinue(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnFileInit(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnFileInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnGenToken(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnGetChatInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnGetPermitDeny(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnGetUserHistory(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnGetUserInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnLoginViaPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnNormalizePhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnReceiveAvatar(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnSearchResults(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnSendMessage(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnValidateSms(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + + void ProcessBuddyList(const JSONNode &pRoot); + void ProcessDiff(const JSONNode &pRoot); + void ProcessEvent(const JSONNode &pRoot); + void ProcessGroupChat(const JSONNode &pRoot); + void ProcessHistData(const JSONNode &pRoot); + void ProcessImState(const JSONNode &pRoot); + void ProcessMyInfo(const JSONNode &pRoot); + void ProcessNotification(const JSONNode &pRoot); + void ProcessPermissions(const JSONNode &pRoot); + void ProcessPresence(const JSONNode &pRoot); + void ProcessSessionEnd(const JSONNode &pRoot); + void ProcessTyping(const JSONNode &pRoot); IcqConn m_ConnPool[CONN_LAST]; CMStringA m_szPassword; diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp index 0e95605bdd..265b6ba632 100644 --- a/protocols/ICQ-WIM/src/server.cpp +++ b/protocols/ICQ-WIM/src/server.cpp @@ -366,7 +366,10 @@ void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNo wszUrl = TranslateT("Unknown sticker"); wszText.Format(L"%s\n%s", TranslateT("User sent a sticker:"), wszUrl.c_str()); } - else wszText = it["text"].as_mstring(); + else { + wszText = it["text"].as_mstring(); + TryFetchFileInfo(wszText); + } int iMsgTime = (bFromHistory) ? it["time"].as_int() : time(0); @@ -464,6 +467,19 @@ void CIcqProto::RetrieveUserInfo(MCONTACT hContact) Push(pReq); } +void CIcqProto::TryFetchFileInfo(CMStringW &wszText) +{ + wszText.TrimRight(); + + if (wszText.Left(26) == L"https://files.icq.net/get/") { + CMStringA szUrl(FORMAT, ICQ_FILE_SERVER "/info/%S/", wszText.Mid(26).c_str()); + auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, szUrl, &CIcqProto::OnFileInfo); + pReq << CHAR_PARAM("aimsid", m_aimsid) << CHAR_PARAM("previews", "600"); + pReq->pUserInfo = &wszText; + ExecuteRequest(pReq); + } +} + AsyncHttpRequest* CIcqProto::UserInfoRequest(MCONTACT hContact) { auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, ICQ_API_SERVER "/presence/get", &CIcqProto::OnGetUserInfo); @@ -584,7 +600,6 @@ void CIcqProto::StartSession() << INT_PARAM("rawMsg", 0) << INT_PARAM("sessionTimeout", 7776000) << INT_PARAM("ts", ts) << CHAR_PARAM("view", "online"); CalcHash(pReq); - Push(pReq); } @@ -593,29 +608,30 @@ void CIcqProto::StartSession() void CIcqProto::OnAddBuddy(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) { JsonReply root(pReply); - if (root.error() == 200) { - CMStringW wszId = getMStringW(pReq->hContact, DB_KEY_ID); - for (auto &it : root.data()["results"]) { - if (it["buddy"].as_mstring() != wszId) - continue; - - int iResultCode = it["resultCode"].as_int(); - if (iResultCode != 0) { - debugLogA("Contact %d failed to add: error %d", pReq->hContact, iResultCode); - - POPUPDATAW Popup = {}; - Popup.lchIcon = IcoLib_GetIconByHandle(Skin_GetIconHandle(SKINICON_ERROR)); - wcsncpy_s(Popup.lpwzText, TranslateT("Buddy addition failed"), _TRUNCATE); - wcsncpy_s(Popup.lpwzContactName, Clist_GetContactDisplayName(pReq->hContact), _TRUNCATE); - Popup.iSeconds = 20; - PUAddPopupW(&Popup); - - // Contact_RemoveFromList(pReq->hContact); - } + if (root.error() != 200) + return; + + CMStringW wszId = getMStringW(pReq->hContact, DB_KEY_ID); + for (auto &it : root.data()["results"]) { + if (it["buddy"].as_mstring() != wszId) + continue; + + int iResultCode = it["resultCode"].as_int(); + if (iResultCode != 0) { + debugLogA("Contact %d failed to add: error %d", pReq->hContact, iResultCode); + + POPUPDATAW Popup = {}; + Popup.lchIcon = IcoLib_GetIconByHandle(Skin_GetIconHandle(SKINICON_ERROR)); + wcsncpy_s(Popup.lpwzText, TranslateT("Buddy addition failed"), _TRUNCATE); + wcsncpy_s(Popup.lpwzContactName, Clist_GetContactDisplayName(pReq->hContact), _TRUNCATE); + Popup.iSeconds = 20; + PUAddPopupW(&Popup); - RetrieveUserInfo(pReq->hContact); - Contact_PutOnList(pReq->hContact); + // Contact_RemoveFromList(pReq->hContact); } + + RetrieveUserInfo(pReq->hContact); + Contact_PutOnList(pReq->hContact); } } @@ -723,6 +739,8 @@ void CIcqProto::OnFileContinue(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld Push(pReq); // Send the same message to myself + TryFetchFileInfo(wszUrl); + T2Utf msgText(wszUrl); PROTORECVEVENT recv = {}; recv.flags = PREF_CREATEREAD | PREF_SENT; @@ -780,6 +798,34 @@ void CIcqProto::OnFileInit(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld) ProtoBroadcastAck(pTransfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, pTransfer, (LPARAM)&pTransfer->pfts); } +void CIcqProto::OnFileInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) +{ + CMStringW *wszText = (CMStringW *)pReq->pUserInfo; + + RobustReply root(pReply); + if (root.error() != 200) + return; + + wszText->Empty(); + auto &data = root.result(); + CMStringW tmp(data["extra"]["file_type"].as_mstring()); + wszText->AppendFormat(L"%s\r\n", (tmp == "image") ? TranslateT("Image received:") : TranslateT("File received")); + + tmp = data["info"]["file_name"].as_mstring(); + if (!tmp.IsEmpty()) + wszText->AppendFormat(L"%s: %s\r\n", TranslateT("File name"), tmp.c_str()); + + tmp = data["info"]["dlink"].as_mstring(); + if (!tmp.IsEmpty()) + wszText->AppendFormat(L"%s: %s\r\n", TranslateT("URL"), tmp.c_str()); + + if (data["info"]["has_previews"].as_bool()) { + tmp = data["previews"]["600"].as_mstring(); + if (!tmp.IsEmpty()) + wszText->AppendFormat(L"%s: %s\r\n", TranslateT("Preview"), tmp.c_str()); + } +} + void CIcqProto::OnGenToken(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*) { RobustReply root(pReply); diff --git a/protocols/ICQ-WIM/src/version.h b/protocols/ICQ-WIM/src/version.h index a35cfd1aa8..e5a6a0cc92 100644 --- a/protocols/ICQ-WIM/src/version.h +++ b/protocols/ICQ-WIM/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 95 #define __RELEASE_NUM 11 -#define __BUILD_NUM 7 +#define __BUILD_NUM 8 #include <stdver.h> |