summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/FacebookRM/src/chat.cpp909
-rw-r--r--protocols/FacebookRM/src/contacts.cpp7
-rw-r--r--protocols/FacebookRM/src/proto.cpp17
-rw-r--r--protocols/FacebookRM/src/proto.h2
4 files changed, 473 insertions, 462 deletions
diff --git a/protocols/FacebookRM/src/chat.cpp b/protocols/FacebookRM/src/chat.cpp
index fc02edf353..b9f416a632 100644
--- a/protocols/FacebookRM/src/chat.cpp
+++ b/protocols/FacebookRM/src/chat.cpp
@@ -1,451 +1,460 @@
-/*
-
-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 <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "common.h"
-#include <m_history.h>
-#include <m_userinfo.h>
-
-void FacebookProto::UpdateChat(const TCHAR *tchat_id, const char *id, const char *name, const char *message, DWORD timestamp, bool is_old)
-{
- // replace % to %% to not interfere with chat color codes
- std::string smessage = message;
- utils::text::replace_all(&smessage, "%", "%%");
-
- ptrT tid( mir_a2t(id));
- ptrT tnick( mir_a2t_cp(name,CP_UTF8));
- ptrT ttext( mir_a2t_cp(smessage.c_str(),CP_UTF8));
-
- GCDEST gcd = { m_szModuleName, tchat_id, GC_EVENT_MESSAGE };
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.ptszText = ttext;
- gce.time = timestamp ? timestamp : ::time(NULL);
- if (id != NULL)
- gce.bIsMe = !strcmp(id,facy.self_.user_id.c_str());
- gce.dwFlags |= GCEF_ADDTOLOG;
- if (is_old) {
- gce.dwFlags |= GCEF_NOTNOTIFY;
- gce.dwFlags &= ~GCEF_ADDTOLOG;
- }
- gce.ptszNick = tnick;
- gce.ptszUID = tid;
- CallServiceSync(MS_GC_EVENT,0,reinterpret_cast<LPARAM>(&gce));
-
- // TODO: keep it here or move it somewhere else?
- std::map<std::tstring, facebook_chatroom*>::iterator chatroom = facy.chat_rooms.find(tchat_id);
- if (chatroom != facy.chat_rooms.end()) {
- chatroom->second->message_readers.clear();
- }
-}
-
-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, tchat_id, GC_EVENT_CHANGESESSIONAME };
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.ptszText = tname;
- CallService(MS_GC_EVENT, 0, reinterpret_cast<LPARAM>(&gce));
-}
-
-int FacebookProto::OnGCEvent(WPARAM wParam,LPARAM lParam)
-{
- GCHOOK *hook = reinterpret_cast<GCHOOK*>(lParam);
-
- if (strcmp(hook->pDest->pszModule, m_szModuleName))
- return 0;
-
- // Ignore for special chatrooms
- if (!_tcscmp(hook->pDest->ptszID, _T(FACEBOOK_NOTIFICATIONS_CHATROOM)))
- return 0;
-
- switch(hook->pDest->iType)
- {
- case GC_USER_MESSAGE:
- {
- std::string msg = _T2A(hook->ptszText, CP_UTF8);
- std::string chat_id = _T2A(hook->pDest->ptszID, CP_UTF8);
-
- if (isOnline()) {
- debugLogA("**Chat - Outgoing message: %s", msg.c_str());
- ForkThread(&FacebookProto::SendChatMsgWorker, new send_chat(chat_id, msg));
- }
-
- break;
- }
-
- case GC_USER_PRIVMESS:
- {
- std::string id = _T2A(hook->ptszUID, CP_UTF8);
-
- MCONTACT hContact = ContactIDToHContact(id);
- if (!hContact)
- break; // TODO: create new temporary contact
-
- CallService(MS_MSG_SENDMESSAGET, 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:
- {
- std::string id = _T2A(hook->ptszUID, CP_UTF8);
-
- MCONTACT hContact = ContactIDToHContact(id);
- if (!hContact)
- break; // TODO: create new temporary contact
-
- switch (hook->dwData)
- {
- case 10:
- CallService(MS_USERINFO_SHOWDIALOG, hContact, 0);
- break;
-
- case 20:
- CallService(MS_HISTORY_SHOWCONTACTHISTORY, 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 TCHAR *tchat_id, const char *id, const char *name)
-{
- ptrT tnick( mir_a2t_cp(name, CP_UTF8));
- ptrT tid( mir_a2t(id));
-
- GCDEST gcd = { m_szModuleName, tchat_id, GC_EVENT_JOIN };
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.pDest = &gcd;
- gce.dwFlags = 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 = TranslateT("Myself");
- } else {
- MCONTACT hContact = ContactIDToHContact(id);
- if (hContact == NULL || getByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, CONTACT_NONE) != CONTACT_FRIEND)
- gce.ptszStatus = TranslateT("User");
- else {
- gce.ptszStatus = TranslateT("Friend");
- }
- }
-
- CallServiceSync(MS_GC_EVENT, 0, reinterpret_cast<LPARAM>(&gce));
-}
-
-void FacebookProto::RemoveChatContact(const TCHAR *tchat_id, const char *id, const char *name)
-{
- // We dont want to remove our self-contact from chat. Ever.
- if (!strcmp(id, facy.self_.user_id.c_str()))
- return;
-
- ptrT tnick(mir_a2t_cp(name, CP_UTF8));
- ptrT tid( mir_a2t(id));
-
- GCDEST gcd = { m_szModuleName, tchat_id, GC_EVENT_PART };
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.dwFlags = GCEF_ADDTOLOG;
- gce.ptszNick = tnick;
- gce.ptszUID = tid;
- gce.time = ::time(NULL);
- gce.bIsMe = false;
-
- CallServiceSync(MS_GC_EVENT,0,reinterpret_cast<LPARAM>(&gce));
-}
-
-/** Caller must free result */
-char *FacebookProto::GetChatUsers(const TCHAR *chat_id)
-{
- GC_INFO gci = {0};
- gci.Flags = GCF_USERS;
- gci.pszModule = m_szModuleName;
- gci.pszID = chat_id;
- CallService(MS_GC_GETINFO, 0, (LPARAM)&gci);
-
- debugLogA("**Chat - Users in chat %s: %s", _T2A(chat_id), gci.pszUsers);
-
- // mir_free(gci.pszUsers);
- return gci.pszUsers;
-}
-
-bool FacebookProto::IsChatContact(const TCHAR *chat_id, const char *id)
-{
- ptrA users( GetChatUsers(chat_id));
- return (users != NULL && strstr(users, id) != NULL);
-}
-
-void FacebookProto::AddChat(const TCHAR *tid, const TCHAR *tname)
-{
- // Create the group chat session
- GCSESSION gcw = { sizeof(gcw) };
- gcw.iType = GCW_PRIVMESS;
- gcw.ptszID = tid;
- gcw.pszModule = m_szModuleName;
- gcw.ptszName = tname;
- CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
-
- // Send setting events
- GCDEST gcd = { m_szModuleName, tid, GC_EVENT_ADDGROUP };
- GCEVENT gce = { sizeof(gce), &gcd };
-
- // Create a user statuses
- gce.ptszStatus = TranslateT("Myself");
- CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
- gce.ptszStatus = TranslateT("Friend");
- CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
- gce.ptszStatus = TranslateT("User");
- CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
-
- // Finish initialization
- gcd.iType = GC_EVENT_CONTROL;
- gce.time = ::time(NULL);
- gce.pDest = &gcd;
-
- bool hideChats = getBool(FACEBOOK_KEY_HIDE_CHATS, DEFAULT_HIDE_CHATS);
-
- // Add self contact
- AddChatContact(tid, facy.self_.user_id.c_str(), facy.self_.real_name.c_str());
- CallServiceSync(MS_GC_EVENT, (hideChats ? WINDOW_HIDDEN : SESSION_INITDONE), reinterpret_cast<LPARAM>(&gce));
- CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
-}
-
-INT_PTR FacebookProto::OnJoinChat(WPARAM hContact, LPARAM suppress)
-{
- // TODO: load info from server + old history,...
-
- ptrT idT( getTStringA(hContact, "ChatRoomID"));
- ptrT nameT( getTStringA(hContact, "Nick"));
-
- if (idT && nameT)
- AddChat(idT, nameT);
-
-/* GCSESSION gcw = {sizeof(gcw)};
-
- // Create the group chat session
- gcw.dwFlags = GC_TCHAR;
- gcw.iType = GCW_PRIVMESS;
- 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, m_tszUserName, GC_EVENT_ADDGROUP };
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.ptszStatus = TranslateT("Myself");
- CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
- gce.ptszStatus = TranslateT("Friend");
- CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
- gce.ptszStatus = TranslateT("User");
- CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&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 wParam,LPARAM)
-{
- ptrT idT(wParam ? getTStringA(wParam, "ChatRoomID") : NULL);
-
- GCDEST gcd = { m_szModuleName, NULL, GC_EVENT_CONTROL };
- gcd.ptszID = idT;
-
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.time = ::time(NULL);
-
- CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE, reinterpret_cast<LPARAM>(&gce));
- CallServiceSync(MS_GC_EVENT,SESSION_TERMINATE,reinterpret_cast<LPARAM>(&gce));
- return 0;
-}
-
-/*
-void FacebookProto::SetChatStatus(int status)
-{
- GCDEST gcd = { m_szModuleName, m_tszUserName, GC_EVENT_CONTROL };
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.time = ::time(NULL);
-
- if(status == ID_STATUS_ONLINE)
- {
- // Add self contact
- AddChatContact(facy.nick_.c_str());
-
- CallServiceSync(MS_GC_EVENT,SESSION_INITDONE,reinterpret_cast<LPARAM>(&gce));
- CallServiceSync(MS_GC_EVENT,SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
- }
- else
- {
- CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE,reinterpret_cast<LPARAM>(&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)
- {
- if (!_stricmp(facy.self_.user_id.c_str(), _T2A(gcmi->pszUID)))
- {
- /*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;
- }
- }
-
- return 0;
-}
-
-bool FacebookProto::IsSpecialChatRoom(MCONTACT hContact) {
- if (!isChatRoom(hContact))
- return false;
-
- ptrT idT(getTStringA(hContact, "ChatRoomID"));
- return idT && !_tcscmp(idT, _T(FACEBOOK_NOTIFICATIONS_CHATROOM));
-}
-
-void FacebookProto::PrepareNotificationsChatRoom() {
- if (!getBool(FACEBOOK_KEY_NOTIFICATIONS_CHATROOM, DEFAULT_NOTIFICATIONS_CHATROOM))
- return;
-
- // Prepare notifications chatroom if not exists
- TCHAR *gidT = _T(FACEBOOK_NOTIFICATIONS_CHATROOM);
-
- MCONTACT hNotificationsChatRoom = ChatIDToHContact(gidT);
- if (hNotificationsChatRoom == NULL || getDword(hNotificationsChatRoom, "Status", ID_STATUS_OFFLINE) != ID_STATUS_ONLINE) {
- TCHAR nameT[200];
- mir_sntprintf(nameT, SIZEOF(nameT), _T("%s: %s"), m_tszUserName, TranslateT("Notifications"));
-
- // Create the group chat session
- GCSESSION gcw = { sizeof(gcw) };
- gcw.iType = GCW_PRIVMESS;
- gcw.ptszID = gidT;
- gcw.pszModule = m_szModuleName;
- gcw.ptszName = nameT;
- CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
-
- // Send setting events
- GCDEST gcd = { m_szModuleName, gidT, GC_EVENT_CONTROL };
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.time = ::time(NULL);
-
- CallServiceSync(MS_GC_EVENT, WINDOW_HIDDEN, reinterpret_cast<LPARAM>(&gce));
- CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
- }
-}
-
-void FacebookProto::UpdateNotificationsChatRoom(facebook_notification *notification) {
- if (!getBool(FACEBOOK_KEY_NOTIFICATIONS_CHATROOM, DEFAULT_NOTIFICATIONS_CHATROOM))
- return;
-
- std::stringstream text;
- text << notification->text << "\n\n" << PrepareUrl(notification->link);
-
- std::string message = text.str();
- utils::text::replace_all(&message, "%", "%%");
-
- ptrT idT(mir_tstrdup(_T(FACEBOOK_NOTIFICATIONS_CHATROOM)));
- ptrT messageT(mir_a2t_cp(message.c_str(), CP_UTF8));
-
- GCDEST gcd = { m_szModuleName, _T(FACEBOOK_NOTIFICATIONS_CHATROOM), GC_EVENT_MESSAGE };
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.ptszText = messageT;
- gce.time = notification->time ? notification->time : ::time(NULL);
- gce.bIsMe = false;
- gce.dwFlags |= GCEF_ADDTOLOG;
- gce.ptszNick = TranslateT("Notifications");
- gce.ptszUID = idT;
-
- CallServiceSync(MS_GC_EVENT, 0, reinterpret_cast<LPARAM>(&gce));
+/*
+
+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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "common.h"
+#include <m_history.h>
+#include <m_userinfo.h>
+
+void FacebookProto::UpdateChat(const TCHAR *tchat_id, const char *id, const char *name, const char *message, DWORD timestamp, bool is_old)
+{
+ // replace % to %% to not interfere with chat color codes
+ std::string smessage = message;
+ utils::text::replace_all(&smessage, "%", "%%");
+
+ ptrT tid( mir_a2t(id));
+ ptrT tnick( mir_a2t_cp(name,CP_UTF8));
+ ptrT ttext( mir_a2t_cp(smessage.c_str(),CP_UTF8));
+
+ GCDEST gcd = { m_szModuleName, tchat_id, GC_EVENT_MESSAGE };
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.ptszText = ttext;
+ gce.time = timestamp ? timestamp : ::time(NULL);
+ if (id != NULL)
+ gce.bIsMe = !strcmp(id,facy.self_.user_id.c_str());
+ gce.dwFlags |= GCEF_ADDTOLOG;
+ if (is_old) {
+ gce.dwFlags |= GCEF_NOTNOTIFY;
+ gce.dwFlags &= ~GCEF_ADDTOLOG;
+ }
+ gce.ptszNick = tnick;
+ gce.ptszUID = tid;
+ CallServiceSync(MS_GC_EVENT,0,reinterpret_cast<LPARAM>(&gce));
+
+ // TODO: keep it here or move it somewhere else?
+ std::map<std::tstring, facebook_chatroom*>::iterator chatroom = facy.chat_rooms.find(tchat_id);
+ if (chatroom != facy.chat_rooms.end()) {
+ chatroom->second->message_readers.clear();
+ }
+}
+
+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, tchat_id, GC_EVENT_CHANGESESSIONAME };
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.ptszText = tname;
+ CallService(MS_GC_EVENT, 0, reinterpret_cast<LPARAM>(&gce));
+}
+
+int FacebookProto::OnGCEvent(WPARAM wParam,LPARAM lParam)
+{
+ GCHOOK *hook = reinterpret_cast<GCHOOK*>(lParam);
+
+ if (strcmp(hook->pDest->pszModule, m_szModuleName))
+ return 0;
+
+ // Ignore for special chatrooms
+ if (!_tcscmp(hook->pDest->ptszID, _T(FACEBOOK_NOTIFICATIONS_CHATROOM)))
+ return 0;
+
+ switch(hook->pDest->iType)
+ {
+ case GC_USER_MESSAGE:
+ {
+ std::string msg = _T2A(hook->ptszText, CP_UTF8);
+ std::string chat_id = _T2A(hook->pDest->ptszID, CP_UTF8);
+
+ if (isOnline()) {
+ debugLogA("**Chat - Outgoing message: %s", msg.c_str());
+ ForkThread(&FacebookProto::SendChatMsgWorker, new send_chat(chat_id, msg));
+ }
+
+ break;
+ }
+
+ case GC_USER_PRIVMESS:
+ {
+ facebook_user fbu;
+ fbu.user_id = _T2A(hook->ptszUID, CP_UTF8);
+
+ // Find this contact in list or add new temporary contact
+ MCONTACT hContact = AddToContactList(&fbu, CONTACT_NONE, false, true);
+
+ if (!hContact)
+ break;
+
+ CallService(MS_MSG_SENDMESSAGET, 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:
+ {
+ MCONTACT hContact = NULL;
+ if (hook->dwData == 10 || hook->dwData == 20) {
+ facebook_user fbu;
+ fbu.user_id = _T2A(hook->ptszUID, CP_UTF8);
+
+ // Find this contact in list or add new temporary contact
+ hContact = AddToContactList(&fbu, CONTACT_NONE, false, true);
+
+ if (!hContact)
+ break;
+ }
+
+ switch (hook->dwData)
+ {
+ case 10:
+ CallService(MS_USERINFO_SHOWDIALOG, hContact, 0);
+ break;
+
+ case 20:
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY, 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 TCHAR *tchat_id, const char *id, const char *name)
+{
+ ptrT tnick( mir_a2t_cp(name, CP_UTF8));
+ ptrT tid( mir_a2t(id));
+
+ GCDEST gcd = { m_szModuleName, tchat_id, GC_EVENT_JOIN };
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.pDest = &gcd;
+ gce.dwFlags = 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 = TranslateT("Myself");
+ } else {
+ MCONTACT hContact = ContactIDToHContact(id);
+ if (hContact == NULL || getByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, CONTACT_NONE) != CONTACT_FRIEND)
+ gce.ptszStatus = TranslateT("User");
+ else {
+ gce.ptszStatus = TranslateT("Friend");
+ }
+ }
+
+ CallServiceSync(MS_GC_EVENT, 0, reinterpret_cast<LPARAM>(&gce));
+}
+
+void FacebookProto::RemoveChatContact(const TCHAR *tchat_id, const char *id, const char *name)
+{
+ // We dont want to remove our self-contact from chat. Ever.
+ if (!strcmp(id, facy.self_.user_id.c_str()))
+ return;
+
+ ptrT tnick(mir_a2t_cp(name, CP_UTF8));
+ ptrT tid( mir_a2t(id));
+
+ GCDEST gcd = { m_szModuleName, tchat_id, GC_EVENT_PART };
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.dwFlags = GCEF_ADDTOLOG;
+ gce.ptszNick = tnick;
+ gce.ptszUID = tid;
+ gce.time = ::time(NULL);
+ gce.bIsMe = false;
+
+ CallServiceSync(MS_GC_EVENT,0,reinterpret_cast<LPARAM>(&gce));
+}
+
+/** Caller must free result */
+char *FacebookProto::GetChatUsers(const TCHAR *chat_id)
+{
+ GC_INFO gci = {0};
+ gci.Flags = GCF_USERS;
+ gci.pszModule = m_szModuleName;
+ gci.pszID = chat_id;
+ CallService(MS_GC_GETINFO, 0, (LPARAM)&gci);
+
+ debugLogA("**Chat - Users in chat %s: %s", _T2A(chat_id), gci.pszUsers);
+
+ // mir_free(gci.pszUsers);
+ return gci.pszUsers;
+}
+
+bool FacebookProto::IsChatContact(const TCHAR *chat_id, const char *id)
+{
+ ptrA users( GetChatUsers(chat_id));
+ return (users != NULL && strstr(users, id) != NULL);
+}
+
+void FacebookProto::AddChat(const TCHAR *tid, const TCHAR *tname)
+{
+ // Create the group chat session
+ GCSESSION gcw = { sizeof(gcw) };
+ gcw.iType = GCW_PRIVMESS;
+ gcw.ptszID = tid;
+ gcw.pszModule = m_szModuleName;
+ gcw.ptszName = tname;
+ CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
+
+ // Send setting events
+ GCDEST gcd = { m_szModuleName, tid, GC_EVENT_ADDGROUP };
+ GCEVENT gce = { sizeof(gce), &gcd };
+
+ // Create a user statuses
+ gce.ptszStatus = TranslateT("Myself");
+ CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
+ gce.ptszStatus = TranslateT("Friend");
+ CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
+ gce.ptszStatus = TranslateT("User");
+ CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
+
+ // Finish initialization
+ gcd.iType = GC_EVENT_CONTROL;
+ gce.time = ::time(NULL);
+ gce.pDest = &gcd;
+
+ bool hideChats = getBool(FACEBOOK_KEY_HIDE_CHATS, DEFAULT_HIDE_CHATS);
+
+ // Add self contact
+ AddChatContact(tid, facy.self_.user_id.c_str(), facy.self_.real_name.c_str());
+ CallServiceSync(MS_GC_EVENT, (hideChats ? WINDOW_HIDDEN : SESSION_INITDONE), reinterpret_cast<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
+}
+
+INT_PTR FacebookProto::OnJoinChat(WPARAM hContact, LPARAM suppress)
+{
+ // TODO: load info from server + old history,...
+
+ ptrT idT( getTStringA(hContact, "ChatRoomID"));
+ ptrT nameT( getTStringA(hContact, "Nick"));
+
+ if (idT && nameT)
+ AddChat(idT, nameT);
+
+/* GCSESSION gcw = {sizeof(gcw)};
+
+ // Create the group chat session
+ gcw.dwFlags = GC_TCHAR;
+ gcw.iType = GCW_PRIVMESS;
+ 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, m_tszUserName, GC_EVENT_ADDGROUP };
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.ptszStatus = TranslateT("Myself");
+ CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
+ gce.ptszStatus = TranslateT("Friend");
+ CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
+ gce.ptszStatus = TranslateT("User");
+ CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&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 wParam,LPARAM)
+{
+ ptrT idT(wParam ? getTStringA(wParam, "ChatRoomID") : NULL);
+
+ GCDEST gcd = { m_szModuleName, NULL, GC_EVENT_CONTROL };
+ gcd.ptszID = idT;
+
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.time = ::time(NULL);
+
+ CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE, reinterpret_cast<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT,SESSION_TERMINATE,reinterpret_cast<LPARAM>(&gce));
+ return 0;
+}
+
+/*
+void FacebookProto::SetChatStatus(int status)
+{
+ GCDEST gcd = { m_szModuleName, m_tszUserName, GC_EVENT_CONTROL };
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.time = ::time(NULL);
+
+ if(status == ID_STATUS_ONLINE)
+ {
+ // Add self contact
+ AddChatContact(facy.nick_.c_str());
+
+ CallServiceSync(MS_GC_EVENT,SESSION_INITDONE,reinterpret_cast<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT,SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
+ }
+ else
+ {
+ CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE,reinterpret_cast<LPARAM>(&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)
+ {
+ if (!_stricmp(facy.self_.user_id.c_str(), _T2A(gcmi->pszUID)))
+ {
+ /*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;
+ }
+ }
+
+ return 0;
+}
+
+bool FacebookProto::IsSpecialChatRoom(MCONTACT hContact) {
+ if (!isChatRoom(hContact))
+ return false;
+
+ ptrT idT(getTStringA(hContact, "ChatRoomID"));
+ return idT && !_tcscmp(idT, _T(FACEBOOK_NOTIFICATIONS_CHATROOM));
+}
+
+void FacebookProto::PrepareNotificationsChatRoom() {
+ if (!getBool(FACEBOOK_KEY_NOTIFICATIONS_CHATROOM, DEFAULT_NOTIFICATIONS_CHATROOM))
+ return;
+
+ // Prepare notifications chatroom if not exists
+ TCHAR *gidT = _T(FACEBOOK_NOTIFICATIONS_CHATROOM);
+
+ MCONTACT hNotificationsChatRoom = ChatIDToHContact(gidT);
+ if (hNotificationsChatRoom == NULL || getDword(hNotificationsChatRoom, "Status", ID_STATUS_OFFLINE) != ID_STATUS_ONLINE) {
+ TCHAR nameT[200];
+ mir_sntprintf(nameT, SIZEOF(nameT), _T("%s: %s"), m_tszUserName, TranslateT("Notifications"));
+
+ // Create the group chat session
+ GCSESSION gcw = { sizeof(gcw) };
+ gcw.iType = GCW_PRIVMESS;
+ gcw.ptszID = gidT;
+ gcw.pszModule = m_szModuleName;
+ gcw.ptszName = nameT;
+ CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
+
+ // Send setting events
+ GCDEST gcd = { m_szModuleName, gidT, GC_EVENT_CONTROL };
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.time = ::time(NULL);
+
+ CallServiceSync(MS_GC_EVENT, WINDOW_HIDDEN, reinterpret_cast<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
+ }
+}
+
+void FacebookProto::UpdateNotificationsChatRoom(facebook_notification *notification) {
+ if (!getBool(FACEBOOK_KEY_NOTIFICATIONS_CHATROOM, DEFAULT_NOTIFICATIONS_CHATROOM))
+ return;
+
+ std::stringstream text;
+ text << notification->text << "\n\n" << PrepareUrl(notification->link);
+
+ std::string message = text.str();
+ utils::text::replace_all(&message, "%", "%%");
+
+ ptrT idT(mir_tstrdup(_T(FACEBOOK_NOTIFICATIONS_CHATROOM)));
+ ptrT messageT(mir_a2t_cp(message.c_str(), CP_UTF8));
+
+ GCDEST gcd = { m_szModuleName, _T(FACEBOOK_NOTIFICATIONS_CHATROOM), GC_EVENT_MESSAGE };
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.ptszText = messageT;
+ gce.time = notification->time ? notification->time : ::time(NULL);
+ gce.bIsMe = false;
+ gce.dwFlags |= GCEF_ADDTOLOG;
+ gce.ptszNick = TranslateT("Notifications");
+ gce.ptszUID = idT;
+
+ CallServiceSync(MS_GC_EVENT, 0, reinterpret_cast<LPARAM>(&gce));
} \ No newline at end of file
diff --git a/protocols/FacebookRM/src/contacts.cpp b/protocols/FacebookRM/src/contacts.cpp
index 5da990e616..61acec9b56 100644
--- a/protocols/FacebookRM/src/contacts.cpp
+++ b/protocols/FacebookRM/src/contacts.cpp
@@ -326,7 +326,7 @@ void FacebookProto::LoadChatInfo(facebook_chatroom *fbc)
}
-MCONTACT FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, bool force_add)
+MCONTACT FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, bool force_add, bool add_temporarily)
{
// First, check if this contact exists (and if does, just return it)
if (!force_add) {
@@ -347,6 +347,11 @@ MCONTACT FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, b
// If we have some contact, we'll save its data
if (hContact) {
// Save these values only when adding new contact, not when updating existing
+ if (add_temporarily) {
+ db_set_b(hContact, "Clist", "Hidden", 1);
+ db_set_b(hContact, "Clist", "NotOnList", 1);
+ }
+
setString(hContact, FACEBOOK_KEY_ID, fbu->user_id.c_str());
std::string homepage = FACEBOOK_URL_PROFILE + fbu->user_id;
diff --git a/protocols/FacebookRM/src/proto.cpp b/protocols/FacebookRM/src/proto.cpp
index 463b7c1e89..ec8ee11424 100644
--- a/protocols/FacebookRM/src/proto.cpp
+++ b/protocols/FacebookRM/src/proto.cpp
@@ -288,16 +288,13 @@ MCONTACT FacebookProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
return NULL;
}
- MCONTACT hContact = AddToContactList(&fbu, CONTACT_NONE);
- if (hContact) {
- if (flags & PALF_TEMPORARY) {
- db_set_b(hContact, "Clist", "Hidden", 1);
- db_set_b(hContact, "Clist", "NotOnList", 1);
- }
- else if (db_get_b(hContact, "CList", "NotOnList", 0)) {
- db_unset(hContact, "CList", "Hidden");
- db_unset(hContact, "CList", "NotOnList");
- }
+ bool add_temporarily = (flags & PALF_TEMPORARY);
+ MCONTACT hContact = AddToContactList(&fbu, CONTACT_NONE, false, add_temporarily);
+
+ // Reset NotOnList flag if present and we're adding this contact not temporarily
+ if (hContact && !add_temporarily && db_get_b(hContact, "CList", "NotOnList", 0)) {
+ db_unset(hContact, "CList", "Hidden");
+ db_unset(hContact, "CList", "NotOnList");
}
return hContact;
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h
index 8f85582ca6..e0c95cf8f9 100644
--- a/protocols/FacebookRM/src/proto.h
+++ b/protocols/FacebookRM/src/proto.h
@@ -204,7 +204,7 @@ public:
MCONTACT ChatIDToHContact(const std::tstring&);
std::string ThreadIDToContactID(const std::string&);
void LoadContactInfo(facebook_user* fbu);
- MCONTACT AddToContactList(facebook_user*, ContactType type, bool force_add = false);
+ MCONTACT AddToContactList(facebook_user*, ContactType type, bool force_add = false, bool add_temporarily = false);
void SetAllContactStatuses(int status);
MCONTACT HContactFromAuthEvent(HANDLE hEvent);
void StartTyping(MCONTACT hContact);