From e94c705bb01c662d934c0096480bc9a732d0e1ec Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 19 Jan 2012 12:21:27 +0000 Subject: FacebookRM: Version bump Version 0.0.7.0 + Support for group chats (EXPERIMENTAL!) - enable it in options ! Fixed loading contact list ! Fixed potential freeze. Total downloads: (None or statistics not available yet) Version 0.0.6.1a Reuploaded. Total downloads: (None or statistics not available yet) Version 0.0.6.1 + Returned option to close chat windows (on website) + New option to map non-standard statuses to Invisible (insetad of Online) + New option to load contacts, which have "On the Phone" status ! Fixed changing chat visibility ! Very long messages are no longer received duplicitely ! Changes and fixes related to multiuser messages and messages from people, which are not in server-list Total downloads: (None or statistics not available yet) git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@261 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- FacebookRM/communication.cpp | 205 ++++++++++++++++++++++++------------------- 1 file changed, 117 insertions(+), 88 deletions(-) (limited to 'FacebookRM/communication.cpp') diff --git a/FacebookRM/communication.cpp b/FacebookRM/communication.cpp index 174c084..3b8da48 100644 --- a/FacebookRM/communication.cpp +++ b/FacebookRM/communication.cpp @@ -224,15 +224,17 @@ DWORD facebook_client::choose_security_level( int request_type ) // case FACEBOOK_REQUEST_LOGOUT: // case FACEBOOK_REQUEST_HOME: // case FACEBOOK_REQUEST_BUDDY_LIST: +// case FACEBOOK_REQUEST_FACEPILES: // case FACEBOOK_REQUEST_LOAD_FRIENDS: // case FACEBOOK_REQUEST_DELETE_FRIEND: +// case FACEBOOK_REQUEST_ADD_FRIEND: // case FACEBOOK_REQUEST_FEEDS: // case FACEBOOK_REQUEST_NOTIFICATIONS: // case FACEBOOK_REQUEST_RECONNECT: // case FACEBOOK_REQUEST_STATUS_SET: // case FACEBOOK_REQUEST_MESSAGE_SEND: // case FACEBOOK_REQUEST_MESSAGES_RECEIVE: -// case FACEBOOK_REQUEST_SETTINGS: +// case FACEBOOK_REQUEST_VISIBILITY: // case FACEBOOK_REQUEST_TABS: // case FACEBOOK_REQUEST_ASYNC: // case FACEBOOK_REQUEST_ASYNC_GET: @@ -249,14 +251,16 @@ int facebook_client::choose_method( int request_type ) case FACEBOOK_REQUEST_LOGIN: case FACEBOOK_REQUEST_SETUP_MACHINE: case FACEBOOK_REQUEST_BUDDY_LIST: + case FACEBOOK_REQUEST_FACEPILES: case FACEBOOK_REQUEST_STATUS_SET: case FACEBOOK_REQUEST_MESSAGE_SEND: - case FACEBOOK_REQUEST_SETTINGS: + case FACEBOOK_REQUEST_VISIBILITY: case FACEBOOK_REQUEST_TABS: case FACEBOOK_REQUEST_ASYNC: case FACEBOOK_REQUEST_TYPING_SEND: case FACEBOOK_REQUEST_LOGOUT: case FACEBOOK_REQUEST_DELETE_FRIEND: + case FACEBOOK_REQUEST_ADD_FRIEND: return REQUEST_POST; // case FACEBOOK_REQUEST_HOME: @@ -287,16 +291,18 @@ std::string facebook_client::choose_proto( int request_type ) // case FACEBOOK_REQUEST_NOTIFICATIONS: // case FACEBOOK_REQUEST_RECONNECT: // case FACEBOOK_REQUEST_BUDDY_LIST: +// case FACEBOOK_REQUEST_FACEPILES: // case FACEBOOK_REQUEST_LOAD_FRIENDS: // case FACEBOOK_REQUEST_STATUS_SET: // case FACEBOOK_REQUEST_MESSAGE_SEND: // case FACEBOOK_REQUEST_MESSAGES_RECEIVE: -// case FACEBOOK_REQUEST_SETTINGS: +// case FACEBOOK_REQUEST_VISIBILITY: // case FACEBOOK_REQUEST_TABS: // case FACEBOOK_REQUEST_ASYNC: // case FACEBOOK_REQUEST_ASYNC_GET: // case FACEBOOK_REQUEST_TYPING_SEND: // case FACEBOOK_REQUEST_DELETE_FRIEND: +// case FACEBOOK_REQUEST_ADD_FRIEND: default: return HTTP_PROTO_REGULAR; @@ -327,19 +333,21 @@ std::string facebook_client::choose_server( int request_type, std::string* data // case FACEBOOK_REQUEST_LOGOUT: // case FACEBOOK_REQUEST_HOME: // case FACEBOOK_REQUEST_BUDDY_LIST: +// case FACEBOOK_REQUEST_FACEPILES: // case FACEBOOK_REQUEST_LOAD_FRIENDS: // case FACEBOOK_REQUEST_FEEDS: // case FACEBOOK_REQUEST_NOTIFICATIONS: // case FACEBOOK_REQUEST_RECONNECT: // case FACEBOOK_REQUEST_STATUS_SET: // case FACEBOOK_REQUEST_MESSAGE_SEND: -// case FACEBOOK_REQUEST_SETTINGS: +// case FACEBOOK_REQUEST_VISIBILITY: // case FACEBOOK_REQUEST_TABS: // case FACEBOOK_REQUEST_ASYNC: // case FACEBOOK_REQUEST_ASYNC_GET: // case FACEBOOK_REQUEST_TYPING_SEND: // case FACEBOOK_REQUEST_SETUP_MACHINE: // case FACEBOOK_REQUEST_DELETE_FRIEND: +// case FACEBOOK_REQUEST_ADD_FRIEND: default: return FACEBOOK_SERVER_REGULAR; } @@ -359,11 +367,14 @@ std::string facebook_client::choose_action( int request_type, std::string* data return "/logout.php"; case FACEBOOK_REQUEST_HOME: - return "/home.php"; + return "/home.php?_fb_noscript=1"; case FACEBOOK_REQUEST_BUDDY_LIST: return "/ajax/chat/buddy_list.php?__a=1"; + case FACEBOOK_REQUEST_FACEPILES: + return "/ajax/groups/chat/update_facepiles.php?__a=1"; + case FACEBOOK_REQUEST_LOAD_FRIENDS: { std::string action = "/ajax/chat/user_info_all.php?__a=1&viewer=%s"; @@ -376,6 +387,11 @@ std::string facebook_client::choose_action( int request_type, std::string* data return "/ajax/profile/removefriend.php?__a=1"; } + case FACEBOOK_REQUEST_ADD_FRIEND: + { + return "/ajax/add_friend/action.php?__a=1"; + } + case FACEBOOK_REQUEST_FEEDS: { std::string action = "/ajax/intent.php?filter="; @@ -426,8 +442,8 @@ std::string facebook_client::choose_action( int request_type, std::string* data return action; } - case FACEBOOK_REQUEST_SETTINGS: - return "/ajax/chat/settings.php?__a=1"; + case FACEBOOK_REQUEST_VISIBILITY: + return "/ajax/chat/visibility.php?__a=1"; case FACEBOOK_REQUEST_TABS: return "/ajax/chat/tabs.php?__a=1"; @@ -446,7 +462,7 @@ std::string facebook_client::choose_action( int request_type, std::string* data return "/ajax/messaging/typ.php?__a=1"; default: - return "/"; + return "/?_fb_noscript=1"; } } @@ -465,15 +481,17 @@ NETLIBHTTPHEADER* facebook_client::get_request_headers( int request_type, int* h case FACEBOOK_REQUEST_LOGIN: case FACEBOOK_REQUEST_SETUP_MACHINE: case FACEBOOK_REQUEST_BUDDY_LIST: + case FACEBOOK_REQUEST_FACEPILES: case FACEBOOK_REQUEST_LOAD_FRIENDS: case FACEBOOK_REQUEST_STATUS_SET: case FACEBOOK_REQUEST_MESSAGE_SEND: - case FACEBOOK_REQUEST_SETTINGS: + case FACEBOOK_REQUEST_VISIBILITY: case FACEBOOK_REQUEST_TABS: case FACEBOOK_REQUEST_ASYNC: case FACEBOOK_REQUEST_ASYNC_GET: case FACEBOOK_REQUEST_TYPING_SEND: case FACEBOOK_REQUEST_DELETE_FRIEND: + case FACEBOOK_REQUEST_ADD_FRIEND: *headers_count = 5; break; @@ -494,15 +512,17 @@ NETLIBHTTPHEADER* facebook_client::get_request_headers( int request_type, int* h case FACEBOOK_REQUEST_LOGIN: case FACEBOOK_REQUEST_SETUP_MACHINE: case FACEBOOK_REQUEST_BUDDY_LIST: + case FACEBOOK_REQUEST_FACEPILES: case FACEBOOK_REQUEST_LOAD_FRIENDS: case FACEBOOK_REQUEST_STATUS_SET: case FACEBOOK_REQUEST_MESSAGE_SEND: - case FACEBOOK_REQUEST_SETTINGS: + case FACEBOOK_REQUEST_VISIBILITY: case FACEBOOK_REQUEST_TABS: case FACEBOOK_REQUEST_ASYNC: case FACEBOOK_REQUEST_ASYNC_GET: case FACEBOOK_REQUEST_TYPING_SEND: case FACEBOOK_REQUEST_DELETE_FRIEND: + case FACEBOOK_REQUEST_ADD_FRIEND: headers[4].szName = "Content-Type"; headers[4].szValue = "application/x-www-form-urlencoded; charset=utf-8"; @@ -574,7 +594,7 @@ void facebook_client::store_headers( http::response* resp, NETLIBHTTPHEADER* hea } else { // TODO RM: (un)comment - parent->Log("----- Got header '%s': %s", header_name.c_str(), header_value.c_str() ); + //parent->Log("----- Got header '%s': %s", header_name.c_str(), header_value.c_str() ); resp->headers[header_name] = header_value; } } @@ -768,13 +788,13 @@ bool facebook_client::home( ) // Get real_name this->self_.real_name = utils::text::remove_html( utils::text::special_expressions_decode( utils::text::source_get_value( &resp.data, 2, " id=\"navAccountName\">", "m_szModuleName,FACEBOOK_KEY_NAME,this->self_.real_name.c_str()); - DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,"Nick",this->self_.real_name.c_str()); + DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,FACEBOOK_KEY_NICK,this->self_.real_name.c_str()); parent->Log(" Got self real name: %s", this->self_.real_name.c_str()); } else if ( resp.data.find("id=\"pageNav\"") != std::string::npos ) { // Get real_name this->self_.real_name = utils::text::remove_html( utils::text::special_expressions_decode( utils::text::source_get_value( &resp.data, 3, " class=\"headerTinymanName\"", ">", "m_szModuleName,FACEBOOK_KEY_NAME,this->self_.real_name.c_str()); - DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,"Nick",this->self_.real_name.c_str()); + DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,FACEBOOK_KEY_NICK,this->self_.real_name.c_str()); parent->Log(" Got self real name: %s", this->self_.real_name.c_str()); } else { client_notify(TranslateT("Something happened to Facebook. Maybe there was some major update so you should wait for an update.")); @@ -791,11 +811,11 @@ bool facebook_client::home( ) parent->CheckAvatarChange(NULL, this->self_.image_url); // Get post_form_id - this->post_form_id_ = utils::text::source_get_value( &resp.data, 2, "post_form_id:\"", "\"" ); + this->post_form_id_ = utils::text::source_get_value( &resp.data, 3, "name=\"post_form_id\"", "value=\"", "\"" ); parent->Log(" Got self post form id: %s", this->post_form_id_.c_str()); // Get dtsg - this->dtsg_ = utils::text::source_get_value( &resp.data, 2, "fb_dtsg:\"", "\"" ); + this->dtsg_ = utils::text::source_get_value( &resp.data, 3, "name=\"fb_dtsg\"", "value=\"", "\"" ); parent->Log(" Got self dtsg: %s", this->dtsg_.c_str()); // Get logout hash @@ -836,35 +856,28 @@ bool facebook_client::home( ) ForkThread( &FacebookProto::ProcessNotifications, this->parent, NULL ); } - // TODO RM: if enabled groupchats support - // Get group chats -/* std::string chat_ids = utils::text::source_get_value( &resp.data, 2, "HomeNavController.initGroupCounts([","]" ); - if ( chat_ids.length() ) - { + // TODO RM: if enabled groupchats support - // split by comma to ids, find names in source, inicialize groups in contactlist - // maybe check which groupchats user wants - // add to list? start worker for parse and add contacts to groupchat - // add "," to end for better parsing - chat_ids += ","; - std::string::size_type oldpos = 0, pos = 0; - - while ( ( pos = chat_ids.find(",", oldpos) ) != std::string::npos ) - { - std::string id = chat_ids.substr(oldpos, pos-oldpos); - std::string name = utils::text::trim( - utils::text::special_expressions_decode( - utils::text::remove_html( - utils::text::edit_html( - utils::text::source_get_value( &resp.data, 5, "HomeNavController.initGroupCounts", "home.php?sk=group_", id.c_str(), "input title=\\\"", "\\\" " ) ) ) ) ); - - parent->Log(" Got groupchat id: %s, name: %s", id.c_str(), name.c_str()); - oldpos = pos+1; - - parent->AddChat(id.c_str(), name.c_str()); - } - }*/ + if (DBGetContactSettingByte(NULL, parent->m_szModuleName, FACEBOOK_KEY_ENABLE_GROUPCHATS, DEFAULT_ENABLE_GROUPCHATS)) { + // Get group chats + std::string favorites = utils::text::source_get_value( &resp.data, 2, "
", pos) - pos); + std::string id = item.substr(0, item.find("/")); + + if (!id.empty()) { + std::string name = utils::text::source_get_value( &item, 3, "class=\"linkWrap", ">", "
" ); + name = utils::text::special_expressions_decode(utils::text::slashu_to_utf8( name ) ); + parent->Log(" Got new group chat: %s (id: %s)", name.c_str(), id.c_str()); + if (!name.empty()) + parent->AddChat(id.c_str(), name.c_str()); + } + } + } return handle_success( "home" ); @@ -891,7 +904,7 @@ bool facebook_client::chat_state( bool online ) data += "&post_form_id_source=AsyncRequest"; data += "&fb_dtsg=" + this->dtsg_; data += "&lsd="; - http::response resp = flap( FACEBOOK_REQUEST_SETTINGS, &data ); + http::response resp = flap( FACEBOOK_REQUEST_VISIBILITY, &data ); return handle_success( "chat_state" ); } @@ -942,16 +955,16 @@ bool facebook_client::buddy_list( ) handle_entry( "buddy_list" ); // Prepare update data - std::string data = "user=" + this->self_.user_id + "&force_render=true&fetch_mobile=true&post_form_id=" + this->post_form_id_ + "&fb_dtsg=" + this->dtsg_ + "&lsd=&post_form_id_source=AsyncRequest&__user=" + this->self_.user_id; + std::string data = "user=" + this->self_.user_id + "&fetch_mobile=true&post_form_id=" + this->post_form_id_ + "&fb_dtsg=" + this->dtsg_ + "&lsd=&post_form_id_source=AsyncRequest&__user=" + this->self_.user_id; { ScopedLock s(buddies_lock_); int counter = 0; - for (List::Item< facebook_user >* i = buddies.begin(); i != NULL; i = i->next ) + for (List::Item< facebook_user >* i = buddies.begin(); i != NULL; i = i->next, counter++ ) { data += "&available_user_info_ids["; - data += counter++; + data += utils::conversion::to_string(&counter, UTILS_CONV_UNSIGNED_NUMBER); data += "]="; data += i->data->user_id; } @@ -966,12 +979,11 @@ bool facebook_client::buddy_list( ) switch ( resp.code ) { case HTTP_CODE_OK: - if ( resp.data.find( "\"listChanged\":true" ) != std::string::npos ) - { - std::string* response_data = new std::string( resp.data ); - ForkThread( &FacebookProto::ProcessBuddyList, this->parent, ( void* )response_data ); - } + { + std::string* response_data = new std::string( resp.data ); + ForkThread( &FacebookProto::ProcessBuddyList, this->parent, ( void* )response_data ); return handle_success( "buddy_list" ); + } case HTTP_CODE_FAKE_ERROR: case HTTP_CODE_FAKE_DISCONNECTED: @@ -980,6 +992,51 @@ bool facebook_client::buddy_list( ) } } +bool facebook_client::facepiles( ) +{ + handle_entry( "facepiles" ); + + int count = (int)CallServiceSync(MS_GC_GETSESSIONCOUNT, 0, (LPARAM)parent->m_szModuleName); + for ( int i = 0; i < count; i++ ) { + GC_INFO gci = {0}; + gci.Flags = BYINDEX | TYPE | ID; + gci.iItem = i; + gci.pszModule = parent->m_szModuleName; + if ( !CallServiceSync( MS_GC_GETINFO, 0, (LPARAM)&gci ) && gci.iType == GCW_CHATROOM ) { + char *id = mir_t2a(gci.pszID); + + // Prepare data + std::string data = "id="; + data += id; + data += "&post_form_id=" + this->post_form_id_ + "&fb_dtsg=" + this->dtsg_ + "&lsd=&post_form_id_source=AsyncRequest&__user=" + this->self_.user_id + "&phstamp=0"; + + // Get facepiles + http::response resp = flap( FACEBOOK_REQUEST_FACEPILES, &data ); + + // Process result data + validate_response(&resp); + + std::string chat_id = id; + mir_free(id); + + switch ( resp.code ) + { + case HTTP_CODE_OK: + ForkThread( &FacebookProto::ProcessFacepiles, this->parent, new send_chat(chat_id, resp.data) ); + break; + + case HTTP_CODE_FAKE_ERROR: + case HTTP_CODE_FAKE_DISCONNECTED: + default: + return handle_error( "facepiles" ); + } + + } + } + + return handle_success( "facepiles" ); +} + bool facebook_client::load_friends( ) { handle_entry( "load_friends" ); @@ -1037,42 +1094,6 @@ bool facebook_client::feeds( ) } } -void facebook_client::delete_friends( ) -{ - handle_entry( "delete_friends" ); - - // Check and update old contacts - for(HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); - hContact; - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0) ) - { - if(!parent->IsMyContact(hContact)) - continue; - - if( !DBGetContactSettingByte(hContact,parent->m_szModuleName,FACEBOOK_KEY_DELETE_NEXT,0) ) { - DBVARIANT dbv; - if( !DBGetContactSettingString(hContact,parent->m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) { - std::string* id = new std::string(dbv.pszVal); - DBFreeVariant(&dbv); - - if( !DBGetContactSettingString(hContact,parent->m_szModuleName,FACEBOOK_KEY_NAME,&dbv) ) { - - TCHAR* szTitle = mir_a2t_cp(dbv.pszVal, CP_UTF8); - parent->NotifyEvent(szTitle, TranslateT("Contact was deleted."), hContact, FACEBOOK_EVENT_CLIENT, NULL); - mir_free( szTitle ); - DBFreeVariant(&dbv); - - CallService(MS_DB_CONTACT_DELETE,(WPARAM)hContact,0); - - ForkThread( &FacebookProto::DeleteContactFromServer, this->parent, ( void* )id ); - } - } - } - } - - handle_success( "delete_friends" ); -} - bool facebook_client::channel( ) { handle_entry( "channel" ); @@ -1131,6 +1152,12 @@ bool facebook_client::channel( ) case HTTP_CODE_FAKE_DISCONNECTED: case HTTP_CODE_FAKE_ERROR: default: + // Testing workaround for channel change + if (!this->chat_channel_jslogger_.empty()) + this->chat_channel_jslogger_ = "_"; + else + this->chat_channel_jslogger_.clear(); + return handle_error( "channel" ); } } @@ -1191,7 +1218,8 @@ bool facebook_client::send_message( std::string message_recipient, std::string m case 1356003: // Contact is offline { HANDLE hContact = parent->ContactIDToHContact( message_recipient ); - DBWriteContactSettingWord(hContact,parent->m_szModuleName,"Status",ID_STATUS_OFFLINE); + if (hContact != NULL) + DBWriteContactSettingWord(hContact,parent->m_szModuleName,"Status",ID_STATUS_OFFLINE); return false; } break; @@ -1225,6 +1253,7 @@ bool facebook_client::send_message( std::string message_recipient, std::string m case HTTP_CODE_FAKE_DISCONNECTED: default: *error_text = Translate("Timeout when sending message."); + handle_error( "send_message" ); return false; } -- cgit v1.2.3