summaryrefslogtreecommitdiff
path: root/protocols/Icq10
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2018-12-24 19:48:28 +0300
committerGeorge Hazan <ghazan@miranda.im>2018-12-24 19:48:28 +0300
commit7f5b936071e3a02fee7f7156157f2d0f776bb395 (patch)
tree39ea508e39ebced43095885a67a747eba2eff8a3 /protocols/Icq10
parent53aaf4d4c34318d5953ca55d879e7153a7a30098 (diff)
Icq10: more avatar processing services
Diffstat (limited to 'protocols/Icq10')
-rw-r--r--protocols/Icq10/src/proto.cpp5
-rw-r--r--protocols/Icq10/src/proto.h10
-rw-r--r--protocols/Icq10/src/server.cpp106
-rw-r--r--protocols/Icq10/src/utils.cpp72
4 files changed, 152 insertions, 41 deletions
diff --git a/protocols/Icq10/src/proto.cpp b/protocols/Icq10/src/proto.cpp
index 8e46820d6f..95ac9478da 100644
--- a/protocols/Icq10/src/proto.cpp
+++ b/protocols/Icq10/src/proto.cpp
@@ -39,6 +39,11 @@ CIcqProto::CIcqProto(const char* aProtoName, const wchar_t* aUserName) :
m_arCache(20, NumericKeySortT),
m_evRequestsQueue(CreateEvent(nullptr, FALSE, FALSE, nullptr))
{
+ CreateProtoService(PS_GETAVATARINFO, &CIcqProto::GetAvatarInfo);
+ CreateProtoService(PS_GETMYAVATAR, &CIcqProto::GetAvatar);
+ CreateProtoService(PS_GETAVATARCAPS, &CIcqProto::GetAvatarCaps);
+ CreateProtoService(PS_SETMYAVATAR, &CIcqProto::SetAvatar);
+
CMStringW descr(FORMAT, TranslateT("%s server connection"), m_tszUserName);
NETLIBUSER nlu = {};
diff --git a/protocols/Icq10/src/proto.h b/protocols/Icq10/src/proto.h
index a3a354feb3..41b816067b 100644
--- a/protocols/Icq10/src/proto.h
+++ b/protocols/Icq10/src/proto.h
@@ -59,7 +59,9 @@ class CIcqProto : public PROTO<CIcqProto>
void OnReceiveAvatar(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
void OnStartSession(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void ProcessBuddyList(const JSONNode&);
void ProcessEvent(const JSONNode&);
+ void ProcessMyInfo(const JSONNode&);
HNETLIBCONN m_ConnPool[CONN_LAST];
CMStringA m_szSessionKey;
@@ -95,6 +97,14 @@ class CIcqProto : public PROTO<CIcqProto>
void __cdecl ServerThread(void*);
//////////////////////////////////////////////////////////////////////////////////////
+ // services
+
+ INT_PTR __cdecl GetAvatar(WPARAM, LPARAM);
+ INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
+ INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
+ INT_PTR __cdecl SetAvatar(WPARAM, LPARAM);
+
+ //////////////////////////////////////////////////////////////////////////////////////
// PROTO_INTERFACE
MCONTACT AddToList( int flags, PROTOSEARCHRESULT *psr) override;
diff --git a/protocols/Icq10/src/server.cpp b/protocols/Icq10/src/server.cpp
index b95ab64b14..bde7ef3319 100644
--- a/protocols/Icq10/src/server.cpp
+++ b/protocols/Icq10/src/server.cpp
@@ -209,60 +209,84 @@ void CIcqProto::OnReceiveAvatar(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pRe
/////////////////////////////////////////////////////////////////////////////////////////
-void CIcqProto::ProcessEvent(const JSONNode &ev)
+void CIcqProto::ProcessBuddyList(const JSONNode &ev)
{
- CMStringW szType = ev["type"].as_mstring();
- if (szType == L"buddylist") {
- for (auto &it : ev["eventData"]["groups"]) {
- CMStringW szGroup = it["name"].as_mstring();
- Clist_GroupCreate(0, szGroup);
-
- for (auto &buddy : it["buddies"]) {
- DWORD dwUin = _wtol(buddy["aimId"].as_mstring());
- MCONTACT hContact = FindContactByUIN(dwUin);
- if (hContact == 0) {
- hContact = db_add_contact();
- Proto_AddToContact(hContact, m_szModuleName);
- setDword(hContact, "UIN", dwUin);
- {
- mir_cslock l(m_csCache);
- m_arCache.insert(new IcqCacheItem(dwUin, hContact));
- }
+ for (auto &it : ev["groups"]) {
+ CMStringW szGroup = it["name"].as_mstring();
+ Clist_GroupCreate(0, szGroup);
+
+ for (auto &buddy : it["buddies"]) {
+ DWORD dwUin = _wtol(buddy["aimId"].as_mstring());
+ MCONTACT hContact = FindContactByUIN(dwUin);
+ if (hContact == 0) {
+ hContact = db_add_contact();
+ Proto_AddToContact(hContact, m_szModuleName);
+ setDword(hContact, "UIN", dwUin);
+ {
+ mir_cslock l(m_csCache);
+ m_arCache.insert(new IcqCacheItem(dwUin, hContact));
}
+ }
- CMStringW wszNick(buddy["friendly"].as_mstring());
- if (!wszNick.IsEmpty())
- setWString(hContact, "Nick", wszNick);
-
- setDword(hContact, "Status", StatusFromString(buddy["state"].as_mstring()));
+ CMStringW wszNick(buddy["friendly"].as_mstring());
+ if (!wszNick.IsEmpty())
+ setWString(hContact, "Nick", wszNick);
- int lastLogin = buddy["lastseen"].as_int();
- if (lastLogin)
- setDword(hContact, "LoginTS", lastLogin);
+ setDword(hContact, "Status", StatusFromString(buddy["state"].as_mstring()));
- CMStringW wszStatus(buddy["statusMsg"].as_mstring());
- if (wszStatus.IsEmpty())
- db_unset(hContact, "CList", "StatusMsg");
- else
- db_set_ws(hContact, "CList", "StatusMsg", wszStatus);
+ int lastLogin = buddy["lastseen"].as_int();
+ if (lastLogin)
+ setDword(hContact, "LoginTS", lastLogin);
- CMStringW wszIconId(buddy["iconId"].as_mstring());
- CMStringW oldIconID(getMStringW(hContact, "IconId"));
- if (wszIconId != oldIconID) {
- setWString(hContact, "IconId", wszIconId);
+ CMStringW wszStatus(buddy["statusMsg"].as_mstring());
+ if (wszStatus.IsEmpty())
+ db_unset(hContact, "CList", "StatusMsg");
+ else
+ db_set_ws(hContact, "CList", "StatusMsg", wszStatus);
- CMStringA szUrl(buddy["buddyIcon"].as_mstring());
- auto *p = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, szUrl, &CIcqProto::OnReceiveAvatar);
- p->pUserInfo = (void*)hContact;
- Push(p);
- }
+ CMStringW wszIconId(buddy["iconId"].as_mstring());
+ CMStringW oldIconID(getMStringW(hContact, "IconId"));
+ if (wszIconId != oldIconID) {
+ setWString(hContact, "IconId", wszIconId);
- db_set_ws(hContact, "CList", "Group", szGroup);
+ CMStringA szUrl(buddy["buddyIcon"].as_mstring());
+ auto *p = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, szUrl, &CIcqProto::OnReceiveAvatar);
+ p->pUserInfo = (void*)hContact;
+ Push(p);
}
+
+ db_set_ws(hContact, "CList", "Group", szGroup);
}
}
}
+void CIcqProto::ProcessEvent(const JSONNode &ev)
+{
+ const JSONNode &pData = ev["eventData"];
+ CMStringW szType = ev["type"].as_mstring();
+ if (szType == L"buddylist")
+ ProcessBuddyList(pData);
+ else if (szType == L"myInfo")
+ ProcessMyInfo(pData);
+
+}
+
+void CIcqProto::ProcessMyInfo(const JSONNode &ev)
+{
+ CMStringW wszNick(ev["friendly"].as_mstring());
+ if (!wszNick.IsEmpty())
+ setWString("Nick", wszNick);
+
+ CMStringW wszIconId(ev["iconId"].as_mstring());
+ CMStringW oldIconID(getMStringW("IconId"));
+ if (wszIconId != oldIconID) {
+ setWString("IconId", wszIconId);
+
+ CMStringA szUrl(ev["buddyIcon"].as_mstring());
+ Push(new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, szUrl, &CIcqProto::OnReceiveAvatar));
+ }
+}
+
void CIcqProto::OnFetchEvents(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
diff --git a/protocols/Icq10/src/utils.cpp b/protocols/Icq10/src/utils.cpp
index 2dec6c800c..0ed21af36c 100644
--- a/protocols/Icq10/src/utils.cpp
+++ b/protocols/Icq10/src/utils.cpp
@@ -34,6 +34,9 @@ MCONTACT CIcqProto::FindContactByUIN(DWORD dwUin)
return (p) ? p->m_hContact : 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
+// Avatars
+
void CIcqProto::GetAvatarFileName(MCONTACT hContact, wchar_t* pszDest, size_t cbLen)
{
int tPathLen = mir_snwprintf(pszDest, cbLen, L"%s\\%S", VARSW(L"%miranda_avatarcache%"), m_szModuleName);
@@ -49,6 +52,75 @@ void CIcqProto::GetAvatarFileName(MCONTACT hContact, wchar_t* pszDest, size_t cb
mir_snwprintf(pszDest + tPathLen, MAX_PATH - tPathLen, L"%s%s", wszFileName.c_str(), szFileType);
}
+INT_PTR __cdecl CIcqProto::GetAvatar(WPARAM wParam, LPARAM lParam)
+{
+ wchar_t *buf = (wchar_t*)wParam;
+ int size = (int)lParam;
+ if (buf == nullptr || size <= 0)
+ return -1;
+
+ GetAvatarFileName(0, buf, size);
+ return 0;
+}
+
+INT_PTR __cdecl CIcqProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
+{
+ switch (wParam) {
+ case AF_MAXSIZE:
+ ((POINT*)lParam)->x = -1;
+ ((POINT*)lParam)->y = -1;
+ return 0;
+
+ case AF_MAXFILESIZE:
+ return 0;
+
+ case AF_PROPORTION:
+ return PIP_NONE;
+
+ case AF_FORMATSUPPORTED: // nobody
+ return 1;
+
+ case AF_DELAYAFTERFAIL:
+ return 10 * 60 * 1000;
+
+ case AF_DONTNEEDDELAYS: // We need delays because of larger friend lists
+ return 0;
+
+ case AF_ENABLED:
+ case AF_FETCHIFPROTONOTVISIBLE:
+ case AF_FETCHIFCONTACTOFFLINE:
+ return 1;
+ }
+ return 0;
+}
+
+INT_PTR __cdecl CIcqProto::GetAvatarInfo(WPARAM, LPARAM lParam)
+{
+ PROTO_AVATAR_INFORMATION* pai = (PROTO_AVATAR_INFORMATION*)lParam;
+
+ ptrW szIconId(getWStringA(pai->hContact, "IconId"));
+ if (szIconId == nullptr) {
+ debugLogA("No avatar");
+ return GAIR_NOAVATAR;
+ }
+
+ GetAvatarFileName(pai->hContact, pai->filename, _countof(pai->filename));
+ pai->format = getByte(pai->hContact, "AvatarType", 0);
+
+ if (::_waccess(pai->filename, 0) == 0)
+ return GAIR_SUCCESS;
+
+ debugLogA("No avatar");
+ return GAIR_NOAVATAR;
+}
+
+INT_PTR __cdecl CIcqProto::SetAvatar(WPARAM, LPARAM)
+{
+ return 1; // TODO
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
int StatusFromString(const CMStringW &wszStatus)
{
if (wszStatus == "online")