/* Facebook plugin for Miranda Instant Messenger _____________________________________________ Copyright © 2011-13 Robert Pösel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "common.h" #include #include void FacebookProto::UpdateChat(const char *chat_id, const char *id, const char *name, const char *message, DWORD timestamp) { ptrT tchat_id( mir_a2t(chat_id)); ptrT tid( mir_a2t(id)); ptrT tnick( mir_a2t_cp(name,CP_UTF8)); ptrT ttext( mir_a2t_cp(message,CP_UTF8)); GCDEST gcd = { m_szModuleName }; gcd.ptszID = tchat_id; GCEVENT gce = {sizeof(gce)}; gce.pDest = &gcd; gce.ptszText = ttext; gce.time = timestamp ? timestamp : ::time(NULL); gce.dwFlags = GC_TCHAR; gcd.iType = GC_EVENT_MESSAGE; if (id != NULL) gce.bIsMe = !strcmp(id,facy.self_.user_id.c_str()); gce.dwFlags |= GCEF_ADDTOLOG; gce.ptszNick = tnick; gce.ptszUID = tid; CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); std::map::iterator chatroom = facy.chat_rooms.find(chat_id); chatroom->second.message_readers = ""; HANDLE hChatContact = ChatIDToHContact(chat_id); CallService(MS_MSG_SETSTATUSTEXT, (WPARAM)hChatContact, (LPARAM)mir_a2u("Unseen")); } void FacebookProto::RenameChat(const char *chat_id, const char *name) { ptrT tchat_id( mir_a2t(chat_id)); ptrT tname( mir_a2t_cp(name, CP_UTF8)); GCDEST gcd = { m_szModuleName }; gcd.ptszID = tchat_id; GCEVENT gce = {sizeof(gce)}; gce.pDest = &gcd; gce.ptszText = tname; gce.dwFlags = GC_TCHAR; gcd.iType = GC_EVENT_CHANGESESSIONAME; CallService(MS_GC_EVENT, 0, reinterpret_cast(&gce)); } int FacebookProto::OnGCEvent(WPARAM wParam,LPARAM lParam) { GCHOOK *hook = reinterpret_cast(lParam); if (strcmp(hook->pDest->pszModule,m_szModuleName)) return 0; switch(hook->pDest->iType) { case GC_USER_MESSAGE: { std::string msg = ptrA( mir_t2a_cp(hook->ptszText,CP_UTF8)); std::string chat_id = ptrA( mir_t2a_cp(hook->pDest->ptszID,CP_UTF8)); if (isOnline()) { LOG("**Chat - Outgoing message: %s", msg.c_str()); ForkThread(&FacebookProto::SendChatMsgWorker, new send_chat(chat_id, msg)); } break; } case GC_USER_PRIVMESS: { char* sn = mir_t2a(hook->ptszUID); HANDLE hContact = ContactIDToHContact(sn); mir_free(sn); CallService(MS_MSG_SENDMESSAGET, (WPARAM)hContact, 0); break; } /* case GC_USER_LOGMENU: { switch(hook->dwData) { case 10: DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, invite_to_chat_dialog, LPARAM(new invite_chat_param(item->id, this))); break; case 20: //chat_leave(id); break; } break; } */ case GC_USER_NICKLISTMENU: { char *sn = mir_t2a(hook->ptszUID); HANDLE hContact = ContactIDToHContact(sn); mir_free(sn); switch (hook->dwData) { case 10: CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); break; case 20: CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)hContact, 0); break; case 110: //chat_leave(id); break; } break; } case GC_USER_LEAVE: case GC_SESSION_TERMINATE: break; } return 0; } void FacebookProto::AddChatContact(const char *chat_id, const char *id, const char *name) { ptrT tchat_id( mir_a2t(chat_id)); ptrT tnick( mir_a2t_cp(name, CP_UTF8)); ptrT tid( mir_a2t(id)); GCDEST gcd = { m_szModuleName }; gcd.ptszID = tchat_id; gcd.iType = GC_EVENT_JOIN; GCEVENT gce = {sizeof(gce)}; gce.pDest = &gcd; gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG; gce.ptszNick = tnick; gce.ptszUID = tid; gce.time = ::time(NULL); gce.bIsMe = !strcmp(id, facy.self_.user_id.c_str()); if (gce.bIsMe) gce.ptszStatus = _T("Admin"); else gce.ptszStatus = _T("Normal"); std::map::iterator room = facy.chat_rooms.find(chat_id); if(room != facy.chat_rooms.end()) room->second.participants.insert(std::make_pair(id, name)); CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); } void FacebookProto::RemoveChatContact(const char *chat_id, const char *id) { // We dont want to remove our self-contact from chat. Ever. if (!strcmp(id, facy.self_.user_id.c_str())) return; ptrT tchat_id( mir_a2t(chat_id)); ptrT tid( mir_a2t(id)); GCDEST gcd = { m_szModuleName }; gcd.ptszID = tchat_id; gcd.iType = GC_EVENT_PART; GCEVENT gce = {sizeof(gce)}; gce.pDest = &gcd; gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG; //gce.ptszNick = mir_a2t_cp(name, CP_UTF8); gce.ptszUID = tid; gce.ptszNick = tid; gce.time = ::time(NULL); gce.bIsMe = false;//!strcmp(id, facy.self_.user_id.c_str()); std::map::iterator room = facy.chat_rooms.find(chat_id); if (room != facy.chat_rooms.end()) room->second.participants.erase(id); CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); } /** Caller must free result */ char *FacebookProto::GetChatUsers(const char *chat_id) { ptrT tid( mir_a2t(chat_id)); GC_INFO gci = {0}; gci.Flags = USERS; gci.pszModule = m_szModuleName; gci.pszID = tid; CallService(MS_GC_GETINFO, 0, (LPARAM)(GC_INFO *) &gci); LOG("**Chat - Users in chat %s: %s", chat_id, gci.pszUsers); // mir_free(gci.pszUsers); return gci.pszUsers; } bool FacebookProto::IsChatContact(const char *chat_id, const char *id) { ptrA users( GetChatUsers(chat_id)); return (users != NULL && strstr(users, id) != NULL); } void FacebookProto::AddChat(const char *id, const char *name) { GCSESSION gcw = {sizeof(gcw)}; ptrT tname( mir_a2t_cp(name, CP_UTF8)); ptrT tid( mir_a2t(id)); // Create the group chat session gcw.dwFlags = GC_TCHAR; gcw.iType = GCW_CHATROOM; gcw.pszModule = m_szModuleName; gcw.ptszName = tname; gcw.ptszID = tid; CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw); // Send setting events GCDEST gcd = { m_szModuleName }; gcd.ptszID = tid; GCEVENT gce = {sizeof(gce)}; gce.pDest = &gcd; gce.dwFlags = GC_TCHAR; // Create a user statuses gcd.iType = GC_EVENT_ADDGROUP; gce.ptszStatus = _T("Admin"); CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast(&gce)); gce.ptszStatus = _T("Normal"); CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast(&gce)); // Finish initialization gcd.iType = GC_EVENT_CONTROL; gce.time = ::time(NULL); gce.pDest = &gcd; facebook_chatroom chatroom; chatroom.chat_name = name; facy.chat_rooms.insert(std::make_pair(id, chatroom)); // Add self contact AddChatContact(id, facy.self_.user_id.c_str(), facy.self_.real_name.c_str()); CallServiceSync(MS_GC_EVENT,SESSION_INITDONE,reinterpret_cast(&gce)); CallServiceSync(MS_GC_EVENT,SESSION_ONLINE, reinterpret_cast(&gce)); } /*void FacebookProto::SetTopic(const char *topic) { GCDEST gcd = { m_szModuleName }; gcd.ptszID = const_cast(m_tszUserName); gcd.iType = GC_EVENT_TOPIC; GCEVENT gce = {sizeof(gce)}; gce.pDest = &gcd; gce.dwFlags = GC_TCHAR; gce.time = ::time(NULL); std::string top = Translate(topic); gce.ptszText = mir_a2t(top.c_str()); CallServiceSync(MS_GC_EVENT,0, reinterpret_cast(&gce)); } */ INT_PTR FacebookProto::OnJoinChat(WPARAM wParam,LPARAM suppress) { HANDLE hContact = (HANDLE)wParam; // TODO: load info from server + old history,... ptrA id( getStringA(hContact, "ChatRoomID")); ptrA name( getStringA(hContact, "Nick")); AddChat(id, name); /* GCSESSION gcw = {sizeof(gcw)}; // Create the group chat session gcw.dwFlags = GC_TCHAR; gcw.iType = GCW_CHATROOM; gcw.pszModule = m_szModuleName; gcw.ptszName = m_tszUserName; gcw.ptszID = m_tszUserName; CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw); if(m_iStatus != ID_STATUS_ONLINE) return 0; // Create a group GCDEST gcd = { m_szModuleName }; gcd.ptszID = const_cast(m_tszUserName); GCEVENT gce = {sizeof(gce)}; gce.pDest = &gcd; gce.dwFlags = GC_TCHAR; gcd.iType = GC_EVENT_ADDGROUP; gce.ptszStatus = _T("Admin"); CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast(&gce)); gce.ptszStatus = _T("Normal"); CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast(&gce)); SetTopic("Omegle is a great way of meeting new friends!"); // Note: Initialization will finish up in SetChatStatus, called separately if (!suppress) SetChatStatus(m_iStatus); */ return 0; } INT_PTR FacebookProto::OnLeaveChat(WPARAM,LPARAM) { GCDEST gcd = { m_szModuleName }; gcd.ptszID = NULL; gcd.iType = GC_EVENT_CONTROL; GCEVENT gce = {sizeof(gce)}; gce.dwFlags = GC_TCHAR; gce.time = ::time(NULL); gce.pDest = &gcd; CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE, reinterpret_cast(&gce)); CallServiceSync(MS_GC_EVENT,SESSION_TERMINATE,reinterpret_cast(&gce)); return 0; } /* void FacebookProto::SetChatStatus(int status) { GCDEST gcd = { m_szModuleName }; gcd.ptszID = const_cast(m_tszUserName); gcd.iType = GC_EVENT_CONTROL; GCEVENT gce = {sizeof(gce)}; gce.dwFlags = GC_TCHAR; gce.time = ::time(NULL); gce.pDest = &gcd; if(status == ID_STATUS_ONLINE) { // Add self contact AddChatContact(facy.nick_.c_str()); CallServiceSync(MS_GC_EVENT,SESSION_INITDONE,reinterpret_cast(&gce)); CallServiceSync(MS_GC_EVENT,SESSION_ONLINE, reinterpret_cast(&gce)); } else { CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE,reinterpret_cast(&gce)); } } */ int FacebookProto::OnGCMenuHook(WPARAM, LPARAM lParam) { GCMENUITEMS *gcmi= (GCMENUITEMS*) lParam; if (gcmi == NULL || _stricmp(gcmi->pszModule, m_szModuleName)) return 0; if (gcmi->Type == MENU_ON_LOG) { static const struct gc_item Items[] = { { LPGENT("&Invite user..."), 10, MENU_ITEM, FALSE }, { LPGENT("&Leave chat session"), 20, MENU_ITEM, FALSE } }; gcmi->nItems = SIZEOF(Items); gcmi->Item = (gc_item*)Items; } else if (gcmi->Type == MENU_ON_NICKLIST) { char* email = mir_t2a(gcmi->pszUID); if (!_stricmp(facy.self_.user_id.c_str(), email)) { /*static const struct gc_item Items[] = { { LPGENT("User &details"), 10, MENU_ITEM, FALSE }, { LPGENT("User &history"), 20, MENU_ITEM, FALSE }, { _T(""), 100, MENU_SEPARATOR, FALSE }, { LPGENT("&Leave chat session"), 110, MENU_ITEM, FALSE } }; gcmi->nItems = SIZEOF(Items); gcmi->Item = (gc_item*)Items;*/ gcmi->nItems = 0; gcmi->Item = NULL; } else { static const struct gc_item Items[] = { { LPGENT("User &details"), 10, MENU_ITEM, FALSE }, { LPGENT("User &history"), 20, MENU_ITEM, FALSE } }; gcmi->nItems = SIZEOF(Items); gcmi->Item = (gc_item*)Items; } mir_free(email); } return 0; }