void TwitterProto::SignOn(void*) { debugLogA( _T("***** Beginning SignOn process")); WaitForSingleObject(&signon_lock_,INFINITE); // Kill the old thread if it's still around // this doesn't seem to work.. should we wait infinitely? if(hMsgLoop_) { debugLogA( _T("***** Requesting MessageLoop to exit")); QueueUserAPC(APC_callback,hMsgLoop_,(ULONG_PTR)this); debugLogA( _T("***** Waiting for old MessageLoop to exit")); //WaitForSingleObject(hMsgLoop_,INFINITE); WaitForSingleObject(hMsgLoop_,180000); CloseHandle(hMsgLoop_); } if(NegotiateConnection()) // Could this be? The legendary Go Time?? { if(!in_chat_ && db_get_b(0,m_szModuleName,TWITTER_KEY_CHATFEED,0)) OnJoinChat(0,true); SetAllContactStatuses(ID_STATUS_ONLINE); hMsgLoop_ = ForkThreadEx(&TwitterProto::MessageLoop, NULL, 0); } ReleaseMutex(signon_lock_); debugLogA( _T("***** SignOn complete")); }
FacebookProto::FacebookProto(const char* proto_name,const TCHAR* username) : PROTO<FacebookProto>(proto_name, username) { facy.parent = this; signon_lock_ = CreateMutex(NULL, FALSE, NULL); avatar_lock_ = CreateMutex(NULL, FALSE, NULL); log_lock_ = CreateMutex(NULL, FALSE, NULL); update_loop_lock_ = CreateEvent(NULL, FALSE, FALSE, NULL); facy.buddies_lock_ = CreateMutex(NULL, FALSE, NULL); facy.send_message_lock_ = CreateMutex(NULL, FALSE, NULL); facy.fcb_conn_lock_ = CreateMutex(NULL, FALSE, NULL); m_invisible = false; CreateProtoService(PS_CREATEACCMGRUI, &FacebookProto::SvcCreateAccMgrUI); CreateProtoService(PS_GETMYAWAYMSG, &FacebookProto::GetMyAwayMsg); CreateProtoService(PS_GETMYAVATART, &FacebookProto::GetMyAvatar); CreateProtoService(PS_GETAVATARINFOT, &FacebookProto::GetAvatarInfo); CreateProtoService(PS_GETAVATARCAPS, &FacebookProto::GetAvatarCaps); CreateProtoService(PS_GETUNREADEMAILCOUNT, &FacebookProto::GetNotificationsCount); CreateProtoService(PS_JOINCHAT, &FacebookProto::OnJoinChat); CreateProtoService(PS_LEAVECHAT, &FacebookProto::OnLeaveChat); CreateProtoService("/Mind", &FacebookProto::OnMind); HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &FacebookProto::OnBuildStatusMenu); HookProtoEvent(ME_OPT_INITIALISE, &FacebookProto::OnOptionsInit); HookProtoEvent(ME_IDLE_CHANGED, &FacebookProto::OnIdleChanged); HookProtoEvent(ME_TTB_MODULELOADED, &FacebookProto::OnToolbarInit); HookProtoEvent(ME_GC_EVENT, &FacebookProto::OnGCEvent); HookProtoEvent(ME_GC_BUILDMENU, &FacebookProto::OnGCMenuHook); HookProtoEvent(ME_DB_EVENT_MARKED_READ, &FacebookProto::OnDbEventRead); HookProtoEvent(ME_MSG_WINDOWEVENT, &FacebookProto::OnProcessSrmmEvent); db_set_resident(m_szModuleName, "Status"); db_set_resident(m_szModuleName, "IdleTS"); InitHotkeys(); InitPopups(); InitSounds(); // Create standard network connection TCHAR descr[512]; NETLIBUSER nlu = {sizeof(nlu)}; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; nlu.szSettingsModule = m_szModuleName; mir_sntprintf(descr, SIZEOF(descr), TranslateT("%s server connection"), m_tszUserName); nlu.ptszDescriptiveName = descr; m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); if (m_hNetlibUser == NULL) MessageBox(NULL, TranslateT("Unable to get Netlib connection for Facebook"), m_tszUserName, MB_OK); facy.set_handle(m_hNetlibUser); // Set all contacts offline -- in case we crashed SetAllContactStatuses(ID_STATUS_OFFLINE); }
FacebookProto::FacebookProto(const char* proto_name,const TCHAR* username) { m_iVersion = 2; m_szProtoName = mir_strdup( proto_name ); m_szModuleName = mir_strdup( proto_name ); m_tszUserName = mir_tstrdup( username ); facy.parent = this; signon_lock_ = CreateMutex( NULL, FALSE, NULL ); avatar_lock_ = CreateMutex( NULL, FALSE, NULL ); log_lock_ = CreateMutex( NULL, FALSE, NULL ); update_loop_lock_ = CreateEvent( NULL, FALSE, FALSE, NULL); facy.buddies_lock_ = CreateMutex( NULL, FALSE, NULL ); facy.send_message_lock_ = CreateMutex( NULL, FALSE, NULL ); facy.fcb_conn_lock_ = CreateMutex( NULL, FALSE, NULL ); CreateProtoService(m_szModuleName, PS_CREATEACCMGRUI, &FacebookProto::SvcCreateAccMgrUI, this); CreateProtoService(m_szModuleName, PS_GETMYAWAYMSG, &FacebookProto::GetMyAwayMsg, this); CreateProtoService(m_szModuleName, PS_GETMYAVATAR, &FacebookProto::GetMyAvatar, this); CreateProtoService(m_szModuleName, PS_GETAVATARINFO, &FacebookProto::GetAvatarInfo, this); CreateProtoService(m_szModuleName, PS_GETAVATARCAPS, &FacebookProto::GetAvatarCaps, this); CreateProtoService(m_szModuleName, PS_JOINCHAT, &FacebookProto::OnJoinChat, this); CreateProtoService(m_szModuleName, PS_LEAVECHAT, &FacebookProto::OnLeaveChat, this); HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &FacebookProto::OnBuildStatusMenu, this); HookProtoEvent(ME_OPT_INITIALISE, &FacebookProto::OnOptionsInit, this); HookProtoEvent(ME_GC_EVENT, &FacebookProto::OnChatOutgoing, this); HookProtoEvent(ME_IDLE_CHANGED, &FacebookProto::OnIdleChanged, this); // Create standard network connection TCHAR descr[512]; NETLIBUSER nlu = {sizeof(nlu)}; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; nlu.szSettingsModule = m_szModuleName; char module[512]; mir_snprintf(module,SIZEOF(module),"%sAv",m_szModuleName); nlu.szSettingsModule = module; mir_sntprintf(descr,SIZEOF(descr),TranslateT("%s server connection"),m_tszUserName); nlu.ptszDescriptiveName = descr; m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER,0,(LPARAM)&nlu); if(m_hNetlibUser == NULL) MessageBox(NULL,TranslateT("Unable to get Netlib connection for Facebook"),m_tszUserName,MB_OK); facy.set_handle(m_hNetlibUser); SkinAddNewSoundExT( "Notification", m_tszUserName, LPGENT( "Notification" ) ); SkinAddNewSoundExT( "NewsFeed", m_tszUserName, LPGENT( "News Feed" ) ); SkinAddNewSoundExT( "OtherEvent", m_tszUserName, LPGENT( "Other Event" ) ); char *profile = Utils_ReplaceVars("%miranda_avatarcache%"); def_avatar_folder_ = std::string(profile)+"\\"+m_szModuleName; mir_free(profile); hAvatarFolder_ = FoldersRegisterCustomPath(m_szModuleName, "Avatars", def_avatar_folder_.c_str()); // Set all contacts offline -- in case we crashed SetAllContactStatuses( ID_STATUS_OFFLINE ); }
void CVkProto::OnLoggedOut() { m_bOnline = false; if (m_pollingConn) CallService(MS_NETLIB_SHUTDOWN, (WPARAM)m_pollingConn, 0); ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE); m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; CallFunctionAsync(VKUnsetTimer, this); SetAllContactStatuses(ID_STATUS_OFFLINE); m_chats.destroy(); }
int TwitterProto::OnModulesLoaded(WPARAM, LPARAM) { TCHAR descr[512]; NETLIBUSER nlu = { sizeof(nlu) }; nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_TCHAR; nlu.szSettingsModule = m_szModuleName; // Create standard network connection mir_sntprintf(descr, TranslateT("%s server connection"), m_tszUserName); nlu.ptszDescriptiveName = descr; m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); if (m_hNetlibUser == NULL) { TCHAR error[200]; mir_sntprintf(error, TranslateT("Unable to initialize Netlib for %s."), m_tszUserName); MessageBox(NULL, error, _T("Miranda NG"), MB_OK | MB_ICONERROR); } // Create avatar network connection (TODO: probably remove this) char module[512]; mir_snprintf(module, "%sAv", m_szModuleName); nlu.szSettingsModule = module; mir_sntprintf(descr, TranslateT("%s avatar connection"), m_tszUserName); nlu.ptszDescriptiveName = descr; hAvatarNetlib_ = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); if (hAvatarNetlib_ == NULL) { TCHAR error[200]; mir_sntprintf(error, TranslateT("Unable to initialize Netlib for %s."), TranslateT("Twitter (avatars)")); MessageBox(NULL, error, _T("Miranda NG"), MB_OK | MB_ICONERROR); } twit_.set_handle(this, m_hNetlibUser); GCREGISTER gcr = { sizeof(gcr) }; gcr.pszModule = m_szModuleName; gcr.ptszDispName = m_tszUserName; gcr.iMaxText = 159; CallService(MS_GC_REGISTER, 0, reinterpret_cast<LPARAM>(&gcr)); DBEVENTTYPEDESCR evt = { sizeof(evt) }; evt.eventType = TWITTER_DB_EVENT_TYPE_TWEET; evt.module = m_szModuleName; evt.descr = "Tweet"; evt.flags = DETF_HISTORY | DETF_MSGWINDOW; CallService(MS_DB_EVENT_REGISTERTYPE, 0, reinterpret_cast<LPARAM>(&evt)); SetAllContactStatuses(ID_STATUS_OFFLINE); // In case we crashed last time return 0; }
WhatsAppProto::WhatsAppProto(const char *proto_name, const TCHAR *username) : PROTO<WhatsAppProto>(proto_name, username), m_tszDefaultGroup(getTStringA(WHATSAPP_KEY_DEF_GROUP)) { update_loop_lock_ = CreateEvent(NULL, false, false, NULL); db_set_resident(m_szModuleName, "StatusMsg"); CreateProtoService(PS_CREATEACCMGRUI, &WhatsAppProto::SvcCreateAccMgrUI); CreateProtoService(PS_GETAVATARINFO, &WhatsAppProto::GetAvatarInfo); CreateProtoService(PS_GETAVATARCAPS, &WhatsAppProto::GetAvatarCaps); CreateProtoService(PS_GETMYAVATAR, &WhatsAppProto::GetMyAvatar); CreateProtoService(PS_SETMYAVATAR, &WhatsAppProto::SetMyAvatar); HookProtoEvent(ME_DB_CONTACT_DELETED, &WhatsAppProto::OnDeleteChat); HookProtoEvent(ME_OPT_INITIALISE, &WhatsAppProto::OnOptionsInit); HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &WhatsAppProto::OnBuildStatusMenu); // Create standard network connection TCHAR descr[512]; mir_sntprintf(descr, TranslateT("%s server connection"), m_tszUserName); NETLIBUSER nlu = { sizeof(nlu) }; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; nlu.szSettingsModule = m_szModuleName; nlu.ptszDescriptiveName = descr; m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); if (m_hNetlibUser == NULL) { TCHAR error[200]; mir_sntprintf(error, TranslateT("Unable to initialize Netlib for %s."), m_tszUserName); MessageBox(NULL, error, _T("Miranda NG"), MB_OK | MB_ICONERROR); } WASocketConnection::initNetwork(m_hNetlibUser); m_tszAvatarFolder = std::tstring(VARST(_T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName; DWORD dwAttributes = GetFileAttributes(m_tszAvatarFolder.c_str()); if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) CreateDirectoryTreeT(m_tszAvatarFolder.c_str()); if (m_tszDefaultGroup == NULL) m_tszDefaultGroup = mir_tstrdup(_T("WhatsApp")); Clist_CreateGroup(0, m_tszDefaultGroup); SetAllContactStatuses(ID_STATUS_OFFLINE, true); }
void CVkProto::OnLoggedOut() { debugLogA("CVkProto::OnLoggedOut"); m_bOnline = false; if (m_pollingConn) CallService(MS_NETLIB_SHUTDOWN, (WPARAM)m_pollingConn); ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE); m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; bool bOnline = false; { mir_cslock lck(csInstances); for (int i = 0; i < vk_Instances.getCount(); i++) bOnline = bOnline || vk_Instances[i]->IsOnline(); } if (!bOnline) CallFunctionAsync(VKUnsetTimer, this); SetAllContactStatuses(ID_STATUS_OFFLINE); m_chats.destroy(); }
CVkProto::CVkProto(const char *szModuleName, const TCHAR *ptszUserName) : PROTO<CVkProto>(szModuleName, ptszUserName), m_arRequestsQueue(10), m_sendIds(3, PtrKeySortT), m_cookies(5), m_msgId(1), m_chats(1, NumericKeySortT) { InitQueue(); CreateProtoService(PS_CREATEACCMGRUI, &CVkProto::SvcCreateAccMgrUI); CreateProtoService(PS_GETAVATARINFOT, &CVkProto::SvcGetAvatarInfo); CreateProtoService(PS_GETAVATARCAPS, &CVkProto::SvcGetAvatarCaps); HookProtoEvent(ME_OPT_INITIALISE, &CVkProto::OnOptionsInit); TCHAR descr[512]; mir_sntprintf(descr, SIZEOF(descr), TranslateT("%s server connection"), m_tszUserName); NETLIBUSER nlu = {sizeof(nlu)}; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; nlu.szSettingsModule = m_szModuleName; nlu.szSettingsModule = m_szModuleName; nlu.ptszDescriptiveName = descr; m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); m_defaultGroup = getTStringA("ProtoGroup"); if (m_defaultGroup == NULL) m_defaultGroup = mir_tstrdup(_T("VKontakte")); Clist_CreateGroup(NULL, m_defaultGroup); db_set_resident(m_szModuleName, "Status"); m_bServerDelivery = getBool("ServerDelivery", true); m_bHideChats = getBool("HideChats", true); // Set all contacts offline -- in case we crashed SetAllContactStatuses(ID_STATUS_OFFLINE); }
WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) : PROTO<WhatsAppProto>(proto_name, username) { this->challenge = new std::vector<unsigned char>; this->msgId = 0; this->msgIdHeader = time(NULL); update_loop_lock_ = CreateEvent(NULL, false, false, NULL); FMessage::generating_lock = new Mutex(); CreateProtoService(PS_CREATEACCMGRUI, &WhatsAppProto::SvcCreateAccMgrUI); CreateProtoService(PS_JOINCHAT, &WhatsAppProto::OnJoinChat); CreateProtoService(PS_LEAVECHAT, &WhatsAppProto::OnLeaveChat); HookProtoEvent(ME_OPT_INITIALISE, &WhatsAppProto::OnOptionsInit); HookProtoEvent(ME_SYSTEM_MODULESLOADED, &WhatsAppProto::OnModulesLoaded); HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &WhatsAppProto::OnBuildStatusMenu); this->InitContactMenus(); // Create standard network connection TCHAR descr[512]; NETLIBUSER nlu = {sizeof(nlu)}; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; char module[512]; mir_snprintf(module, SIZEOF(module), "%s", m_szModuleName); nlu.szSettingsModule = module; mir_sntprintf(descr, SIZEOF(descr), TranslateT("%s server connection"), m_tszUserName); nlu.ptszDescriptiveName = descr; m_hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); if (m_hNetlibUser == NULL) MessageBox(NULL, TranslateT("Unable to get Netlib connection for WhatsApp"), m_tszUserName, MB_OK); WASocketConnection::initNetwork(m_hNetlibUser); def_avatar_folder_ = std::tstring( VARST( _T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName; SetAllContactStatuses(ID_STATUS_OFFLINE, true); }
int TwitterProto::SetStatus(int new_status) { int old_status = m_iStatus; if (new_status == m_iStatus) return 0; m_iDesiredStatus = new_status; // 40072 - 40080 are the "online" statuses, basically every status except offline. see statusmodes.h if (new_status >= 40072 && new_status <= 40080) { m_iDesiredStatus = ID_STATUS_ONLINE; //i think i have to set this so it forces the twitter proto to be online (and not away, DND, etc) // if we're already connecting and they want to go online, BAIL! we're already trying to connect you dumbass if (old_status == ID_STATUS_CONNECTING) return 0; // if we're already connected, and we change to another connected status, don't try and reconnect! if (old_status >= 40072 && old_status <= 40080) return 0; // i think here we tell the proto interface struct that we're connecting, just so it knows m_iStatus = ID_STATUS_CONNECTING; // ok.. here i think we're telling the core that this protocol something.. but why? ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); ForkThread(&TwitterProto::SignOn, this); } else if (new_status == ID_STATUS_OFFLINE) { twit_.Disconnect(); m_iStatus = m_iDesiredStatus; SetAllContactStatuses(ID_STATUS_OFFLINE); ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); } return 0; }
void WhatsAppProto::stayConnectedLoop(void*) { ptrA cc(getStringA(WHATSAPP_KEY_CC)); if (mir_strlen(cc) == 0) { NotifyEvent(m_tszUserName, TranslateT("Please enter a country code."), NULL, WHATSAPP_EVENT_CLIENT); return; } ptrA in(getStringA(WHATSAPP_KEY_LOGIN)); if (mir_strlen(in) == 0) { NotifyEvent(m_tszUserName, TranslateT("Please enter a phone number without country code."), NULL, WHATSAPP_EVENT_CLIENT); return; } m_szPhoneNumber = std::string(cc) + std::string(in); m_szJid = m_szPhoneNumber + "@s.whatsapp.net"; ptrA szNick(getStringA(WHATSAPP_KEY_NICK)); if (mir_strlen(szNick) == 0) { NotifyEvent(m_tszUserName, TranslateT("Please enter a nickname."), NULL, WHATSAPP_EVENT_CLIENT); return; } m_szNick = szNick; ptrA szPassword(getStringA(WHATSAPP_KEY_PASS)); if (mir_strlen(szPassword) == 0) { NotifyEvent(m_tszUserName, TranslateT("Please enter a password."), NULL, WHATSAPP_EVENT_CLIENT); return; } // ----------------------------- Mutex writerMutex; bool error = false; m_pSocket = NULL; while (true) { if (m_pConnection != NULL) { delete m_pConnection; m_pConnection = NULL; } if (m_pSocket != NULL) { delete m_pSocket; m_pSocket = NULL; } if (m_iDesiredStatus == ID_STATUS_OFFLINE || error) { debugLogA("Set status to offline"); SetAllContactStatuses(ID_STATUS_OFFLINE, true); ToggleStatusMenuItems(false); int prevStatus = m_iStatus; m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)prevStatus, m_iStatus); break; } debugLogA("Connecting..."); try { unsigned passLen; ptrA passBin((char*)mir_base64_decode(szPassword, &passLen)); std::string password(passBin, passLen), resource = ACCOUNT_RESOURCE; int portNumber; if (getByte(WHATSAPP_KEY_SSL, 0)) portNumber = 443, resource += "-443"; else portNumber = 5222, resource += "-5222"; m_pSocket = new WASocketConnection("c.whatsapp.net", portNumber); m_pConnection = new WAConnection(m_szPhoneNumber, resource, &connMutex, &writerMutex, m_pSocket, this, this); { WALogin login(m_pConnection, password); m_Challenge = login.login(m_Challenge); m_pConnection->setLogin(&login); } m_pConnection->nick = m_szNick; if (m_iDesiredStatus != ID_STATUS_INVISIBLE) m_pConnection->sendAvailableForChat(); debugLogA("Set status to online"); m_iStatus = m_iDesiredStatus; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus); ToggleStatusMenuItems(true); ForkThread(&WhatsAppProto::ProcessBuddyList, NULL); // #TODO Move out of try block. Exception is expected on disconnect while (true) { m_tLastWriteTime = time(NULL); if (!m_pConnection->read()) break; } debugLogA("Exit from read-loop"); } catch (WAException &e) { debugLogA("Exception: %s", e.what()); error = true; } catch (exception &e) { debugLogA("Exception: %s", e.what()); error = true; } catch (...) { debugLogA("Unknown exception"); error = true; } } debugLogA("Break out from loop"); }
int WhatsAppProto::SetStatus(int new_status) { if (m_iDesiredStatus == new_status) return 0; int oldStatus = m_iStatus; debugLogA("===== Beginning SetStatus process"); // Routing statuses not supported by WhatsApp switch (new_status) { case ID_STATUS_INVISIBLE: case ID_STATUS_OFFLINE: m_iDesiredStatus = new_status; break; case ID_STATUS_IDLE: default: m_iDesiredStatus = ID_STATUS_INVISIBLE; if (getByte(WHATSAPP_KEY_MAP_STATUSES, DEFAULT_MAP_STATUSES)) break; case ID_STATUS_ONLINE: case ID_STATUS_FREECHAT: m_iDesiredStatus = ID_STATUS_ONLINE; break; } if (m_iDesiredStatus == ID_STATUS_OFFLINE) { if (m_pSocket != NULL) { SetEvent(update_loop_lock_); m_pSocket->forceShutdown(); debugLogA("Forced shutdown"); } m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); } else if (m_pSocket == NULL && !IsStatusConnecting(m_iStatus)) { m_iStatus = ID_STATUS_CONNECTING; ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); ResetEvent(update_loop_lock_); ForkThread(&WhatsAppProto::sentinelLoop, 0); ForkThread(&WhatsAppProto::stayConnectedLoop, 0); } else if (m_pConnection != NULL) { if (m_iDesiredStatus == ID_STATUS_ONLINE) { m_pConnection->sendAvailableForChat(); m_iStatus = ID_STATUS_ONLINE; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); } else if (m_iStatus == ID_STATUS_ONLINE && m_iDesiredStatus == ID_STATUS_INVISIBLE) { m_pConnection->sendClose(); m_iStatus = ID_STATUS_INVISIBLE; SetAllContactStatuses(ID_STATUS_OFFLINE, true); ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); } } else ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); return 0; }
void FacebookProto::ChangeStatus(void*) { ScopedLock s(signon_lock_); ScopedLock b(facy.buddies_lock_); int new_status = m_iDesiredStatus; int old_status = m_iStatus; if (new_status == ID_STATUS_OFFLINE) { // Logout debugLogA("### Beginning SignOff process"); m_signingOut = true; SetEvent(update_loop_lock_); // Shutdown and close channel handle Netlib_Shutdown(facy.hMsgCon); if (facy.hMsgCon) Netlib_CloseHandle(facy.hMsgCon); facy.hMsgCon = NULL; // Turn off chat on Facebook if (getByte(FACEBOOK_KEY_DISCONNECT_CHAT, DEFAULT_DISCONNECT_CHAT)) facy.chat_state(false); facy.logout(); OnLeaveChat(NULL, NULL); SetAllContactStatuses(ID_STATUS_OFFLINE); ToggleStatusMenuItems(false); delSetting(FACEBOOK_KEY_LOGON_TS); facy.chat_traceid_.clear(); facy.chat_sticky_num_.clear(); facy.chat_sticky_pool_.clear(); facy.chat_msgs_recv_ = 0; facy.chat_req_ = 0; facy.clear_cookies(); facy.clear_notifications(); facy.clear_chatrooms(); facy.clear_readers(); facy.buddies.clear(); facy.messages_ignore.clear(); facy.messages_timestamp.clear(); facy.pages.clear(); facy.typers.clear(); // Clear thread/user id caches? /* Right now it's commented out because it's not really needed to erase - maybe only when user changes login/pass in same account, but even then it shouldn't cause problems facy.thread_id_to_user_id.clear(); facy.chat_id_to_hcontact.clear(); facy.user_id_to_hcontact.clear(); */ // Close connection handle if (facy.hFcbCon) Netlib_CloseHandle(facy.hFcbCon); facy.hFcbCon = NULL; m_iStatus = facy.self_.status_id = ID_STATUS_OFFLINE; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); m_signingOut = false; debugLogA("### SignOff complete"); return; } else if (old_status == ID_STATUS_OFFLINE) { // Login SYSTEMTIME t; GetLocalTime(&t); debugLogA("[%d.%d.%d] Using Facebook Protocol RM %s", t.wDay, t.wMonth, t.wYear, __VERSION_STRING_DOTS); debugLogA("*** Beginning SignOn process"); m_enableChat = getBool(FACEBOOK_KEY_ENABLE_CHATS, DEFAULT_ENABLE_CHATS); m_iStatus = facy.self_.status_id = ID_STATUS_CONNECTING; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); ResetEvent(update_loop_lock_); // Workaround for not working "mbasic." for some users - reset this flag at every login facy.mbasicWorks = true; if (NegotiateConnection() && facy.home() && facy.reconnect()) { // Load all friends ProcessFriendList(NULL); // Process friendship requests ForkThread(&FacebookProto::ProcessFriendRequests, NULL); // Sync threads, get messages - or get unread messages if (getBool(FACEBOOK_KEY_LOGIN_SYNC, DEFAULT_LOGIN_SYNC)) ForkThread(&FacebookProto::SyncThreads, NULL); else ForkThread(&FacebookProto::ProcessUnreadMessages, NULL); // Get notifications ForkThread(&FacebookProto::ProcessNotifications, NULL); // Load pages for post status dialog ForkThread(&FacebookProto::ProcessPages, NULL); // Load on this day posts if (getByte(FACEBOOK_KEY_EVENT_ON_THIS_DAY_ENABLE, DEFAULT_EVENT_ON_THIS_DAY_ENABLE)) ForkThread(&FacebookProto::ProcessOnThisDay, NULL); setDword(FACEBOOK_KEY_LOGON_TS, (DWORD)time(NULL)); ForkThread(&FacebookProto::UpdateLoop, NULL); ForkThread(&FacebookProto::MessageLoop, NULL); if (getByte(FACEBOOK_KEY_SET_MIRANDA_STATUS, DEFAULT_SET_MIRANDA_STATUS)) ForkThread(&FacebookProto::SetAwayMsgWorker, NULL); } else { ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_FAILED, (HANDLE)old_status, m_iStatus); if (facy.hFcbCon) Netlib_CloseHandle(facy.hFcbCon); facy.hFcbCon = NULL; facy.clear_cookies(); // Set to offline m_iStatus = m_iDesiredStatus = facy.self_.status_id = ID_STATUS_OFFLINE; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); debugLogA("*** SignOn failed"); return; } ToggleStatusMenuItems(true); debugLogA("*** SignOn complete"); } m_invisible = (new_status == ID_STATUS_INVISIBLE); // Remember time of switching to away (and if we are idle already, use the idle time) m_awayTS = (new_status == ID_STATUS_AWAY ? (m_idleTS > 0 ? m_idleTS : ::time(NULL)) : 0); facy.chat_state(!m_invisible); ForkThread(&FacebookProto::ProcessBuddyList, NULL); m_iStatus = facy.self_.status_id = new_status; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); debugLogA("*** ChangeStatus complete"); }
CVkProto::CVkProto(const char *szModuleName, const TCHAR *ptszUserName) : PROTO<CVkProto>(szModuleName, ptszUserName), m_arRequestsQueue(10, sttCompareAsyncHttpRequest), m_sendIds(3, PtrKeySortT), m_incIds(3, PtrKeySortT), m_cookies(5), m_msgId(1), m_chats(1, NumericKeySortT) { InitQueue(); CreateProtoService(PS_CREATEACCMGRUI, &CVkProto::SvcCreateAccMgrUI); CreateProtoService(PS_GETAVATARINFO, &CVkProto::SvcGetAvatarInfo); CreateProtoService(PS_GETAVATARCAPS, &CVkProto::SvcGetAvatarCaps); CreateProtoService(PS_GETMYAVATAR, &CVkProto::SvcGetMyAvatar); CreateProtoService(PS_SET_LISTENINGTO, &CVkProto::SvcSetListeningTo); HookProtoEvent(ME_OPT_INITIALISE, &CVkProto::OnOptionsInit); TCHAR descr[512]; mir_sntprintf(descr, TranslateT("%s server connection"), m_tszUserName); NETLIBUSER nlu = {sizeof(nlu)}; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; nlu.szSettingsModule = m_szModuleName; nlu.ptszDescriptiveName = descr; m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); m_defaultGroup = getTStringA("ProtoGroup"); if (m_defaultGroup == NULL) m_defaultGroup = mir_tstrdup(_T("VKontakte")); Clist_CreateGroup(NULL, m_defaultGroup); m_bServerDelivery = getBool("ServerDelivery", true); m_bHideChats = getBool("HideChats", true); m_bMesAsUnread = getBool("MesAsUnread"); m_bUseLocalTime = getBool("UseLocalTime"); m_bReportAbuse = getBool("ReportAbuseOnBanUser"); m_bClearServerHistory = getBool("ClearServerHistoryOnBanUser"); m_bRemoveFromFrendlist = getBool("RemoveFromFrendlistOnBanUser"); m_bRemoveFromClist = getBool("RemoveFromClistOnBanUser"); m_bPopUpSyncHistory = getBool("PopUpSyncHistory"); m_iMarkMessageReadOn = (MarkMsgReadOn)getByte("MarkMessageReadOn", markOnRead); m_bStikersAsSmyles = getBool("StikersAsSmyles"); m_bUserForceOnlineOnActivity = getBool("UserForceOnlineOnActivity"); m_iMusicSendMetod = (MusicSendMetod)getByte("MusicSendMetod", sendBroadcastOnly); m_iSyncHistoryMetod = (SyncHistoryMetod)getByte("SyncHistoryMetod", syncOff); CMStringA szListeningTo(m_szModuleName); szListeningTo += "Enabled"; db_set_b(NULL, "ListeningTo", szListeningTo, m_iMusicSendMetod == 0 ? 0 : 1); m_bNewsEnabled = getBool("NewsEnabled"); m_iMaxLoadNewsPhoto = getByte("MaxLoadNewsPhoto", 5); m_bNotificationsEnabled = getBool("NotificationsEnabled"); m_bNotificationsMarkAsViewed = getBool("NotificationsMarkAsViewed", true); m_bSpecialContactAlwaysEnabled = getBool("SpecialContactAlwaysEnabled"); m_iNewsInterval = getDword("NewsInterval", 15); m_iNotificationsInterval = getDword("NotificationsInterval", 1); m_iIMGBBCSupport = (IMGBBCSypport)getByte("IMGBBCSupport", imgNo); m_iBBCForNews = (BBCSupport)getByte("BBCForNews", bbcBasic); m_iBBCForAttachments = (BBCSupport)getByte("BBCForAttachments", bbcBasic); m_bUseBBCOnAttacmentsAsNews = getBool("UseBBCOnAttacmentsAsNews", true); m_bNewsAutoClearHistory = getBool("NewsAutoClearHistory"); m_iNewsAutoClearHistoryInterval = getDword("NewsAutoClearHistoryInterval", 60*60*24*3); m_bNewsFilterPosts = getBool("NewsFilterPosts", true); m_bNewsFilterPhotos = getBool("NewsFilterPhotos", true); m_bNewsFilterTags = getBool("NewsFilterTags", true); m_bNewsFilterWallPhotos = getBool("NewsFilterWallPhotos", true); m_bNewsSourceFriends = getBool("NewsSourceFriends", true); m_bNewsSourceGroups = getBool("NewsSourceGroups", true); m_bNewsSourcePages = getBool("NewsSourcePages", true); m_bNewsSourceFollowing = getBool("NewsSourceFollowing", true); m_bNewsSourceIncludeBanned = getBool("NewsSourceIncludeBanned"); m_bNewsSourceNoReposts = getBool("NewsSourceNoReposts"); m_bNotificationFilterComments = getBool("NotificationFilterComments", true); m_bNotificationFilterLikes = getBool("NotificationFilterLikes", true); m_bNotificationFilterReposts = getBool("NotificationFilterReposts", true); m_bNotificationFilterMentions = getBool("NotificationFilterMentions", true); m_bNotificationFilterInvites = getBool("NotificationFilterInvites", true); m_bUseNonStandardUrlEncode = getBool("UseNonStandardUrlEncode", true); m_iInvisibleInterval = getDword("InvisibleInterval", 10); m_bShortenLinksForAudio = getBool("ShortenLinksForAudio", true); m_bSplitFormatFwdMsg = getBool("SplitFormatFwdMsg", true); m_bSetBroadcast = false; m_bNeedSendOnline = false; delSetting("InviteGroupIds"); // Set all contacts offline -- in case we crashed SetAllContactStatuses(ID_STATUS_OFFLINE); { mir_cslock lck(csInstances); vk_Instances.insert(this); } }
FacebookProto::FacebookProto(const char* proto_name, const TCHAR* username) : PROTO<FacebookProto>(proto_name, username), m_tszDefaultGroup(getTStringA(FACEBOOK_KEY_DEF_GROUP)) { facy.parent = this; signon_lock_ = CreateMutex(NULL, FALSE, NULL); avatar_lock_ = CreateMutex(NULL, FALSE, NULL); log_lock_ = CreateMutex(NULL, FALSE, NULL); update_loop_lock_ = CreateEvent(NULL, FALSE, FALSE, NULL); facy.buddies_lock_ = CreateMutex(NULL, FALSE, NULL); facy.send_message_lock_ = CreateMutex(NULL, FALSE, NULL); facy.fcb_conn_lock_ = CreateMutex(NULL, FALSE, NULL); facy.notifications_lock_ = CreateMutex(NULL, FALSE, NULL); facy.cookies_lock_ = CreateMutex(NULL, FALSE, NULL); // Initialize random seed for this client facy.random_ = ::time(NULL) + PtrToUint(&facy); m_enableChat = DEFAULT_ENABLE_CHATS; // Load custom locale, if set ptrA locale(getStringA(FACEBOOK_KEY_LOCALE)); if (locale != NULL) m_locale = locale; if (m_tszDefaultGroup == NULL) m_tszDefaultGroup = mir_tstrdup(_T("Facebook")); CreateProtoService(PS_CREATEACCMGRUI, &FacebookProto::SvcCreateAccMgrUI); CreateProtoService(PS_GETMYAWAYMSG, &FacebookProto::GetMyAwayMsg); CreateProtoService(PS_GETMYAVATAR, &FacebookProto::GetMyAvatar); CreateProtoService(PS_GETAVATARINFO, &FacebookProto::GetAvatarInfo); CreateProtoService(PS_GETAVATARCAPS, &FacebookProto::GetAvatarCaps); CreateProtoService(PS_GETUNREADEMAILCOUNT, &FacebookProto::GetNotificationsCount); CreateProtoService(PS_JOINCHAT, &FacebookProto::OnJoinChat); CreateProtoService(PS_LEAVECHAT, &FacebookProto::OnLeaveChat); HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &FacebookProto::OnBuildStatusMenu); HookProtoEvent(ME_OPT_INITIALISE, &FacebookProto::OnOptionsInit); HookProtoEvent(ME_IDLE_CHANGED, &FacebookProto::OnIdleChanged); HookProtoEvent(ME_TTB_MODULELOADED, &FacebookProto::OnToolbarInit); HookProtoEvent(ME_GC_EVENT, &FacebookProto::OnGCEvent); HookProtoEvent(ME_GC_BUILDMENU, &FacebookProto::OnGCMenuHook); HookProtoEvent(ME_DB_EVENT_MARKED_READ, &FacebookProto::OnDbEventRead); db_set_resident(m_szModuleName, "IdleTS"); db_set_resident(m_szModuleName, FACEBOOK_KEY_MESSAGE_READ); db_set_resident(m_szModuleName, FACEBOOK_KEY_MESSAGE_READERS); InitHotkeys(); InitPopups(); InitSounds(); // Create standard network connection TCHAR descr[512]; NETLIBUSER nlu = { sizeof(nlu) }; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; nlu.szSettingsModule = m_szModuleName; mir_sntprintf(descr, TranslateT("%s server connection"), m_tszUserName); nlu.ptszDescriptiveName = descr; m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); if (m_hNetlibUser == NULL) { TCHAR error[200]; mir_sntprintf(error, TranslateT("Unable to initialize Netlib for %s."), m_tszUserName); MessageBox(NULL, error, _T("Miranda NG"), MB_OK | MB_ICONERROR); } facy.set_handle(m_hNetlibUser); // Set all contacts offline -- in case we crashed SetAllContactStatuses(ID_STATUS_OFFLINE); // register special type of event // there's no need to declare the special service for getting text // because a blob contains only text DBEVENTTYPEDESCR evtype = { sizeof(evtype) }; evtype.module = m_szModuleName; evtype.eventType = FACEBOOK_EVENTTYPE_CALL; evtype.descr = LPGEN("Video call"); evtype.eventIcon = GetIconHandle("facebook"); evtype.flags = DETF_HISTORY | DETF_MSGWINDOW; CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&evtype); }