diff options
author | George Hazan <ghazan@miranda.im> | 2019-01-31 19:32:14 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2019-01-31 19:32:22 +0300 |
commit | 48571763be1aec9d9ac10934c30797cc6d5081e5 (patch) | |
tree | 1480bbe88ec62dbb8d4317d0c905a79564adb937 | |
parent | 131a0bbaf24630bcc4f516ae3c8f96a0d39dc2eb (diff) |
ICQ-WIM: support for Ignore
-rw-r--r-- | protocols/ICQ-WIM/src/main.cpp | 51 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/proto.cpp | 45 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/proto.h | 18 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/server.cpp | 55 |
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()); |