#include "common.h" #include "proto.h" #include "server_con.h" #include "resource.h" #define MAX_MESSAGE_SIZE 1024 int GetCaps(WPARAM wParam,LPARAM lParam) { int ret = 0; switch (wParam) { case PFLAGNUM_1: ret = PF1_NUMERICUSERID | PF1_IM | PF1_BASICSEARCH | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME | PF1_ADDSEARCHRES | PF1_SERVERCLIST; break; case PFLAGNUM_2: ret = PF2_ONLINE;// | PF2_SHORTAWAY | PF2_HEAVYDND; break; case PFLAGNUM_3: //ret = PF2_ONLINE;// | PF2_SHORTAWAY | PF2_HEAVYDND; break; case PFLAGNUM_4: //ret = PF4_SUPPORTTYPING; break; case PFLAG_UNIQUEIDTEXT: ret = (int) Translate("UserID"); break; case PFLAG_MAXLENOFMESSAGE: ret = MAX_MESSAGE_SIZE; break; case PFLAG_UNIQUEIDSETTING: ret = (int) "UID"; break; } return ret; } int GetName(WPARAM wParam,LPARAM lParam) { mir_snprintf((char *)lParam, wParam, "%s", MODULE); return 0; } int LoadIcon(WPARAM wParam,LPARAM lParam) { UINT id; switch (wParam & 0xFFFF) { case PLI_PROTOCOL: id = IDI_ICON_PROTO; break; case PLI_ONLINE: id = IDI_ICON_PROTO; break; case PLI_OFFLINE: id = IDI_ICON_PROTO; break; default: return (int) (HICON) NULL; } return (int) LoadImage(hInst, MAKEINTRESOURCE(id), IMAGE_ICON, GetSystemMetrics(wParam & PLIF_SMALL ? SM_CXSMICON : SM_CXICON), GetSystemMetrics(wParam & PLIF_SMALL ? SM_CYSMICON : SM_CYICON), 0); return 0; } int GetInfo(WPARAM wParam,LPARAM lParam) { return 0; } int SetStatus(WPARAM wParam,LPARAM lParam) { if(wParam == status) return 0; if(wParam != ID_STATUS_OFFLINE) InitServerConnection(); else DeinitServerConnection(); return 0; } int GetStatus(WPARAM wParam,LPARAM lParam) { return status; } int ProtoSendMessage(WPARAM wParam, LPARAM lParam) { CCSDATA *ccs = (CCSDATA *) lParam; char *message = (char *)ccs->lParam; // TODO: process 'message' and/or 'messagew' below if(ccs->wParam & PREF_UNICODE) { wchar_t *messagew = (wchar_t *)&message[strlen(message)+1]; } else if(ccs->wParam & PREF_UTF) { // message is utf8 encoded - you can use mir_utf8decode (m_system.h) to make it wide } else { } return CallService(MS_PROTO_CHAINSEND, wParam, lParam); } int ProtoSendMessageW(WPARAM wParam, LPARAM lParam) { CCSDATA *ccs = (CCSDATA *) lParam; ccs->wParam |= PREF_UNICODE; return ProtoSendMessage(wParam, lParam); } int ProtoRecvMessage(WPARAM wParam, LPARAM lParam) { CCSDATA *ccs = (CCSDATA *) lParam; PROTORECVEVENT *pre = (PROTORECVEVENT *) ccs->lParam; char *message = pre->szMessage; // TODO: process 'message' and/or 'messagew' below if(pre->flags & PREF_UNICODE) { wchar_t *messagew = (wchar_t *)&message[strlen(message)+1]; } else if(pre->flags & PREF_UTF) { // message is utf8 encoded - you can use mir_utf8decode (m_system.h) to make it wide } return CallService(MS_PROTO_CHAINRECV, wParam, lParam); } int BasicSearch(WPARAM wParam, LPARAM lParam) { if(status <= ID_STATUS_OFFLINE) return 0; char *szId = (char *)lParam; ClientNetMessage msg; msg.add_int("persist", 1); msg.add_int("sesskey", sesskey); msg.add_int("uid", DBGetContactSettingDword(0, MODULE, "UID", 0)); msg.add_int("cmd", 1); msg.add_int("dsn", 4); msg.add_int("lid", 3); int req = req_id++; msg.add_int("rid", req); char body[512]; mir_snprintf(body, 512, "UserID=%s", szId); msg.add_string("body", body); SendMessage(msg); return req; } int SearchByEmail(WPARAM wParam, LPARAM lParam) { if(status <= ID_STATUS_OFFLINE) return 0; char *email = (char*)lParam; ClientNetMessage msg; msg.add_int("persist", 1); msg.add_int("sesskey", sesskey); msg.add_int("uid", DBGetContactSettingDword(0, MODULE, "UID", 0)); msg.add_int("cmd", 1); msg.add_int("dsn", 5); msg.add_int("lid", 7); int req = req_id++; msg.add_int("rid", req); char body[512]; mir_snprintf(body, 512, "Email=%s", email); msg.add_string("body", body); SendMessage(msg); return req; } int SearchByName(WPARAM wParam, LPARAM lParam) { if(status <= ID_STATUS_OFFLINE) return 0; PROTOSEARCHBYNAME *sbn = (PROTOSEARCHBYNAME *)lParam; if(!sbn->pszNick) return 0; ClientNetMessage msg; msg.add_int("persist", 1); msg.add_int("sesskey", sesskey); msg.add_int("uid", DBGetContactSettingDword(0, MODULE, "UID", 0)); msg.add_int("cmd", 1); msg.add_int("dsn", 5); msg.add_int("lid", 7); int req = req_id++; msg.add_int("rid", req); char body[512]; mir_snprintf(body, 512, "UserName=%s", sbn->pszNick); msg.add_string("body", body); SendMessage(msg); return req; } HANDLE FindContact(int uid) { char *proto; DBVARIANT dbv; int cuid; HANDLE hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); while ( hContact != NULL ) { proto = ( char* )CallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM )hContact,0 ); if ( proto && !strcmp( MODULE, proto)) { cuid = DBGetContactSettingDword(hContact, MODULE, "UID", (DWORD)-1); if(cuid != (DWORD)-1) { return hContact; } } hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 ); } return 0; } int AddToList(WPARAM wParam, LPARAM lParam) { MYPROTOSEARCHRESULT *mpsr = (MYPROTOSEARCHRESULT *)lParam; bool temp = (wParam & PALF_TEMPORARY) != 0; HANDLE hContact = FindContact(mpsr->uid); bool new_contact = (hContact == 0); if(!hContact) { hContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0); } else if(!temp) { DBDeleteContactSetting(hContact, "CList", "NotOnList"); DBDeleteContactSetting(hContact, "CList", "Hidden"); } if(hContact) { // add to miranda if(new_contact) { DBWriteContactSettingDword(hContact, MODULE, "UID", mpsr->uid); ClientNetMessage msg_add; msg_add.add_string("addbuddy", ""); msg_add.add_int("sesskey", sesskey); msg_add.add_int("newprofileid", mpsr->uid); msg_add.add_string("reason", ""); SendMessage(msg_add); ClientNetMessage msg_block; msg_block.add_string("blocklist", ""); msg_block.add_int("sesskey", sesskey); char idlist[1024]; mir_snprintf(idlist, 1024, "b-|%d|a+|%d", mpsr->uid, mpsr->uid); msg_block.add_string("idlist", idlist); SendMessage(msg_block); // update contact details? ClientNetMessage msg_persist; msg_persist.add_int("persist", 1); msg_persist.add_int("sesskey", sesskey); msg_persist.add_int("cmd", 514); msg_persist.add_int("dsn", 0); msg_persist.add_int("uid", DBGetContactSettingDword(0, MODULE, "UID", 0)); msg_persist.add_int("lid", 9); msg_persist.add_int("rid", req_id++); char body[4096]; mir_snprintf(body, 4096, "ContactID=%d\x1cGroupName=\x1cPosition=1000\x1cVisibility=1\x1cNickName=\x1cNameSelect=0", mpsr->uid); msg_persist.add_string("body", body); SendMessage(msg_persist); } if(mpsr->psr.nick && strlen(mpsr->psr.nick)) { DBWriteContactSettingStringUtf(hContact, MODULE, "Nick", mpsr->psr.nick); } if(mpsr->psr.email && strlen(mpsr->psr.email)) { DBWriteContactSettingStringUtf(hContact, MODULE, "email", mpsr->psr.email); } if(new_contact) { CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)MODULE); } if(temp) { DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1); DBWriteContactSettingByte(hContact, "CList", "Hidden", 1); } else { DBDeleteContactSetting(hContact, "CList", "NotOnList"); DBDeleteContactSetting(hContact, "CList", "Hidden"); } } return (int)hContact; } int ContactDeleted(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)wParam; int uid = DBGetContactSettingDword(hContact, MODULE, "UID", 0); if(uid) { ClientNetMessage msg_del; msg_del.add_string("delbuddy", ""); msg_del.add_int("sesskey", sesskey); msg_del.add_int("delprofileid", uid); SendMessage(msg_del); ClientNetMessage msg_persist; msg_persist.add_int("persist", 1); msg_persist.add_int("sesskey", sesskey); msg_persist.add_int("cmd", 515); msg_persist.add_int("dsn", 0); msg_persist.add_int("uid", DBGetContactSettingDword(0, MODULE, "UID", 0)); msg_persist.add_int("lid", 8); msg_persist.add_int("rid", req_id++); char body[1024]; mir_snprintf(body, 1024, "ContactID=%d", uid); msg_persist.add_string("body", body); SendMessage(msg_persist); ClientNetMessage msg_block; msg_block.add_string("blocklist", ""); msg_block.add_int("sesskey", sesskey); char idlist[1024]; mir_snprintf(idlist, 1024, "a-|%d|b-|%d", uid, uid); msg_block.add_string("idlist", idlist); SendMessage(msg_block); } return 0; } void RegisterProto() { PROTOCOLDESCRIPTOR pd = {0}; pd.cbSize = sizeof(pd); pd.szName = MODULE; pd.type = PROTOTYPE_PROTOCOL; CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); } #define NUM_FILTER_SERVICES 12 HANDLE hServices[NUM_FILTER_SERVICES]; HANDLE hEventContactDeleted; void CreateProtoServices() { // create our services int i = 0; hServices[i++] = CreateProtoServiceFunction(MODULE, PSS_MESSAGE, ProtoSendMessage); hServices[i++] = CreateProtoServiceFunction(MODULE, PSS_MESSAGE"W", ProtoSendMessageW); hServices[i++] = CreateProtoServiceFunction(MODULE, PSR_MESSAGE, ProtoRecvMessage); hServices[i++] = CreateProtoServiceFunction(MODULE, PS_GETCAPS, GetCaps); hServices[i++] = CreateProtoServiceFunction(MODULE, PS_GETNAME, GetName); hServices[i++] = CreateProtoServiceFunction(MODULE, PS_LOADICON,LoadIcon); hServices[i++] = CreateProtoServiceFunction(MODULE, PSS_GETINFO,GetInfo); hServices[i++] = CreateProtoServiceFunction(MODULE, PS_SETSTATUS, SetStatus); hServices[i++] = CreateProtoServiceFunction(MODULE, PS_GETSTATUS, GetStatus); hServices[i++] = CreateProtoServiceFunction(MODULE, PS_BASICSEARCH, BasicSearch); hServices[i++] = CreateProtoServiceFunction(MODULE, PS_SEARCHBYEMAIL, SearchByEmail); hServices[i++] = CreateProtoServiceFunction(MODULE, PS_SEARCHBYNAME, SearchByName); hServices[i++] = CreateProtoServiceFunction(MODULE, PS_ADDTOLIST, AddToList); // remember to modify the NUM_FILTER_SERVICES #define above if you add more services! hEventContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, ContactDeleted); } void DeinitProto() { UnhookEvent(hEventContactDeleted); for(int i = 0; i < NUM_FILTER_SERVICES; i++) DestroyServiceFunction(hServices[i]); }