summaryrefslogtreecommitdiff
path: root/protocols/FacebookRM/src/connection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/FacebookRM/src/connection.cpp')
-rw-r--r--protocols/FacebookRM/src/connection.cpp247
1 files changed, 247 insertions, 0 deletions
diff --git a/protocols/FacebookRM/src/connection.cpp b/protocols/FacebookRM/src/connection.cpp
new file mode 100644
index 0000000000..d041e0344f
--- /dev/null
+++ b/protocols/FacebookRM/src/connection.cpp
@@ -0,0 +1,247 @@
+/*
+
+Facebook plugin for Miranda Instant Messenger
+_____________________________________________
+
+Copyright © 2009-11 Michal Zelinka
+
+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/>.
+
+File name : $HeadURL: http://eternityplugins.googlecode.com/svn/trunk/facebook/connection.cpp $
+Revision : $Revision: 91 $
+Last change by : $Author: n3weRm0re.ewer $
+Last change on : $Date: 2011-01-08 11:10:34 +0100 (so, 08 1 2011) $
+
+*/
+
+#include "common.h"
+
+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
+ LOG("##### Beginning SignOff process");
+
+ m_iStatus = facy.self_.status_id = ID_STATUS_OFFLINE;
+ SetEvent(update_loop_lock_);
+ Netlib_Shutdown(facy.hMsgCon);
+
+ if ( getByte(FACEBOOK_KEY_DISCONNECT_CHAT, DEFAULT_DISCONNECT_CHAT))
+ facy.chat_state( false );
+
+ facy.logout( );
+
+ deleteSetting( "LogonTS" );
+
+ facy.clear_cookies( );
+ facy.buddies.clear( );
+
+ ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
+
+ OnLeaveChat(NULL, NULL);
+
+ SetAllContactStatuses( ID_STATUS_OFFLINE );
+
+ ToggleStatusMenuItems(false);
+
+ if (facy.hMsgCon)
+ Netlib_CloseHandle(facy.hMsgCon);
+ facy.hMsgCon = NULL;
+
+ LOG("##### SignOff complete");
+
+ return;
+ }
+ else if ( old_status == ID_STATUS_OFFLINE )
+ { // Login
+ SYSTEMTIME t;
+ GetLocalTime( &t );
+ Log("[%d.%d.%d] Using Facebook Protocol RM %s", t.wDay, t.wMonth, t.wYear, __VERSION_STRING);
+
+ LOG("***** Beginning SignOn process");
+
+ m_iStatus = facy.self_.status_id = ID_STATUS_CONNECTING;
+ ProtoBroadcastAck(m_szModuleName,0,ACKTYPE_STATUS,ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
+
+ ResetEvent(update_loop_lock_);
+
+ if ( NegotiateConnection( ))
+ {
+ facy.last_feeds_update_ = ::time( NULL );
+
+ facy.home();
+ facy.reconnect();
+
+ facy.load_friends();
+
+ // Process Friends requests
+ ForkThread( &FacebookProto::ProcessFriendRequests, this, NULL );
+
+ if (getByte(FACEBOOK_KEY_PARSE_MESSAGES, DEFAULT_PARSE_MESSAGES))
+ ForkThread( &FacebookProto::ProcessUnreadMessages, this );
+
+ setDword( "LogonTS", (DWORD)time(NULL));
+ ForkThread( &FacebookProto::UpdateLoop, this );
+ ForkThread( &FacebookProto::MessageLoop, this );
+
+ if (getByte(FACEBOOK_KEY_SET_MIRANDA_STATUS, DEFAULT_SET_MIRANDA_STATUS))
+ {
+ ForkThread(&FacebookProto::SetAwayMsgWorker, this, NULL);
+ }
+ } else {
+ ProtoBroadcastAck(m_szModuleName,0,ACKTYPE_STATUS,ACKRESULT_FAILED,
+ (HANDLE)old_status,m_iStatus);
+
+ // Set to offline
+ m_iStatus = m_iDesiredStatus = facy.self_.status_id = ID_STATUS_OFFLINE;
+ ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
+
+ LOG("***** SignOn failed");
+
+ return;
+ }
+
+ ToggleStatusMenuItems(true);
+ LOG("***** SignOn complete");
+ }
+ else if ( new_status == ID_STATUS_INVISIBLE )
+ {
+ facy.buddies.clear( );
+ this->SetAllContactStatuses( ID_STATUS_OFFLINE );
+ }
+
+ facy.chat_state( m_iDesiredStatus != ID_STATUS_INVISIBLE );
+ facy.buddy_list( );
+
+ m_iStatus = facy.self_.status_id = m_iDesiredStatus;
+ ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
+
+ LOG("***** ChangeStatus complete");
+}
+
+/** Return true on success, false on error. */
+bool FacebookProto::NegotiateConnection( )
+{
+ LOG("***** Negotiating connection with Facebook");
+
+ bool error;
+ std::string user, pass;
+ DBVARIANT dbv = {0};
+
+ error = true;
+ if ( !DBGetContactSettingString(NULL,m_szModuleName,FACEBOOK_KEY_LOGIN,&dbv))
+ {
+ user = dbv.pszVal;
+ DBFreeVariant(&dbv);
+ error = user.empty();
+ }
+ if (error)
+ {
+ NotifyEvent(m_tszUserName,TranslateT("Please enter a username."),NULL,FACEBOOK_EVENT_CLIENT);
+ return false;
+ }
+
+ error = true;
+ if ( !DBGetContactSettingString(NULL,m_szModuleName,FACEBOOK_KEY_PASS,&dbv))
+ {
+ CallService(MS_DB_CRYPT_DECODESTRING,strlen(dbv.pszVal)+1,
+ reinterpret_cast<LPARAM>(dbv.pszVal));
+ pass = dbv.pszVal;
+ DBFreeVariant(&dbv);
+ error = pass.empty();
+ }
+ if (error)
+ {
+ NotifyEvent(m_tszUserName,TranslateT("Please enter a password."),NULL,FACEBOOK_EVENT_CLIENT);
+ return false;
+ }
+
+ // Load machine name
+ if ( !DBGetContactSettingString(NULL,m_szModuleName,FACEBOOK_KEY_DEVICE_ID,&dbv))
+ {
+ facy.cookies["datr"] = dbv.pszVal;
+ DBFreeVariant(&dbv);
+ }
+
+ // Get info about secured connection
+ facy.https_ = DBGetContactSettingByte(NULL, m_szModuleName, FACEBOOK_KEY_FORCE_HTTPS, DEFAULT_FORCE_HTTPS ) != 0;
+
+ // Create default group for new contacts
+ if (!DBGetContactSettingTString(NULL, m_szModuleName, FACEBOOK_KEY_DEF_GROUP, &dbv) && lstrlen(dbv.ptszVal) > 0)
+ {
+ CallService(MS_CLIST_GROUPCREATE, 0, (LPARAM)dbv.ptszVal);
+ }
+
+ return facy.login( user, pass );
+}
+
+void FacebookProto::UpdateLoop(void *)
+{
+ time_t tim = ::time(NULL);
+ LOG( ">>>>> Entering Facebook::UpdateLoop[%d]", tim );
+
+ for ( int i = -1; !isOffline(); i = ++i % 50 )
+ {
+ if ( i != -1 ) {
+ if ( !facy.invisible_ )
+ if ( !facy.buddy_list( ))
+ break;
+ }
+ if ( i == 2 && getByte( FACEBOOK_KEY_EVENT_FEEDS_ENABLE, DEFAULT_EVENT_FEEDS_ENABLE ))
+ if ( !facy.feeds( ))
+ break;
+
+ if ( i == 49 )
+ ForkThread( &FacebookProto::ProcessFriendRequests, this, NULL );
+
+ LOG( "***** FacebookProto::UpdateLoop[%d] going to sleep...", tim );
+ if ( WaitForSingleObjectEx( update_loop_lock_, GetPollRate( ) * 1000, true ) != WAIT_TIMEOUT )
+ break;
+ LOG( "***** FacebookProto::UpdateLoop[%d] waking up...", tim );
+ }
+
+ ResetEvent(update_loop_lock_);
+ LOG( "<<<<< Exiting FacebookProto::UpdateLoop[%d]", tim );
+}
+
+void FacebookProto::MessageLoop(void *)
+{
+ time_t tim = ::time(NULL);
+ LOG( ">>>>> Entering Facebook::MessageLoop[%d]", tim );
+
+ while ( facy.channel( ))
+ {
+ if ( isOffline())
+ break;
+ LOG( "***** FacebookProto::MessageLoop[%d] refreshing...", tim );
+ }
+
+ LOG( "<<<<< Exiting FacebookProto::MessageLoop[%d]", tim );
+}
+
+BYTE FacebookProto::GetPollRate( )
+{
+ BYTE poll_rate = getByte( FACEBOOK_KEY_POLL_RATE, FACEBOOK_DEFAULT_POLL_RATE );
+
+ return (
+ ( poll_rate >= FACEBOOK_MINIMAL_POLL_RATE &&
+ poll_rate <= FACEBOOK_MAXIMAL_POLL_RATE )
+ ? poll_rate : FACEBOOK_DEFAULT_POLL_RATE );
+}