summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-01-31 19:32:14 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-01-31 19:32:22 +0300
commit48571763be1aec9d9ac10934c30797cc6d5081e5 (patch)
tree1480bbe88ec62dbb8d4317d0c905a79564adb937
parent131a0bbaf24630bcc4f516ae3c8f96a0d39dc2eb (diff)
ICQ-WIM: support for Ignore
-rw-r--r--protocols/ICQ-WIM/src/main.cpp51
-rw-r--r--protocols/ICQ-WIM/src/proto.cpp45
-rw-r--r--protocols/ICQ-WIM/src/proto.h18
-rw-r--r--protocols/ICQ-WIM/src/server.cpp55
4 files changed, 127 insertions, 42 deletions
diff --git a/protocols/ICQ-WIM/src/main.cpp b/protocols/ICQ-WIM/src/main.cpp
index 3de14ce81f..6050cae4d6 100644
--- a/protocols/ICQ-WIM/src/main.cpp
+++ b/protocols/ICQ-WIM/src/main.cpp
@@ -54,20 +54,67 @@ CMPlugin g_plugin;
/////////////////////////////////////////////////////////////////////////////////////////
-int ModuleLoad(WPARAM, LPARAM)
+static int OnContactMenu(WPARAM hContact, LPARAM lParam)
+{
+ Menu_ShowItem(g_plugin.m_hmiRoot, false);
+
+ CIcqProto *proto = CMPlugin::getInstance(hContact);
+ return proto ? proto->OnContactMenu(hContact, lParam) : 0;
+}
+
+static INT_PTR ICQPermitDeny(WPARAM hContact, LPARAM, LPARAM bAllow)
+{
+ CIcqProto *proto = CMPlugin::getInstance(hContact);
+ if (proto)
+ proto->SetPermitDeny(hContact, bAllow != 0);
+ return 0;
+}
+
+static int ModuleLoad(WPARAM, LPARAM)
{
g_bPopupService = ServiceExists(MS_POPUP_ADDPOPUPT);
g_bMessageState = ServiceExists(MS_MESSAGESTATE_UPDATE);
return 0;
}
+static int OnModulesLoaded(WPARAM, LPARAM)
+{
+ ModuleLoad(0, 0);
+
+ // init menus
+ CMenuItem mi(&g_plugin);
+
+ SET_UID(mi, 0x9cd3a933, 0x3bd5, 0x4d1c, 0xbd, 0xf1, 0xa8, 0xf9, 0xbf, 0xf0, 0xd7, 0x28);
+ mi.position = 100000;
+ mi.name.a = "ICQ";
+ mi.hIcolibItem = Skin_LoadProtoIcon(g_plugin.getModule(), ID_STATUS_ONLINE);
+ g_plugin.m_hmiRoot = Menu_AddContactMenuItem(&mi);
+
+ mi.flags = CMIF_UNMOVABLE;
+ mi.root = g_plugin.m_hmiRoot;
+ mi.name.a = LPGEN("Ignore");
+ mi.hIcolibItem = Skin_GetIconHandle(SKINICON_AUTH_REVOKE);
+ mi.pszService = "ICQ/Ignore";
+ g_plugin.m_hmiIgnore = Menu_AddContactMenuItem(&mi);
+ CreateServiceFunctionParam(mi.pszService, ICQPermitDeny, 0);
+
+ mi.name.a = LPGEN("Allow");
+ mi.hIcolibItem = Skin_GetIconHandle(SKINICON_AUTH_ADD);
+ mi.pszService = "ICQ/RemoveIgnore";
+ g_plugin.m_hmiAllow = Menu_AddContactMenuItem(&mi);
+ CreateServiceFunctionParam(mi.pszService, ICQPermitDeny, 1);
+
+ HookEvent(ME_CLIST_PREBUILDCONTACTMENU, OnContactMenu);
+ return 0;
+}
+
int CMPlugin::Load()
{
g_hwndHeartbeat = CreateWindowEx(0, L"STATIC", nullptr, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr, nullptr);
HookEvent(ME_SYSTEM_MODULELOAD, ModuleLoad);
HookEvent(ME_SYSTEM_MODULEUNLOAD, ModuleLoad);
- HookEvent(ME_SYSTEM_MODULESLOADED, ModuleLoad);
+ HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
return 0;
};
diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp
index 3520584a24..8a9675530f 100644
--- a/protocols/ICQ-WIM/src/proto.cpp
+++ b/protocols/ICQ-WIM/src/proto.cpp
@@ -149,6 +149,19 @@ INT_PTR CIcqProto::UploadGroups(WPARAM, LPARAM)
/////////////////////////////////////////////////////////////////////////////////////////
+int CIcqProto::OnContactMenu(WPARAM hContact, LPARAM)
+{
+ Menu_ShowItem(g_plugin.m_hmiRoot, true);
+ Menu_ModifyItem(g_plugin.m_hmiRoot, nullptr, Skin_LoadProtoIcon(GetContactProto(hContact), ID_STATUS_ONLINE));
+
+ bool bIgnorable = getDword(hContact, "ApparentMode") != ID_STATUS_OFFLINE;
+ Menu_ShowItem(g_plugin.m_hmiAllow, !bIgnorable);
+ Menu_ShowItem(g_plugin.m_hmiIgnore, bIgnorable);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
void CIcqProto::MarkReadTimerProc(HWND hwnd, UINT, UINT_PTR id, DWORD)
{
CIcqProto *ppro = (CIcqProto*)id;
@@ -258,38 +271,6 @@ int CIcqProto::AuthRequest(MCONTACT hContact, const wchar_t* szMessage)
}
////////////////////////////////////////////////////////////////////////////////////////
-// PS_FileAllow - starts a file transfer
-
-HANDLE CIcqProto::FileAllow(MCONTACT, HANDLE, const wchar_t*)
-{
- return nullptr; // Failure
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_FileCancel - cancels a file transfer
-
-int CIcqProto::FileCancel(MCONTACT, HANDLE)
-{
- return 1; // Failure
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_FileDeny - denies a file transfer
-
-int CIcqProto::FileDeny(MCONTACT, HANDLE, const wchar_t*)
-{
- return 1; // Invalid contact
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-// PS_FileResume - processes file renaming etc
-
-int CIcqProto::FileResume(HANDLE, int*, const wchar_t**)
-{
- return 1; // Failure
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
// GetCaps - return protocol capabilities bits
INT_PTR CIcqProto::GetCaps(int type, MCONTACT)
diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h
index 827718e03e..5e0609a4c1 100644
--- a/protocols/ICQ-WIM/src/proto.h
+++ b/protocols/ICQ-WIM/src/proto.h
@@ -52,6 +52,7 @@ struct IcqCacheItem
DWORD m_uin;
MCONTACT m_hContact;
bool m_bInList = false;
+ int m_iApparentMode;
};
struct IcqOwnMessage
@@ -133,6 +134,7 @@ class CIcqProto : public PROTO<CIcqProto>
MCONTACT CheckOwnMessage(const CMStringA &reqId, const CMStringA &msgId, bool bRemove);
void CheckPassword(void);
void ConnectionFailed(int iReason, int iErrorCode = 0);
+ void GetPermitDeny(void);
void MoveContactToGroup(MCONTACT hContact, const wchar_t *pwszGroup, const wchar_t *pwszNewGroup);
void RetrieveUserHistory(MCONTACT, __int64 startMsgId, __int64 endMsgId);
void RetrieveUserInfo(MCONTACT);
@@ -156,13 +158,14 @@ 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 OnGetChatInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnGetPermitDeny(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
void OnGetUserHistory(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
void OnGetUserInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
void OnFileContinue(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
@@ -182,6 +185,7 @@ class CIcqProto : public PROTO<CIcqProto>
void ProcessHistData(const JSONNode&);
void ProcessImState(const JSONNode&);
void ProcessMyInfo(const JSONNode&);
+ void ProcessPermissions(const JSONNode&);
void ProcessPresence(const JSONNode&);
void ProcessTyping(const JSONNode&);
@@ -269,12 +273,7 @@ class CIcqProto : public PROTO<CIcqProto>
MCONTACT AddToList( int flags, PROTOSEARCHRESULT *psr) override;
int AuthRequest(MCONTACT hContact, const wchar_t *szMessage) override;
-
- HANDLE FileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szPath) override;
- int FileCancel(MCONTACT hContact, HANDLE hTransfer) override;
- int FileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szReason) override;
- int FileResume( HANDLE hTransfer, int *action, const wchar_t **szFilename) override;
-
+
INT_PTR GetCaps(int type, MCONTACT hContact = NULL) override;
int GetInfo(MCONTACT hContact, int infoType) override;
@@ -307,12 +306,17 @@ public:
CMOption<BYTE> m_bHideGroupchats; // don't pop up group chat windows on startup
CMStringA GetUserId(MCONTACT);
+
+ int __cdecl OnContactMenu(WPARAM, LPARAM);
+ void SetPermitDeny(MCONTACT hContact, bool bAllow);
};
struct CMPlugin : public ACCPROTOPLUGIN<CIcqProto>
{
CMPlugin();
+ HGENMENU m_hmiRoot, m_hmiIgnore, m_hmiAllow;
+
int Load() override;
int Unload() override;
};
diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp
index 5c6ec298ae..a392baf454 100644
--- a/protocols/ICQ-WIM/src/server.cpp
+++ b/protocols/ICQ-WIM/src/server.cpp
@@ -128,6 +128,13 @@ void CIcqProto::ConnectionFailed(int iReason, int iErrorCode)
ShutdownSession();
}
+void CIcqProto::GetPermitDeny()
+{
+ auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, ICQ_API_SERVER "/preference/getPermitDeny", &CIcqProto::OnGetPermitDeny);
+ pReq << CHAR_PARAM("f", "json") << CHAR_PARAM("aimsid", m_aimsid) << CHAR_PARAM("r", pReq->m_reqId);
+ Push(pReq);
+}
+
void CIcqProto::MoveContactToGroup(MCONTACT hContact, const wchar_t *pwszGroup, const wchar_t *pwszNewGroup)
{
auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, ICQ_API_SERVER "/buddylist/moveBuddy");
@@ -142,6 +149,7 @@ void CIcqProto::OnLoggedIn()
m_bOnline = true;
SetServerStatus(m_iDesiredStatus);
RetrieveUserInfo(0);
+ GetPermitDeny();
}
void CIcqProto::OnLoggedOut()
@@ -383,6 +391,14 @@ void CIcqProto::RetrieveUserHistory(MCONTACT hContact, __int64 startMsgId, __int
Push(pReq);
}
+void CIcqProto::SetPermitDeny(MCONTACT hContact, bool bAllow)
+{
+ auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, ICQ_API_SERVER "/preference/setPermitDeny");
+ pReq << CHAR_PARAM("f", "json") << CHAR_PARAM("aimsid", m_aimsid) << CHAR_PARAM("r", pReq->m_reqId)
+ << CHAR_PARAM((bAllow) ? "pdIgnoreRemove" : "pdIgnore", GetUserId(hContact));
+ Push(pReq);
+}
+
void CIcqProto::SetServerStatus(int iStatus)
{
const char *szStatus = "online";
@@ -428,7 +444,7 @@ void CIcqProto::ShutdownSession()
/////////////////////////////////////////////////////////////////////////////////////////
#define CAPS "094613504c7f11d18222444553540000,094613514c7f11d18222444553540000,094613534c7f11d18222444553540000,094613544c7f11d18222444553540000,094613594c7f11d18222444553540000,0946135b4c7f11d18222444553540000,0946135a4c7f11d18222444553540000"
-#define EVENTS "myInfo,presence,buddylist,typing,dataIM,userAddedToBuddyList,webrtcMsg,mchat,hist,hiddenChat,diff,permitDeny,imState,notification,apps"
+#define EVENTS "myInfo,presence,buddylist,typing,dataIM,userAddedToBuddyList,mchat,hist,hiddenChat,diff,permitDeny,imState,notification,apps"
#define FIELDS "aimId,buddyIcon,bigBuddyIcon,iconId,bigIconId,largeIconId,displayId,friendly,offlineMsg,state,statusMsg,userType,phoneNumber,cellNumber,smsNumber,workNumber,otherNumber,capabilities,ssl,abPhoneNumber,moodIcon,lastName,abPhones,abContactName,lastseen,mute,livechat,official"
void CIcqProto::StartSession()
@@ -593,6 +609,13 @@ void CIcqProto::OnFileInit(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld)
ProtoBroadcastAck(pTransfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, pTransfer, (LPARAM)&pTransfer->pfts);
}
+void CIcqProto::OnGetPermitDeny(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+{
+ JsonReply root(pReply);
+ if (root.error() == 200)
+ ProcessPermissions(root.data());
+}
+
void CIcqProto::OnGetUserHistory(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
{
RobustReply root(pReply);
@@ -824,6 +847,8 @@ void CIcqProto::ProcessEvent(const JSONNode &ev)
ProcessGroupChat(pData);
else if (szType == L"myInfo")
ProcessMyInfo(pData);
+ else if (szType == L"permitDeny")
+ ProcessPermissions(pData);
else if (szType == L"presence")
ProcessPresence(pData);
else if (szType == L"typing")
@@ -910,6 +935,34 @@ void CIcqProto::ProcessMyInfo(const JSONNode &ev)
CheckAvatarChange(0, ev);
}
+void CIcqProto::ProcessPermissions(const JSONNode &ev)
+{
+ for (auto &it : m_arCache)
+ it->m_iApparentMode = 0;
+
+ for (auto &it : ev["allows"]) {
+ auto *p = FindContactByUIN(_wtoi(it.as_mstring()));
+ if (p)
+ p->m_iApparentMode = ID_STATUS_ONLINE;
+ }
+
+ for (auto &it : ev["ignores"]) {
+ auto *p = FindContactByUIN(_wtoi(it.as_mstring()));
+ if (p)
+ p->m_iApparentMode = ID_STATUS_OFFLINE;
+ }
+
+ for (auto &it: m_arCache) {
+ int oldMode = getDword(it->m_hContact, "ApparentMode");
+ if (oldMode != it->m_iApparentMode) {
+ if (it->m_iApparentMode == 0)
+ delSetting(it->m_hContact, "ApparentMode");
+ else
+ setDword(it->m_hContact, "ApparentMode", it->m_iApparentMode);
+ }
+ }
+}
+
void CIcqProto::ProcessPresence(const JSONNode &ev)
{
DWORD dwUin = _wtol(ev["aimId"].as_mstring());