void TwitterProto::SetChatStatus(int status) { GCDEST gcd = { m_szModuleName, m_tszUserName, GC_EVENT_CONTROL }; GCEVENT gce = { sizeof(gce), &gcd }; if (status == ID_STATUS_ONLINE) { // Add all friends to contact list for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { if (isChatRoom(hContact)) continue; DBVARIANT uid, nick; if (getString(hContact, TWITTER_KEY_UN, &uid)) continue; if (!db_get_s(hContact, "CList", "MyHandle", &nick)) { AddChatContact(uid.pszVal, nick.pszVal); db_free(&nick); } else AddChatContact(uid.pszVal); db_free(&uid); } // For some reason, I have to send an INITDONE message, even if I'm not actually // initializing the room... 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)); }
MCONTACT TwitterProto::AddToClientList(const char *name, const char *status) { // First, check if this contact exists MCONTACT hContact = UsernameToHContact(name); if (hContact) return hContact; if (in_chat_) AddChatContact(name); // If not, make a new contact! hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0); if (hContact) { if (Proto_AddToContact(hContact, m_szModuleName) == 0) { setString(hContact, TWITTER_KEY_UN, name); setWord(hContact, "Status", ID_STATUS_ONLINE); db_set_utf(hContact, "CList", "StatusMsg", status); std::string url = profile_base_url(twit_.get_base_url()) + http::url_encode(name); setString(hContact, "Homepage", url.c_str()); DBVARIANT dbv; if (!getTString(TWITTER_KEY_GROUP, &dbv)) { db_set_ts(hContact, "CList", "Group", dbv.ptszVal); db_free(&dbv); } return hContact; } CallService(MS_DB_CONTACT_DELETE, hContact, 0); } return 0; }
void CSkypeProto::OnGetChatInfo(const NETLIBHTTPREQUEST *response, void *p) { TCHAR *topic = (TCHAR*)p; if (response == NULL || response->pData == NULL) return; JSONNode root = JSONNode::parse(response->pData); if (!root) return; const JSONNode &members = root["members"]; const JSONNode &properties = root["properties"]; if (!properties["capabilities"] || properties["capabilities"].empty()) return; CMStringA chatId(ChatUrlToName(root["messages"].as_string().c_str())); StartChatRoom(_A2T(chatId), topic); for (size_t i = 0; i < members.size(); i++) { const JSONNode &member = members.at(i); CMStringA username(ContactUrlToName(member["userLink"].as_string().c_str())); std::string role = member["role"].as_string(); if (!IsChatContact(_A2T(chatId), username)) AddChatContact(_A2T(chatId), username, username, _A2T(role.c_str()), true); } PushRequest(new GetHistoryRequest(m_szRegToken, chatId, 15, true, 0, m_szServer), &CSkypeProto::OnGetServerHistory); mir_free(topic); }
INT_PTR FacebookProto::OnJoinChat(WPARAM hContact, LPARAM) { if (!m_enableChat || IsSpecialChatRoom(hContact)) return 0; ptrT idT(getTStringA(hContact, "ChatRoomID")); ptrT nameT(getTStringA(hContact, "Nick")); ptrA threadId(getStringA(hContact, FACEBOOK_KEY_TID)); if (!idT || !nameT || !threadId) return 0; facebook_chatroom *fbc; std::string tthread_id = threadId; auto it = facy.chat_rooms.find(tthread_id); if (it != facy.chat_rooms.end()) { fbc = it->second; } else { // We don't have this chat loaded in memory yet, lets load some info (name, list of users) fbc = new facebook_chatroom(tthread_id); LoadChatInfo(fbc); facy.chat_rooms.insert(std::make_pair(tthread_id, fbc)); } // RM TODO: better use check if chatroom exists/is in db/is online... no? // like: if (ChatIDToHContact(tthread_id) == NULL) { ptrA users(GetChatUsers(tthread_id.c_str())); if (users == NULL) { // Add chatroom AddChat(fbc->thread_id.c_str(), fbc->chat_name.c_str()); // Add chat contacts for (std::map<std::string, std::string>::iterator jt = fbc->participants.begin(); jt != fbc->participants.end(); ++jt) { AddChatContact(fbc->thread_id.c_str(), jt->first.c_str(), jt->second.c_str()); } // Load last messages delSetting(hContact, FACEBOOK_KEY_MESSAGE_ID); // We're creating new chatroom so we want load all recent messages ForkThread(&FacebookProto::LoadLastMessages, new MCONTACT(hContact)); } return 0; }
void FacebookProto::AddChat(const char *id, const char *name) { GCSESSION gcw = {sizeof(gcw)}; // Create the group chat session gcw.dwFlags = GC_TCHAR; gcw.iType = GCW_CHATROOM; gcw.pszModule = m_szModuleName; gcw.ptszName = mir_a2t_cp(name, CP_UTF8); gcw.ptszID = mir_a2t(id); CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw); mir_free(const_cast<TCHAR*>(gcw.ptszName)); mir_free(const_cast<TCHAR*>(gcw.ptszID)); // Send setting events GCDEST gcd = { m_szModuleName }; gcd.ptszID = mir_a2t(id); 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<LPARAM>(&gce) ); gce.ptszStatus = _T("Normal"); CallServiceSync( MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce) ); // Finish initialization gcd.iType = GC_EVENT_CONTROL; gce.time = ::time(NULL); gce.pDest = &gcd; // 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<LPARAM>(&gce)); CallServiceSync(MS_GC_EVENT,SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce)); mir_free(const_cast<TCHAR*>(gcd.ptszID)); }
void FacebookProto::AddChat(const char *id, const TCHAR *tname) { ptrT tid(mir_a2t(id)); // 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(id, 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)); }
void CSkypeProto::OnChatEvent(const JSONNode &node) { //std::string clientMsgId = node["clientmessageid"].as_string(); //std::string skypeEditedId = node["skypeeditedid"].as_string(); std::string fromLink = node["from"].as_string(); CMStringA from(ContactUrlToName(fromLink.c_str())); time_t timestamp = IsoToUnixTime(node["composetime"].as_string().c_str()); std::string content = node["content"].as_string(); int emoteOffset = node["skypeemoteoffset"].as_int(); std::string conversationLink = node["conversationLink"].as_string(); CMStringA chatname(ChatUrlToName(conversationLink.c_str())); CMString topic(node["threadtopic"].as_mstring()); if (FindChatRoom(chatname) == NULL) SendRequest(new GetChatInfoRequest(m_szRegToken, chatname, m_szServer), &CSkypeProto::OnGetChatInfo, topic.Detach()); std::string messageType = node["messagetype"].as_string(); if (!mir_strcmpi(messageType.c_str(), "Text") || !mir_strcmpi(messageType.c_str(), "RichText")) { AddMessageToChat(_A2T(chatname), _A2T(from), content.c_str(), emoteOffset != NULL, emoteOffset, timestamp); } else if (!mir_strcmpi(messageType.c_str(), "ThreadActivity/AddMember")) { ptrA xinitiator, xtarget, initiator; //content = <addmember><eventtime>1429186229164</eventtime><initiator>8:initiator</initiator><target>8:user</target></addmember> HXML xml = xmlParseString(ptrT(mir_a2t(content.c_str())), 0, _T("addmember")); if (xml == NULL) return; for (int i = 0; i < xmlGetChildCount(xml); i++) { HXML xmlNode = xmlGetNthChild(xml, L"target", i); if (xmlNode == NULL) break; xtarget = mir_t2a(xmlGetText(xmlNode)); CMStringA target = ParseUrl(xtarget, "8:"); AddChatContact(_A2T(chatname), target, target, L"User"); } xmlDestroyNode(xml); } else if (!mir_strcmpi(messageType.c_str(), "ThreadActivity/DeleteMember")) { ptrA xinitiator, xtarget; //content = <addmember><eventtime>1429186229164</eventtime><initiator>8:initiator</initiator><target>8:user</target></addmember> HXML xml = xmlParseString(ptrT(mir_a2t(content.c_str())), 0, _T("deletemember")); if (xml != NULL) { HXML xmlNode = xmlGetChildByPath(xml, _T("initiator"), 0); xinitiator = node != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlNode = xmlGetChildByPath(xml, _T("target"), 0); xtarget = xmlNode != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlDestroyNode(xml); } if (xtarget == NULL) return; CMStringA target = ParseUrl(xtarget, "8:"); CMStringA initiator = ParseUrl(xinitiator, "8:"); RemoveChatContact(_A2T(chatname), target, target, true, initiator); } else if (!mir_strcmpi(messageType.c_str(), "ThreadActivity/TopicUpdate")) { //content=<topicupdate><eventtime>1429532702130</eventtime><initiator>8:user</initiator><value>test topic</value></topicupdate> ptrA xinitiator, value; HXML xml = xmlParseString(ptrT(mir_a2t(content.c_str())), 0, _T("topicupdate")); if (xml != NULL) { HXML xmlNode = xmlGetChildByPath(xml, _T("initiator"), 0); xinitiator = xmlNode != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlNode = xmlGetChildByPath(xml, _T("value"), 0); value = xmlNode != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlDestroyNode(xml); } CMStringA initiator = ParseUrl(xinitiator, "8:"); RenameChat(chatname, value); ChangeChatTopic(chatname, value, initiator); } else if (!mir_strcmpi(messageType.c_str(), "ThreadActivity/RoleUpdate")) { //content=<roleupdate><eventtime>1429551258363</eventtime><initiator>8:user</initiator><target><id>8:user1</id><role>admin</role></target></roleupdate> ptrA xinitiator, xId, xRole; HXML xml = xmlParseString(ptrT(mir_a2t(content.c_str())), 0, _T("roleupdate")); if (xml != NULL) { HXML xmlNode = xmlGetChildByPath(xml, _T("initiator"), 0); xinitiator = xmlNode != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlNode = xmlGetChildByPath(xml, _T("target"), 0); if (xmlNode != NULL) { HXML xmlId = xmlGetChildByPath(xmlNode, _T("id"), 0); HXML xmlRole = xmlGetChildByPath(xmlNode, _T("role"), 0); xId = xmlId != NULL ? mir_t2a(xmlGetText(xmlId)) : NULL; xRole = xmlRole != NULL ? mir_t2a(xmlGetText(xmlRole)) : NULL; } xmlDestroyNode(xml); CMStringA initiator = ParseUrl(xinitiator, "8:"); CMStringA id = ParseUrl(xId, "8:"); GCDEST gcd = { m_szModuleName, _A2T(chatname), !mir_strcmpi(xRole, "Admin") ? GC_EVENT_ADDSTATUS : GC_EVENT_REMOVESTATUS }; GCEVENT gce = { sizeof(gce), &gcd }; ptrT tszId(mir_a2t(id)); ptrT tszRole(mir_a2t(xRole)); ptrT tszInitiator(mir_a2t(initiator)); gce.pDest = &gcd; gce.dwFlags = GCEF_ADDTOLOG; gce.ptszNick = tszId; gce.ptszUID = tszId; gce.ptszText = tszInitiator; gce.time = time(NULL); gce.bIsMe = IsMe(id); gce.ptszStatus = TranslateT("Admin"); CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); } } }
int __cdecl AddMembers(char *szSkypeMsg) { BYTE *contactmask=NULL; DBVARIANT dbv2; CONTACTINFO ci={0}; char *ptr, *who, *nextoken; TCHAR *szChatId; int i, iRet = 0; gchat_contacts *gc; LOG(("AddMembers STARTED")); if (!(ptr=strstr(szSkypeMsg, " MEMBERS"))) return -1; EnterCriticalSection(&m_GCMutex); ptr[0]=0; szChatId = make_nonutf_tchar_string((const unsigned char*)szSkypeMsg+5); ptr+=9; if (find_chat(szChatId) && (gc=GetChat(szChatId)) && !db_get_s(NULL, SKYPE_PROTONAME, SKYPE_NAME, &dbv2)) { char *pszMemObjs, *token; if (protocol>=7 && (pszMemObjs = SkypeGet ("CHAT", szSkypeMsg+5, "MEMBEROBJECTS"))) { // Add new contacts (protocol 7+ with memberobjects, supports roles) for (token=strtok_r(pszMemObjs, ", ", &nextoken); token; token=strtok_r(NULL, ", ", &nextoken)) { if (!(who = SkypeGet ("CHATMEMBER", token, "IDENTITY"))) continue; if (strcmp(who, dbv2.pszVal)) { char *pszRole; TCHAR *ptszRole = NULL; if (pszRole = SkypeGet ("CHATMEMBER", token, "ROLE")) ptszRole = make_nonutf_tchar_string((const unsigned char*)pszRole); i=AddChatContact(gc, who, ptszRole); free_nonutf_tchar_string (ptszRole); if (pszRole) free (pszRole); if (i>=0 && !contactmask && !(contactmask = (unsigned char*)calloc(gc->mJoinedCount, 1))) i=-2; if (!(contactmask= (unsigned char *) realloc(contactmask, gc->mJoinedCount))) { iRet = -1; free (who); break; } contactmask[i]=TRUE; } free (who); } free (pszMemObjs); } else { // Add new contacts (normal) for (who=strtok_r(ptr, " ", &nextoken); who; who=strtok_r(NULL, " ", &nextoken)) { if (strcmp(who, dbv2.pszVal)) { i=AddChatContact(gc, who, NULL); if (i>=0 && !contactmask && !(contactmask = (unsigned char*)calloc(gc->mJoinedCount, 1))) i=-2; if (i<0 || !(contactmask= (unsigned char *) realloc(contactmask, gc->mJoinedCount))) { iRet = -1; break; } contactmask[i]=TRUE; } } } // Quit contacts which are no longer there if (iRet == 0 && contactmask) { GCDEST gcd = { SKYPE_PROTONAME, szChatId, GC_EVENT_QUIT }; GCEVENT gce = { sizeof(gce), &gcd }; gce.time = (DWORD)time(NULL); gce.dwFlags = GCEF_ADDTOLOG; ci.cbSize = sizeof(ci); ci.szProto = SKYPE_PROTONAME; ci.dwFlag = CNF_DISPLAY; for (i=0;i<gc->mJoinedCount;i++) if (!contactmask[i]) { ci.hContact = gc->mJoinedContacts[i].hContact; ci.dwFlag = CNF_TCHAR; if (ci.hContact && !CallService(MS_CONTACT_GETCONTACTINFO,0,(LPARAM)&ci)) gce.ptszNick=ci.pszVal; else gce.ptszNick=gc->mJoinedContacts[i].who; RemChatContact(gc, gc->mJoinedContacts[i].who); gce.ptszUID = gc->mJoinedContacts[i].who; CallService(MS_GC_EVENT, 0, (LPARAM)&gce); if (ci.pszVal) { mir_free (ci.pszVal); ci.pszVal=NULL; } } // We don't do this, because the dialog group-chat may have been started intentionally /* if (gc->mJoinedCount == 1) { // switch back to normal session KillChatSession(&gcd); } */ } if (contactmask) free(contactmask); db_free(&dbv2); } else iRet = -1; free_nonutf_tchar_string (szChatId); LeaveCriticalSection(&m_GCMutex); LOG(("AddMembers DONE")); return iRet; }