#include "headers.h" #include "main.h" #include "shake.h" #include "m_msg_buttonsbar.h" int nProtocol = 0; static HANDLE g_hEventModulesLoaded = NULL, hEventOptionsInitialize = NULL, g_hIcon = NULL, g_hEventDbWindowEvent = NULL, g_hEventToolbarLoaded = NULL, g_hEventButtonPressed = NULL, g_hEventAccountsChanged = NULL; HINSTANCE hInst; NudgeElementList *NudgeList = NULL; CNudgeElement DefaultNudge; CShake shake; CNudge GlobalNudge; int hLangpack = 0; //======================== // MirandaPluginInfo //======================== PLUGININFOEX pluginInfo={ sizeof(PLUGININFOEX), "Nudge", PLUGIN_MAKE_VERSION(0,0,2,0), "Plugin to shake the clist and chat window", "Tweety/GouZ, FREAK_THEMIGHTY", "francois.mean@skynet.be, Sylvain.gougouzian@gmail.com, wishmaster51@googlemail.com", "copyright to the miranda community", "http://addons.miranda-im.org/", // www UNICODE_AWARE, 0, //doesn't replace anything built-in { 0xe47cc215, 0xd28, 0x462d, { 0xa0, 0xf6, 0x3a, 0xe4, 0x44, 0x3d, 0x29, 0x26 } } // {E47CC215-0D28-462D-A0F6-3AE4443D2926} }; INT_PTR NudgeShowMenu(WPARAM wParam,LPARAM lParam) { for(NudgeElementList *n = NudgeList;n != NULL; n = n->next) { if (!strcmp((char *) wParam,n->item.ProtocolName)) { return n->item.ShowContactMenu(lParam != 0); } } return 0; } INT_PTR NudgeSend(WPARAM wParam,LPARAM lParam) { char *protoName = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0); int diff = time(NULL) - DBGetContactSettingDword((HANDLE) wParam, "Nudge", "LastSent", time(NULL)-30); if(diff < GlobalNudge.sendTimeSec) { TCHAR msg[500]; mir_sntprintf(msg,500, TranslateT("You are not allowed to send too much nudge (only 1 each %d sec, %d sec left)"),GlobalNudge.sendTimeSec, 30 - diff); //MessageBox(NULL,msg,NULL,0); if(GlobalNudge.useByProtocol) { for(NudgeElementList *n = NudgeList;n != NULL; n = n->next) { if (!strcmp(protoName,n->item.ProtocolName)) { Nudge_ShowPopup(n->item, (HANDLE) wParam, msg); } } } else { Nudge_ShowPopup(DefaultNudge, (HANDLE) wParam, msg); } return 0; } DBWriteContactSettingDword((HANDLE) wParam, "Nudge", "LastSent", time(NULL)); if(GlobalNudge.useByProtocol) { NudgeElementList *n; for(n = NudgeList;n != NULL; n = n->next) { if (!strcmp(protoName,n->item.ProtocolName)) { //if(n->item.showPopup) // Nudge_ShowPopup(n->item, (HANDLE) wParam, n->item.senText); if(n->item.showStatus) Nudge_SentStatus(n->item, (HANDLE) wParam); } } } else { //if(DefaultNudge.showPopup) // Nudge_ShowPopup(DefaultNudge, (HANDLE) wParam, DefaultNudge.senText); if(DefaultNudge.showStatus) Nudge_SentStatus(DefaultNudge, (HANDLE) wParam); } CallProtoService(protoName,"/SendNudge",wParam,lParam); return 0; } void OpenContactList() { HWND hWnd = (HWND) CallService(MS_CLUI_GETHWND,0,0); ShowWindow(hWnd, SW_RESTORE); ShowWindow(hWnd, SW_SHOW); } int NudgeRecieved(WPARAM wParam,LPARAM lParam) { char *protoName = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0); DWORD currentTimestamp = time(NULL); DWORD nudgeSentTimestamp = lParam ? (DWORD)lParam : currentTimestamp; int diff = currentTimestamp - DBGetContactSettingDword((HANDLE) wParam, "Nudge", "LastReceived", currentTimestamp-30); int diff2 = nudgeSentTimestamp - DBGetContactSettingDword((HANDLE) wParam, "Nudge", "LastReceived2", nudgeSentTimestamp-30); if(diff >= GlobalNudge.recvTimeSec) DBWriteContactSettingDword((HANDLE) wParam, "Nudge", "LastReceived", currentTimestamp); if(diff2 >= GlobalNudge.recvTimeSec) DBWriteContactSettingDword((HANDLE) wParam, "Nudge", "LastReceived2", nudgeSentTimestamp); if(GlobalNudge.useByProtocol) { for(NudgeElementList *n = NudgeList;n != NULL; n = n->next) { if (!strcmp(protoName,n->item.ProtocolName)) { if(n->item.enabled) { if(n->item.useIgnoreSettings && CallService(MS_IGNORE_ISIGNORED,wParam,IGNOREEVENT_USERONLINE)) return 0; DWORD Status = CallProtoService(protoName,PS_GETSTATUS,0,0); if ( ((n->item.statusFlags & NUDGE_ACC_ST0) && (Status<=ID_STATUS_OFFLINE)) || ((n->item.statusFlags & NUDGE_ACC_ST1) && (Status==ID_STATUS_ONLINE)) || ((n->item.statusFlags & NUDGE_ACC_ST2) && (Status==ID_STATUS_AWAY)) || ((n->item.statusFlags & NUDGE_ACC_ST3) && (Status==ID_STATUS_DND)) || ((n->item.statusFlags & NUDGE_ACC_ST4) && (Status==ID_STATUS_NA)) || ((n->item.statusFlags & NUDGE_ACC_ST5) && (Status==ID_STATUS_OCCUPIED)) || ((n->item.statusFlags & NUDGE_ACC_ST6) && (Status==ID_STATUS_FREECHAT)) || ((n->item.statusFlags & NUDGE_ACC_ST7) && (Status==ID_STATUS_INVISIBLE)) || ((n->item.statusFlags & NUDGE_ACC_ST8) && (Status==ID_STATUS_ONTHEPHONE)) || ((n->item.statusFlags & NUDGE_ACC_ST9) && (Status==ID_STATUS_OUTTOLUNCH))) { if(diff >= GlobalNudge.recvTimeSec) { if(n->item.showPopup) Nudge_ShowPopup(n->item, (HANDLE) wParam, n->item.recText); if(n->item.openContactList) OpenContactList(); if(n->item.shakeClist) ShakeClist(wParam,lParam); if(n->item.openMessageWindow) CallService(MS_MSG_SENDMESSAGET,wParam,0); if(n->item.shakeChat) ShakeChat(wParam,lParam); if(n->item.autoResend) mir_forkthread(AutoResendNudge,(void *)wParam); SkinPlaySound( n->item.NudgeSoundname ); } } if(diff2 >= GlobalNudge.recvTimeSec) { if(n->item.showStatus) Nudge_ShowStatus(n->item, (HANDLE) wParam, nudgeSentTimestamp); } } break; } } } else { if(DefaultNudge.enabled) { if(DefaultNudge.useIgnoreSettings && CallService(MS_IGNORE_ISIGNORED,wParam,IGNOREEVENT_USERONLINE)) return 0; DWORD Status = CallService(MS_CLIST_GETSTATUSMODE,0,0); if ( ((DefaultNudge.statusFlags & NUDGE_ACC_ST0) && (Status<=ID_STATUS_OFFLINE)) || ((DefaultNudge.statusFlags & NUDGE_ACC_ST1) && (Status==ID_STATUS_ONLINE)) || ((DefaultNudge.statusFlags & NUDGE_ACC_ST2) && (Status==ID_STATUS_AWAY)) || ((DefaultNudge.statusFlags & NUDGE_ACC_ST3) && (Status==ID_STATUS_DND)) || ((DefaultNudge.statusFlags & NUDGE_ACC_ST4) && (Status==ID_STATUS_NA)) || ((DefaultNudge.statusFlags & NUDGE_ACC_ST5) && (Status==ID_STATUS_OCCUPIED)) || ((DefaultNudge.statusFlags & NUDGE_ACC_ST6) && (Status==ID_STATUS_FREECHAT)) || ((DefaultNudge.statusFlags & NUDGE_ACC_ST7) && (Status==ID_STATUS_INVISIBLE)) || ((DefaultNudge.statusFlags & NUDGE_ACC_ST8) && (Status==ID_STATUS_ONTHEPHONE)) || ((DefaultNudge.statusFlags & NUDGE_ACC_ST9) && (Status==ID_STATUS_OUTTOLUNCH))) { if(diff >= GlobalNudge.recvTimeSec) { if(DefaultNudge.showPopup) Nudge_ShowPopup(DefaultNudge, (HANDLE) wParam, DefaultNudge.recText); if(DefaultNudge.openContactList) OpenContactList(); if(DefaultNudge.shakeClist) ShakeClist(wParam,lParam); if(DefaultNudge.openMessageWindow) CallService(MS_MSG_SENDMESSAGET,wParam,0); if(DefaultNudge.shakeChat) ShakeChat(wParam,lParam); if(DefaultNudge.autoResend) mir_forkthread(AutoResendNudge,(void *)wParam); SkinPlaySound( DefaultNudge.NudgeSoundname ); } } if(diff2 >= GlobalNudge.recvTimeSec) { if(DefaultNudge.showStatus) Nudge_ShowStatus(DefaultNudge, (HANDLE) wParam, nudgeSentTimestamp); } } } return 0; } extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) { hInst=hinstDLL; return TRUE; } extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { return &pluginInfo; } static INT_PTR CALLBACK DlgProcOptsTrigger(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { // lParam = (LPARAM)(DWORD)actionID or 0 if this is a new trigger entry BOOL bshakeClist,bshakeChat; DWORD actionID = (DWORD)lParam; TranslateDialogDefault(hwnd); // Initialize the dialog according to the action ID bshakeClist = DBGetActionSettingByte(actionID, NULL, "Nudge", "ShakeClist",FALSE); bshakeChat = DBGetActionSettingByte(actionID, NULL, "Nudge", "ShakeChat",FALSE); CheckDlgButton(hwnd, IDC_TRIGGER_SHAKECLIST, bshakeClist ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hwnd, IDC_TRIGGER_SHAKECHAT, bshakeChat ? BST_CHECKED : BST_UNCHECKED); break; } case TM_ADDACTION: { // save your settings // wParam = (WPARAM)(DWORD)actionID bool bshakeClist,bshakeChat; DWORD actionID = (DWORD)wParam; bshakeClist = (IsDlgButtonChecked(hwnd,IDC_TRIGGER_SHAKECLIST)==BST_CHECKED); bshakeChat = (IsDlgButtonChecked(hwnd,IDC_TRIGGER_SHAKECHAT)==BST_CHECKED); DBWriteActionSettingByte(actionID, NULL, "Nudge", "ShakeClist",bshakeClist); DBWriteActionSettingByte(actionID, NULL, "Nudge", "ShakeChat",bshakeChat); break; } } return FALSE; } int TriggerActionRecv( DWORD actionID, REPORTINFO *ri) { // check how to process this call if (ri->flags&ACT_PERFORM) { BOOL bshakeClist,bshakeChat; HANDLE hContact = ((ri->td!=NULL)&&(ri->td->dFlags&DF_CONTACT))?ri->td->hContact:NULL; bshakeClist = DBGetActionSettingByte(actionID, NULL, "Nudge", "ShakeClist",FALSE); bshakeChat = DBGetActionSettingByte(actionID, NULL, "Nudge", "ShakeChat",FALSE); if(bshakeClist) ShakeClist(NULL,NULL); if(bshakeChat && (hContact != NULL)) ShakeChat((WPARAM)hContact,NULL); } if (ri->flags&ACT_CLEANUP) // request to delete all associated settings RemoveAllActionSettings(actionID, "Nudge"); return FALSE; } int TriggerActionSend( DWORD actionID, REPORTINFO *ri) { if (ri->flags & ACT_PERFORM) { HANDLE hContact = ((ri->td!=NULL)&&(ri->td->dFlags&DF_CONTACT))?ri->td->hContact:NULL; if(hContact != NULL) NudgeSend((WPARAM)hContact,NULL); } return FALSE; } void LoadProtocols(void) { //Load the default nudge mir_snprintf(DefaultNudge.ProtocolName,sizeof(DefaultNudge.ProtocolName),"Default"); mir_snprintf(DefaultNudge.NudgeSoundname,sizeof(DefaultNudge.NudgeSoundname),"Nudge : Default"); SkinAddNewSoundEx( DefaultNudge.NudgeSoundname, LPGEN("Nudge"), LPGEN("Default Nudge")); DefaultNudge.Load(); GlobalNudge.Load(); int numberOfProtocols = 0; PROTOACCOUNT **ppProtocolDescriptors; INT_PTR ret = ProtoEnumAccounts(&numberOfProtocols,&ppProtocolDescriptors); if(ret == 0) { for(int i = 0; i < numberOfProtocols ; i++) { Nudge_AddAccount(ppProtocolDescriptors[i]); } } shake.Load(); /*CNudgeElement *n; for(n = NudgeList;n != NULL; n = n->next) { MessageBox(NULL,n->ProtocolName,n->NudgeSoundname,0); }*/ } void RegisterToTrigger(void) { if ( ServiceExists(MS_TRIGGER_REGISTERACTION)) { ACTIONREGISTER ar; ZeroMemory(&ar, sizeof(ar)); ar.cbSize = sizeof(ar); ar.hInstance = hInst; ar.flags = ARF_TCHAR|ARF_FUNCTION; ar.actionFunction = TriggerActionRecv; ar.pfnDlgProc = DlgProcOptsTrigger; ar.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_TRIGGER); ar.pszName = Translate("Nudge : Shake contact list/chat window"); // register the action CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar); ar.actionFunction = TriggerActionSend; ar.pszName = Translate("Nudge : Send a nudge"); ar.pfnDlgProc = NULL; ar.pszTemplate = NULL; // register the action CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar); } } void RegisterToDbeditorpp(void) { // known modules list if (ServiceExists("DBEditorpp/RegisterSingleModule")) CallService("DBEditorpp/RegisterSingleModule", (WPARAM)"Nudge", 0); } void LoadIcons(void) { //Load icons SKINICONDESC sid = {0}; TCHAR szFilename[MAX_PATH]; GetModuleFileName(hInst,szFilename,MAX_PATH); sid.cbSize = sizeof(sid); sid.flags = SIDF_ALL_TCHAR; sid.ptszSection = LPGENT("Nudge"); sid.ptszDefaultFile = szFilename; sid.pszName = "Nudge_Default"; sid.ptszDescription = LPGENT("Nudge as Default"); sid.iDefaultIndex = -IDI_NUDGE; sid.hDefaultIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_NUDGE)); g_hIcon = Skin_AddIcon(&sid); } // Nudge support static int TabsrmmButtonPressed(WPARAM wParam, LPARAM lParam) { CustomButtonClickData *cbcd=(CustomButtonClickData *)lParam; if (!strcmp(cbcd->pszModule,"Nudge")) NudgeSend(wParam, 0); return 0; } static int TabsrmmButtonInit(WPARAM wParam, LPARAM lParam) { BBButton bbd = {0}; bbd.cbSize = sizeof(BBButton); bbd.pszModuleName = "Nudge"; bbd.ptszTooltip = LPGENT("Send Nudge"); bbd.dwDefPos = 300; bbd.bbbFlags = BBBF_ISIMBUTTON|BBBF_ISLSIDEBUTTON|BBBF_CANBEHIDDEN; bbd.hIcon = g_hIcon; bbd.dwButtonID = 6000; bbd.iButtonWidth = 0; CallService (MS_BB_ADDBUTTON, 0, (LPARAM)&bbd); return 0; } void HideNudgeButton(HANDLE hContact) { char str[MAXMODULELABELLENGTH + 12] = {0}; char *szProto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); mir_snprintf(str,MAXMODULELABELLENGTH + 12,"%s/SendNudge", szProto); if (!ServiceExists(str)) { BBButton bbd={0}; bbd.cbSize=sizeof(BBButton); bbd.bbbFlags=BBSF_HIDDEN|BBSF_DISABLED; bbd.pszModuleName="Nudge"; bbd.dwButtonID = 6000; CallService(MS_BB_SETBUTTONSTATE, (WPARAM)hContact, (LPARAM)&bbd); } } static int ContactWindowOpen(WPARAM wparam,LPARAM lParam) { MessageWindowEventData *MWeventdata = (MessageWindowEventData*)lParam; if(MWeventdata->uType == MSG_WINDOW_EVT_OPENING&&MWeventdata->hContact) { HideNudgeButton(MWeventdata->hContact); } return 0; } int ModulesLoaded(WPARAM,LPARAM) { RegisterToTrigger(); RegisterToDbeditorpp(); LoadProtocols(); LoadIcons(); LoadPopupClass(); g_hEventToolbarLoaded = HookEvent(ME_MSG_TOOLBARLOADED, TabsrmmButtonInit); if (g_hEventToolbarLoaded) { g_hEventButtonPressed = HookEvent(ME_MSG_BUTTONPRESSED, TabsrmmButtonPressed); g_hEventDbWindowEvent = HookEvent(ME_MSG_WINDOWEVENT,ContactWindowOpen); } return 0; } int AccListChanged(WPARAM wParam,LPARAM lParam) { PROTOACCOUNT *proto = (PROTOACCOUNT*) wParam; if (proto==NULL) return 0; switch (lParam) { case PRAC_ADDED: Nudge_AddAccount(proto); break; } return 0; } HANDLE hShakeClist=NULL,hShakeChat=NULL,hNudgeSend=NULL,hNudgeShowMenu=NULL; extern "C" int __declspec(dllexport) Load(void) { mir_getLP(&pluginInfo); g_hEventModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED,ModulesLoaded); g_hEventAccountsChanged = HookEvent(ME_PROTO_ACCLISTCHANGED,AccListChanged); hEventOptionsInitialize = HookEvent(ME_OPT_INITIALISE, NudgeOptInit); //Create function for plugins hShakeClist=CreateServiceFunction(MS_SHAKE_CLIST,ShakeClist); hShakeChat=CreateServiceFunction(MS_SHAKE_CHAT,ShakeChat); hNudgeSend=CreateServiceFunction(MS_NUDGE_SEND,NudgeSend); hNudgeShowMenu=CreateServiceFunction(MS_NUDGE_SHOWMENU,NudgeShowMenu); return 0; } extern "C" int __declspec(dllexport) Unload(void) { if(g_hEventToolbarLoaded) UnhookEvent(g_hEventToolbarLoaded); if(g_hEventDbWindowEvent) UnhookEvent(g_hEventButtonPressed); if(g_hEventDbWindowEvent) UnhookEvent(g_hEventDbWindowEvent); UnhookEvent(g_hEventModulesLoaded); UnhookEvent(g_hEventAccountsChanged); UnhookEvent(hEventOptionsInitialize); DestroyServiceFunction(hShakeClist); DestroyServiceFunction(hShakeChat); DestroyServiceFunction(hNudgeSend); DestroyServiceFunction(hNudgeShowMenu); NudgeElementList* p = NudgeList; while ( p != NULL ) { if(p->item.hEvent) UnhookEvent(p->item.hEvent); NudgeElementList* p1 = p->next; //free( p ); delete p; p = p1; } return 0; } LRESULT CALLBACK NudgePopUpProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { switch(msg) { case WM_COMMAND: { HANDLE hContact = PUGetContact(hWnd); CallService(MS_MSG_SENDMESSAGET, (WPARAM)hContact, 0); PUDeletePopUp(hWnd); break; } case WM_CONTEXTMENU: PUDeletePopUp(hWnd); break; case UM_FREEPLUGINDATA: //Here we'd free our own data, if we had it. return FALSE; case UM_INITPOPUP: break; case UM_DESTROYPOPUP: break; case WM_NOTIFY: default: break; } return DefWindowProc(hWnd,msg,wParam,lParam); } void LoadPopupClass() { if(ServiceExists(MS_POPUP_REGISTERCLASS)) { POPUPCLASS ppc = {0}; ppc.cbSize = sizeof(ppc); ppc.flags = PCF_TCHAR; ppc.pszName = "nudge"; ppc.ptszDescription = LPGENT("Show Nudge"); ppc.hIcon = (HICON) CallService(MS_SKIN2_GETICONBYHANDLE,0,(LPARAM)g_hIcon); ppc.colorBack = NULL; ppc.colorText = NULL; ppc.iSeconds = 0; ppc.PluginWindowProc = NudgePopUpProc; CallService(MS_POPUP_REGISTERCLASS,0,(LPARAM)&ppc); } } int Preview() { HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST,0,0); if ( GlobalNudge.useByProtocol ) { for(NudgeElementList *n = NudgeList;n != NULL; n = n->next) { if(n->item.enabled) { SkinPlaySound( n->item.NudgeSoundname ); if(n->item.showPopup) Nudge_ShowPopup(n->item, hContact, n->item.recText); if(n->item.openContactList) OpenContactList(); if(n->item.shakeClist) ShakeClist(0,0); if(n->item.openMessageWindow) CallService(MS_MSG_SENDMESSAGET,(WPARAM)hContact,NULL); if(n->item.shakeChat) ShakeChat((WPARAM)hContact,(LPARAM)time(NULL)); } } } else { if(DefaultNudge.enabled) { SkinPlaySound( DefaultNudge.NudgeSoundname ); if(DefaultNudge.showPopup) Nudge_ShowPopup(DefaultNudge, hContact, DefaultNudge.recText); if(DefaultNudge.openContactList) OpenContactList(); if(DefaultNudge.shakeClist) ShakeClist(0,0); if(DefaultNudge.openMessageWindow) CallService(MS_MSG_SENDMESSAGET,(WPARAM)hContact,NULL); if(DefaultNudge.shakeChat) ShakeChat((WPARAM)hContact,(LPARAM)time(NULL)); } } return 0; } void Nudge_ShowPopup(CNudgeElement n, HANDLE hContact, TCHAR * Message) { hContact = Nudge_GethContact(hContact); TCHAR * lpzContactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCDNF_TCHAR); if(ServiceExists(MS_POPUP_ADDPOPUPCLASS)) { POPUPDATACLASS NudgePopUp = {0}; NudgePopUp.cbSize = sizeof(NudgePopUp); NudgePopUp.hContact = hContact; NudgePopUp.ptszText = Message; NudgePopUp.ptszTitle = lpzContactName; NudgePopUp.pszClassName = "nudge"; CallService(MS_POPUP_ADDPOPUPCLASS, 0, (LPARAM)&NudgePopUp); } else if(ServiceExists(MS_POPUP_ADDPOPUPT)) { POPUPDATAT NudgePopUp = {0}; NudgePopUp.lchContact = hContact; NudgePopUp.lchIcon = (HICON) CallService(MS_SKIN2_GETICON,0,(LPARAM) n.hIcoLibItem ); NudgePopUp.colorBack = 0; NudgePopUp.colorText = 0; NudgePopUp.iSeconds = 0; NudgePopUp.PluginWindowProc = NudgePopUpProc; NudgePopUp.PluginData = (void *)1; //lstrcpy(NudgePopUp.lpzText, Translate(Message)); lstrcpy(NudgePopUp.lptzText, Message); lstrcpy(NudgePopUp.lptzContactName, lpzContactName); CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&NudgePopUp,0); } else { MessageBox(NULL,Message,lpzContactName,0); } } void Nudge_SentStatus(CNudgeElement n, HANDLE hContact) { DBEVENTINFO NudgeEvent = { 0 }; NudgeEvent.cbSize = sizeof(NudgeEvent); NudgeEvent.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); char *buff = mir_utf8encodeT(n.senText); NudgeEvent.flags = DBEF_SENT | DBEF_UTF; NudgeEvent.timestamp = ( DWORD )time(NULL); NudgeEvent.eventType = EVENTTYPE_STATUSCHANGE; NudgeEvent.cbBlob = (DWORD)strlen(buff) + 1; NudgeEvent.pBlob = ( PBYTE ) buff; INT_PTR res = CallService( MS_MC_GETMETACONTACT, (WPARAM)hContact, 0 ); //try to retrieve the metacontact if some if(res != CALLSERVICE_NOTFOUND) { HANDLE hMetaContact = (HANDLE) res; if(hMetaContact != NULL) //metacontact CallService(MS_DB_EVENT_ADD,(WPARAM)hMetaContact,(LPARAM)&NudgeEvent); } CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&NudgeEvent); } void Nudge_ShowStatus(CNudgeElement n, HANDLE hContact, DWORD timestamp) { DBEVENTINFO NudgeEvent = { 0 }; NudgeEvent.cbSize = sizeof(NudgeEvent); NudgeEvent.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); char *buff = mir_utf8encodeT(n.recText); NudgeEvent.flags = DBEF_UTF; NudgeEvent.timestamp = timestamp; NudgeEvent.eventType = EVENTTYPE_STATUSCHANGE; NudgeEvent.cbBlob = (DWORD)strlen(buff) + 1; NudgeEvent.pBlob = ( PBYTE ) buff; INT_PTR res = CallService( MS_MC_GETMETACONTACT, (WPARAM)hContact, 0 ); //try to retrieve the metacontact if some if(res != CALLSERVICE_NOTFOUND) { HANDLE hMetaContact = (HANDLE) res; if(hMetaContact != NULL) //metacontact { CallService(MS_DB_EVENT_ADD,(WPARAM)hMetaContact,(LPARAM)&NudgeEvent); NudgeEvent.flags |= DBEF_READ; } } CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&NudgeEvent); } HANDLE Nudge_GethContact(HANDLE hContact) { INT_PTR res = CallService( MS_MC_GETMETACONTACT, (WPARAM)hContact, 0 ); if(res!=CALLSERVICE_NOTFOUND) { HANDLE hMetaContact = (HANDLE) res; if(hMetaContact!=NULL) return hMetaContact; } return hContact; } void Nudge_AddAccount(PROTOACCOUNT *proto) { char str[MAXMODULELABELLENGTH + 10]; mir_snprintf(str,sizeof(str),"%s/Nudge",proto->szModuleName); HANDLE hevent = HookEvent(str, NudgeRecieved); if(hevent == NULL) return; nProtocol ++; //Add a specific sound per protocol NudgeElementList *newNudge = new NudgeElementList; //newNudge = (NudgeElementList*) malloc(sizeof(NudgeElementList)); mir_snprintf(newNudge->item.NudgeSoundname,sizeof(newNudge->item.NudgeSoundname),"%s: Nudge",proto->szModuleName); strcpy( newNudge->item.ProtocolName, proto->szProtoName ); _tcscpy(newNudge->item.AccountName, proto->tszAccountName ); newNudge->item.Load(); newNudge->item.hEvent = hevent; TCHAR soundDesc[MAXMODULELABELLENGTH + 10]; mir_sntprintf(soundDesc,sizeof(soundDesc),_T("Nudge for %s"),proto->tszAccountName); SkinAddNewSoundExT(newNudge->item.NudgeSoundname, LPGENT("Nudge"), soundDesc); newNudge->next = NudgeList; NudgeList = newNudge; char iconName[MAXMODULELABELLENGTH + 10]; mir_snprintf(iconName,sizeof(iconName),"Nudge_%s",proto->szModuleName); TCHAR szFilename[MAX_PATH], iconDesc[MAXMODULELABELLENGTH + 10]; GetModuleFileName(hInst,szFilename,MAX_PATH); mir_sntprintf(iconDesc, SIZEOF(iconDesc), TranslateT("Nudge for %s"), proto->tszAccountName); SKINICONDESC sid = {0}; sid.cbSize = sizeof(sid); sid.flags = SIDF_ALL_TCHAR; sid.ptszSection = LPGENT("Nudge"); sid.ptszDefaultFile = szFilename; sid.pszName = iconName; sid.ptszDescription = iconDesc; sid.iDefaultIndex = -IDI_NUDGE; sid.hDefaultIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_NUDGE)); newNudge->item.hIcoLibItem = Skin_AddIcon(&sid); //Add contact menu entry CLISTMENUITEM mi = {0}; mi.cbSize = sizeof(mi); mi.popupPosition = 500085000; mi.pszContactOwner = proto->szModuleName; mi.pszPopupName = proto->szModuleName; mi.flags = CMIF_NOTOFFLINE | CMIF_TCHAR | CMIF_ICONFROMICOLIB; mi.position = -500050004; mi.icolibItem = newNudge->item.hIcoLibItem; mi.ptszName = LPGENT( "Send &Nudge" ); mi.pszService = MS_NUDGE_SEND; newNudge->item.hContactMenu = Menu_AddContactMenuItem(&mi); } void AutoResendNudge(void *wParam) { Sleep(GlobalNudge.resendDelaySec * 1000); NudgeSend((WPARAM) wParam,NULL); }