Example #1
0
bool facebook_client::set_status(const std::string &status_text)
{
	handle_entry( "set_status" );

	std::string data = "post_form_id_source=AsyncRequest&post_form_id=";
	data += ( this->post_form_id_.length( ) ) ? this->post_form_id_ : "0";
	data += "&fb_dtsg=";
	data += ( this->dtsg_.length( ) ) ? this->dtsg_ : "0";
	data += "&target_id=";
	data += this->self_.user_id;

	if ( status_text.length( ) )
	{
		data += "&action=PROFILE_UPDATE&app_id=&hey_kid_im_a_composer=true&display_context=profile&_log_display_context=profile&ajax_log=1&status=";
		data += utils::url::encode( status_text );
		data += "&profile_id=";
		data += this->self_.user_id;
	}

	http::response resp = flap( FACEBOOK_REQUEST_STATUS_SET, &data );

	validate_response(&resp);

	switch ( resp.code )
	{
	case HTTP_CODE_OK:
  		return handle_success( "set_status" );

  	case HTTP_CODE_FAKE_ERROR:
	case HTTP_CODE_FAKE_DISCONNECTED:
	default:
  		return handle_error( "set_status" );
	}
}
Example #2
0
bool facebook_client::feeds( )
{
	handle_entry( "feeds" );

	// Get feeds
	http::response resp = flap( FACEBOOK_REQUEST_FEEDS );

	// Process result data
	validate_response(&resp);
  
	switch ( resp.code )
	{
	case HTTP_CODE_OK:
		if (resp.data.find("\"num_stories\":0") == std::string::npos) {
			std::string* response_data = new std::string( resp.data );
		    ForkThread( &FacebookProto::ProcessFeeds, this->parent, ( void* )response_data );
		}
		return handle_success( "feeds" );

	case HTTP_CODE_FAKE_ERROR:
	case HTTP_CODE_FAKE_DISCONNECTED:
	default:
		return handle_error( "feeds" );
	}
}
Example #3
0
bool facebook_client::buddy_list( )
{
	handle_entry( "buddy_list" );

	// Prepare update data
	std::string data = "user="******"&fetch_mobile=true&post_form_id=" + this->post_form_id_ + "&fb_dtsg=" + this->dtsg_ + "&lsd=&post_form_id_source=AsyncRequest&__user="******"&available_user_info_ids[";
			data += utils::conversion::to_string(&counter, UTILS_CONV_UNSIGNED_NUMBER);
			data += "]=";
			data += i->data->user_id;
		}
	}

	// Get buddy list
	http::response resp = flap( FACEBOOK_REQUEST_BUDDY_LIST, &data );

	// Process result data
	validate_response(&resp);

	switch ( resp.code )
	{
	case HTTP_CODE_OK:
	{
		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:
	default:
		return handle_error( "buddy_list" );
	}
}
Example #4
0
bool facebook_client::reconnect( )
{
	handle_entry( "reconnect" );

	// Request reconnect
	http::response resp = flap( FACEBOOK_REQUEST_RECONNECT );

	// Process result data
	validate_response(&resp);

	switch ( resp.code )
	{
	case HTTP_CODE_OK:
	{
		this->chat_channel_jslogger_ = utils::text::source_get_value( &resp.data, 2, "\"jslogger_suffix\":\"", "\"" );
		parent->Log("      Got self channel jslogger: %s", this->chat_channel_jslogger_.c_str());
				
		this->chat_channel_partition_ = utils::text::source_get_value2( &resp.data, "\"partition\":", ",}" );
		parent->Log("      Got self channel partition: %s", this->chat_channel_partition_.c_str());
		
		this->chat_channel_host_ = utils::text::source_get_value( &resp.data, 2, "\"host\":\"", "\"" );
		parent->Log("      Got self channel host: %s", this->chat_channel_host_.c_str());

		this->chat_sequence_num_ = utils::text::source_get_value2( &resp.data, "\"seq\":", ",}" );
		parent->Log("      Got self sequence number: %s", this->chat_sequence_num_.c_str());

		if (this->chat_channel_jslogger_.empty()) {
			if (!atoi(this->chat_channel_host_.substr(0, this->chat_channel_host_.find(".")).c_str())) {
				this->chat_channel_jslogger_ = "SOMETHING";
				parent->Log("      Got no jslogger, changed.");
			}
		}
  		
		return handle_success( "reconnect" );
	}
	 
	default:
		return handle_error( "reconnect", FORCE_DISCONNECT );
	}
}
Example #5
0
bool facebook_client::load_friends( )
{
	handle_entry( "load_friends" );

	// Get buddy list
	http::response resp = flap( FACEBOOK_REQUEST_LOAD_FRIENDS );

	// Process result data
	validate_response(&resp);

	switch ( resp.code )
	{
	case HTTP_CODE_OK:
	{
		std::string* response_data = new std::string( resp.data );
		ForkThread( &FacebookProto::ProcessFriendList, this->parent, ( void* )response_data );
		return handle_success( "load_friends" );
	}
	case HTTP_CODE_FAKE_ERROR:
	case HTTP_CODE_FAKE_DISCONNECTED:
	default:
		return handle_error( "load_friends" );
	}
}
Example #6
0
static void socket_readable(aeEventLoop *loop, int fd, void *data, int mask) {
    connection *c = data;
    thread *thread = c->thread;
    uint64_t now;
    ssize_t n;

    if ((n = read(fd, c->buf, sizeof(c->buf))) <= 0) goto error;
    c->buf[n] = '\0';

    now = time_us();
    if (!validate_response(c)) goto invalid;
    thread->bytes += n;
    thread->complete++;
    thread->requests++;

    stats_record(thread->latency, now - c->start);

    if (now >= thread->stop_at) {
        aeStop(thread->loop);
        close(c->fd);
    }
    else {
        reconnect_socket(c->thread, c);
    }

    return;

  invalid:
    c->thread->errors.validate++;
    reconnect_socket(c->thread, c);
    return;

  error:
    c->thread->errors.read++;
    reconnect_socket(c->thread, c);
}
Example #7
0
bool facebook_client::home( )
{
	handle_entry( "home" );

	http::response resp = flap( FACEBOOK_REQUEST_HOME );

	// Process result data
	validate_response(&resp);

	switch ( resp.code )
	{
	case HTTP_CODE_OK:
	{		
		if ( resp.data.find( "id=\"navAccountName\"" ) != std::string::npos )
		{ // Backup for old fb version
			// 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\">", "</a" ) ) );
			DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,FACEBOOK_KEY_NAME,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\"", ">", "</a" ) ) );
			DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,FACEBOOK_KEY_NAME,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."));
			return handle_error( "home", FORCE_DISCONNECT );
		}

		// Get avatar
		std::string avatar = utils::text::source_get_value( &resp.data, 3, "class=\\\"fbxWelcomeBoxImg", "src=\\\"", "\\\"" );
		if (avatar.empty())
			avatar = utils::text::source_get_value( &resp.data, 3, "class=\"fbxWelcomeBoxImg", "src=\"", "\"" );

		this->self_.image_url = utils::text::trim( utils::text::special_expressions_decode( avatar ) );
		parent->Log("      Got self avatar: %s", this->self_.image_url.c_str());
		parent->CheckAvatarChange(NULL, this->self_.image_url);

		// Get 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, 3, "name=\"fb_dtsg\"", "value=\"", "\"" );
		parent->Log("      Got self dtsg: %s", this->dtsg_.c_str());

		// Get logout hash
		this->logout_hash_ = utils::text::source_get_value( &resp.data, 2, "<input type=\"hidden\" autocomplete=\"off\" name=\"h\" value=\"", "\"" );
		parent->Log("      Got self logout hash: %s", this->logout_hash_.c_str());
			
		// TODO: DIrectly get that friend requests
		// Get friend requests count and notify it
		std::string str_count = utils::text::source_get_value( &resp.data, 2, "<span id=\"requestsCountValue\">", "</span>" );
		if ( str_count.length() && str_count != std::string( "0" ) )
		{
			std::string message = Translate("Got new friend requests: ") + str_count;

			TCHAR* tmessage = mir_a2t(message.c_str());
			parent->NotifyEvent( parent->m_tszUserName, tmessage, NULL, FACEBOOK_EVENT_OTHER, TEXT(FACEBOOK_URL_REQUESTS) );
			mir_free( tmessage );
		}

		if (!DBGetContactSettingByte(NULL,parent->m_szModuleName,FACEBOOK_KEY_PARSE_MESSAGES, DEFAULT_PARSE_MESSAGES))
		{
			str_count = utils::text::source_get_value( &resp.data, 2, "<span id=\"messagesCountValue\">", "</span>" );
			if ( str_count.length() && str_count != std::string( "0" ) )
			{
				std::string message = Translate("Got new messages: ") + str_count;

				TCHAR* tmessage = mir_a2t(message.c_str());
				parent->NotifyEvent( parent->m_tszUserName, tmessage, NULL, FACEBOOK_EVENT_OTHER, TEXT(FACEBOOK_URL_MESSAGES) );
				mir_free( tmessage );
			}
		}
			
		str_count = utils::text::source_get_value( &resp.data, 2, "<span id=\"notificationsCountValue\">", "</span>" );
		if ( str_count.length() && str_count != std::string( "0" ) )
		{
			// Parse notifications directly to popups
			ForkThread( &FacebookProto::ProcessNotifications, this->parent, NULL );
		}

		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, "<div id=\"leftCol\"", "<div id=\"contentCol\"" );

			std::string::size_type pos = 0;
			while ((pos = favorites.find("href=\"/groups/",pos)) != std::string::npos) {
				pos += 14;
				std::string item = favorites.substr(pos, favorites.find("</a>", 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", ">", "</div>" );
					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" );

	}
	case HTTP_CODE_FOUND:
		// Work-around for replica_down, f**king hell what's that?
		parent->Log("      REPLICA_DOWN is back in force!");
		return this->home();
	
	default:
		return handle_error( "home", FORCE_DISCONNECT );
	}
}
Example #8
0
bool facebook_client::login(const std::string &username,const std::string &password)
{
	handle_entry( "login" );

	username_ = username;
	password_ = password;

	// Access homepage to get initial cookies
	flap( FACEBOOK_REQUEST_HOME, NULL );

	// Prepare login data
	std::string data = "charset_test=%e2%82%ac%2c%c2%b4%2c%e2%82%ac%2c%c2%b4%2c%e6%b0%b4%2c%d0%94%2c%d0%84&locale=en&email=";
	data += utils::url::encode( username );
	data += "&pass="******"&pass_placeHolder=Password&login=Login&persistent=1";

	// Send validation
	http::response resp = flap( FACEBOOK_REQUEST_LOGIN, &data );

	// Process result data
	validate_response(&resp);

	if ( resp.code == HTTP_CODE_FOUND && resp.headers.find("Location") != resp.headers.end() )
	{
		// Check whether some Facebook things are required
		if ( resp.headers["Location"].find("help.php") != std::string::npos )
		{
			client_notify( TranslateT("Login error: Some Facebook things are required.") );
			parent->Log(" ! !  Login error: Some Facebook things are required.");
			// return handle_error( "login", FORCE_DISCONNECT );
		}
		
		// Check whether setting Machine name is required
		if ( resp.headers["Location"].find("/checkpoint/") != std::string::npos )
		{
			resp = flap( FACEBOOK_REQUEST_SETUP_MACHINE );
			
			std::string inner_data = "machine_name=MirandaIM&submit[Save%20Device]=Save%20Device";
			inner_data += "&post_form_id=";
			inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"post_form_id\"", "value=\"", "\"" );
			
			inner_data += "&lsd=";
			inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"lsd\"", "value=\"", "\"" );
			
			inner_data += "&nh=";
			inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\"" );

			resp = flap( FACEBOOK_REQUEST_SETUP_MACHINE, &inner_data );
			validate_response(&resp);
		}
	}
	
	if ( resp.code == HTTP_CODE_FOUND && resp.headers.find("Location") != resp.headers.end() )
	{
		// Check whether HTTPS connection is required and we don't have enabled it
		if (!this->https_)
		{    
			if ( resp.headers["Location"].find("https://") != std::string::npos )
			{
				client_notify(TranslateT("Your account requires HTTPS connection. Activating."));
				DBWriteContactSettingByte(NULL, parent->m_szModuleName, FACEBOOK_KEY_FORCE_HTTPS, 1);
				this->https_ = true;
			}
		}

	}

	// Check for Device ID
	if ( cookies["datr"].length() )
		DBWriteContactSettingString( NULL, parent->m_szModuleName, FACEBOOK_KEY_DEVICE_ID, cookies["datr"].c_str() );

	switch ( resp.code )
	{
	case HTTP_CODE_FAKE_DISCONNECTED:
	{
		// When is error only because timeout, try login once more
		if ( handle_error( "login" ) )
			return login(username, password);
		else
			return false;
	}

	case HTTP_CODE_OK: // OK page returned, but that is regular login page we don't want in fact
	{ 
		// Check whether captcha code is required
		if ( resp.data.find("id=\"captcha\"") != std::string::npos )
		{
			client_notify( TranslateT("Login error: Captcha code is required. Bad login credentials?") );
			parent->Log(" ! !  Login error: Captcha code is required.");
			return handle_error( "login", FORCE_DISCONNECT );
		}
		
		// Get error message
		std::string error_str = utils::text::trim(
			utils::text::special_expressions_decode(
				utils::text::remove_html( 
					utils::text::edit_html(
						utils::text::source_get_value( &resp.data, 2, "id=\"standard_error\">", "</h2>" ) ) ) ) );

		if ( !error_str.length() )
			error_str = Translate("Unknown login error");
		parent->Log(" ! !  Login error: %s", error_str.c_str());

		std::string message = Translate("Login error: ") + error_str;
		TCHAR* tmessage = mir_a2t(message.c_str());
		client_notify( tmessage );
		mir_free( tmessage );
	}
	case HTTP_CODE_FORBIDDEN: // Forbidden
	case HTTP_CODE_NOT_FOUND: // Not Found
	default:
		return handle_error( "login", FORCE_DISCONNECT );

	case HTTP_CODE_FOUND: // Found and redirected to Home, Logged in, everything is OK
		if ( cookies.find("c_user") != cookies.end() )
		{
			this->self_.user_id = cookies.find("c_user")->second;
			DBWriteContactSettingString(NULL,parent->m_szModuleName,FACEBOOK_KEY_ID,this->self_.user_id.c_str());
			parent->Log("      Got self user id: %s", this->self_.user_id.c_str());
			return handle_success( "login" );
		} else {
			client_notify(TranslateT("Login error, probably bad login credentials."));
			parent->Log(" ! !  Login error, probably bad login credentials.");
			return handle_error( "login", FORCE_DISCONNECT );
		}
	}
}
Example #9
0
http::response facebook_client::flap( const int request_type, std::string* request_data, std::string* request_get_data )
{
	NETLIBHTTPREQUEST nlhr = {sizeof( NETLIBHTTPREQUEST )};
	nlhr.requestType = choose_method( request_type );
	std::string url = choose_request_url( request_type, request_data, request_get_data );
	nlhr.szUrl = (char*)url.c_str( );
	nlhr.flags = NLHRF_HTTP11 | NLHRF_NODUMP | choose_security_level( request_type );
	nlhr.headers = get_request_headers( request_type, &nlhr.headersCount );
	
	switch (request_type)
	{
	case FACEBOOK_REQUEST_MESSAGES_RECEIVE:
		nlhr.timeout = 1000 * 65; break;
	case FACEBOOK_REQUEST_MESSAGE_SEND:
		nlhr.timeout = 1000 * 10; break;
	default:
		nlhr.timeout = 1000 * 15; break;
	}

	if ( request_data != NULL )
	{
		nlhr.pData = (char*)(*request_data).c_str();
		nlhr.dataLength = (int)request_data->length( );
	}

	parent->Log("@@@@@ Sending request to '%s'", nlhr.szUrl);

	switch ( request_type )
	{
	case FACEBOOK_REQUEST_LOGIN:
		nlhr.nlc = NULL;
		break;

	case FACEBOOK_REQUEST_MESSAGES_RECEIVE:
		nlhr.nlc = hMsgCon;
		nlhr.flags |= NLHRF_PERSISTENT;
		break;

	default:
		WaitForSingleObject(fcb_conn_lock_, INFINITE);
		nlhr.nlc = hFcbCon;
		nlhr.flags |= NLHRF_PERSISTENT;
		break;
	}

	NETLIBHTTPREQUEST* pnlhr = ( NETLIBHTTPREQUEST* )CallService( MS_NETLIB_HTTPTRANSACTION, (WPARAM)handle_, (LPARAM)&nlhr );

	utils::mem::detract(nlhr.headers[3].szValue);
	utils::mem::detract(nlhr.headers);

	http::response resp;

	switch ( request_type )
	{
	case FACEBOOK_REQUEST_LOGIN:
	case FACEBOOK_REQUEST_SETUP_MACHINE:
		break;

	case FACEBOOK_REQUEST_MESSAGES_RECEIVE:
		hMsgCon = pnlhr ? pnlhr->nlc : NULL;
		break;

	default:
		ReleaseMutex(fcb_conn_lock_);
		hFcbCon = pnlhr ? pnlhr->nlc : NULL;
		break;
	}

	if ( pnlhr != NULL )
	{
		parent->Log("@@@@@ Got response with code %d", pnlhr->resultCode);
		store_headers( &resp, pnlhr->headers, pnlhr->headersCount );
		resp.code = pnlhr->resultCode;
		resp.data = pnlhr->pData ? pnlhr->pData : "";

		CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)pnlhr);
	} else {
		parent->Log("!!!!! No response from server (time-out)");
		resp.code = HTTP_CODE_FAKE_DISCONNECTED;
		// Better to have something set explicitely as this value
	    // is compaired in all communication requests
	}

	if (DBGetContactSettingByte( NULL, parent->m_szModuleName, FACEBOOK_KEY_VALIDATE_RESPONSE, 0 ) == 1)
		validate_response(&resp);

	return resp;
}
Example #10
0
bool facebook_client::send_message( std::string message_recipient, std::string message_text, std::string *error_text, bool use_inbox )
{
	handle_entry( "send_message" );

	http::response resp;

	if (parent->isInvisible() || use_inbox) {
		// Use inbox send message when invisible
		std::string data = "action=send&body=";
		data += utils::url::encode( message_text );
		data += "&recipients[0]=";
		data += message_recipient;
		data += "&lsd=&fb_dtsg=";
		data += ( dtsg_.length( ) ) ? dtsg_ : "0";
		data += "&post_form_id=";
		data += ( post_form_id_.length( ) ) ? post_form_id_ : "0";

		resp = flap( FACEBOOK_REQUEST_ASYNC, &data );	
	} else {
		// Use standard send message
		std::string data = "msg_text=";
		data += utils::url::encode( message_text );
		data += "&msg_id=";
		data += utils::time::mili_timestamp( );
		data += "%3A";
		data += utils::time::unix_timestamp( );
		data += "&to=";
		data += message_recipient;
		data += "&__user="******"&client_time=";
		data += utils::time::mili_timestamp( );
		data += "&pvs_time&fb_dtsg=";
		data += ( dtsg_.length( ) ) ? dtsg_ : "0";
		data += "&to_offline=false&to_idle=false&lsd&post_form_id_source=AsyncRequest&num_tabs=1";
		data += "&window_id=0&sidebar_launched=false&sidebar_enabled=false&sidebar_capable=false&sidebar_should_show=false&sidebar_visible=false";
		data += "&post_form_id=";
		data += ( post_form_id_.length( ) ) ? post_form_id_ : "0";

		resp = flap( FACEBOOK_REQUEST_MESSAGE_SEND, &data );
	}

	
	validate_response(&resp);
	*error_text = resp.error_text;

	switch ( resp.error_number )
	{
  	case 0: // Everything is OK
		break;

    //case 1356002: // You are offline - wtf??

	case 1356003: // Contact is offline
	{
		HANDLE hContact = parent->ContactIDToHContact( message_recipient );
		if (hContact != NULL)
  			DBWriteContactSettingWord(hContact,parent->m_szModuleName,"Status",ID_STATUS_OFFLINE);
		return false;
	} break;

  	case 1356026: // Contact has alternative client
	{
		client_notify(TranslateT("Need confirmation for sending messages to other clients.\nOpen facebook website and try to send message to this contact again!"));
      /*
          post na url http://www.facebook.com/ajax/chat/post_application_settings.php?__a=1

          enable_and_send      Povolit a odeslat                                                                                                                                                                                                                                                                                                                                                                                                                               
          to_send              AQCoweMPeszBoKpd4iahcOyhmh0kiTYIhv1b5wCtuBiD0AaPVZIdEp3Pf5JMBmQ-9wf0ju-xdi-VRuk0ERk_I7XzI5dVJCs6-B0FExTZhspD-4-kTZLmZI-_M6fIuF2328yMyT3R3UEUmMV8P9MHcZwu-_pS3mOhsaHf6rIVcQ2rocSqLKi03wLKCfg0m8VsptPADWpOI-UNcIo-xl1PAoC1yVnL2wEXEtnF1qI_xFcmlJZ40AOONfIF_LS_lBrGYA-oCWLUK-GLHtQAHjO8aDeNXDU8Jk7Z_ES-_oAHee2PVLHcG_ACHXpasE7Iu3XFLMrdN2hjM96AjPRIf0Vk8gBZzfW_lUspakZmXxMI7iSNQE8lourK_6B3Z1s4UHxDZCNXYuc9gh70nm_xnaxnF9K1bR00s4MltnFjUT_3ypThzA  
          __d                  1                                                                                                                                                                                                                                                                                                                                                                                                                                               
          post_form_id         c73ebd9d94b7449c40e6965410fcdcf6                                                                                                                                                                                                                                                                                                                                                                                                                
          fb_dtsg              Tb-T9                                                                                                                                                                                                                                                                                                                                                                                                                                           
          lsd                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
          post_form_id_source  AsyncRequest                                                                                                                                                                                                                                                                                                                                                                                                                                    
          */
		return false;
	} break;
 
    default: // Other error
		return false;
 	}

	switch ( resp.code )
	{
	case HTTP_CODE_OK:
		return handle_success( "send_message" );

	case HTTP_CODE_FAKE_ERROR:
	case HTTP_CODE_FAKE_DISCONNECTED:
	default:
		*error_text = Translate("Timeout when sending message.");

		handle_error( "send_message" );
		return false;
	}
}
Example #11
0
bool facebook_client::channel( )
{
	handle_entry( "channel" );

	// Get update
	http::response resp = flap( FACEBOOK_REQUEST_MESSAGES_RECEIVE );

	// Process result data
	validate_response(&resp);

	if ( resp.code != HTTP_CODE_OK )
	{
		// Something went wrong
	}
	else if ( resp.data.find( "\"t\":\"continue\"" ) != std::string::npos )
	{
		// Everything is OK, no new message received
	}
	else if ( resp.data.find( "\"t\":\"fullReload\"" ) != std::string::npos )
	{
		// Something went wrong (server flooding?)

		parent->Log("! ! ! Requested full reload");
    
		this->chat_sequence_num_ = utils::text::source_get_value2( &resp.data, "\"seq\":", ",}" );
		parent->Log("      Got self sequence number: %s", this->chat_sequence_num_.c_str());

		this->chat_reconnect_reason_ = utils::text::source_get_value2( &resp.data, "\"reason\":", ",}" );
		parent->Log("      Reconnect reason: %s", this->chat_reconnect_reason_.c_str());
	}
	else if ( resp.data.find( "\"t\":\"refresh\"" ) != std::string::npos )
	{
		// Something went wrong (server flooding?)
		parent->Log("! ! ! Requested channel refresh");
    
		this->chat_reconnect_reason_ = utils::text::source_get_value2( &resp.data, "\"reason\":", ",}" );
		parent->Log("      Reconnect reason: %s", this->chat_reconnect_reason_.c_str());

		this->chat_sequence_num_ = utils::text::source_get_value2( &resp.data, "\"seq\":", ",}" );
		parent->Log("      Got self sequence number: %s", this->chat_sequence_num_.c_str());

		return this->reconnect( );
	} else {
		// Something has been received, throw to new thread to process
		std::string* response_data = new std::string( resp.data );
		ForkThread( &FacebookProto::ProcessMessages, this->parent, ( void* )response_data );

		// Increment sequence number
		this->chat_sequence_num_ = utils::text::source_get_value2( &resp.data, "\"seq\":", ",}" );
		parent->Log("      Got self sequence number: %s", this->chat_sequence_num_.c_str());
	}

	// Return
	switch ( resp.code )
	{
	case HTTP_CODE_OK:
		return handle_success( "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" );
	}
}