Esempio n. 1
0
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"));
}
Esempio n. 2
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");
}