# HG changeset patch # User andrew.victor@mxit.com # Date 1301381754 0 # Node ID 245dd63f9d42a71a2c078d60bcb06b2c29c0ef5f # Parent f1fd3df53e743855d0051eb84c9ab1c7d118a4e7# Parent dde6f5770cd0cf19f35507d01d3e805f33d3cab1 merge of '75c1e83a87528fd242c342004ffcc0a4af52164f' and '8945b5678260b7adafc8d3f4b9e3622a756668dd' diff -r f1fd3df53e74 -r 245dd63f9d42 libpurple/protocols/mxit/actions.c --- a/libpurple/protocols/mxit/actions.c Fri Mar 25 08:36:10 2011 +0000 +++ b/libpurple/protocols/mxit/actions.c Tue Mar 29 06:55:54 2011 +0000 @@ -389,6 +389,59 @@ /*------------------------------------------------------------------------ + * Request list of suggested friends. + * + * @param action The action object + */ +static void mxit_cb_suggested_friends( PurplePluginAction* action ) +{ + PurpleConnection* gc = (PurpleConnection*) action->context; + struct MXitSession* session = (struct MXitSession*) gc->proto_data; + const char* profilelist[] = { + CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME, CP_PROFILE_FIRSTNAME, + CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY, CP_PROFILE_STATUS, CP_PROFILE_AVATAR }; + + mxit_send_suggest_friends( session, 20, ARRAY_SIZE( profilelist ), profilelist ); +} + + +/*------------------------------------------------------------------------ + * Perform contact search. + * + * @param action The action object + */ +static void mxit_user_search_cb( PurpleConnection *gc, const char *input ) +{ + struct MXitSession* session = (struct MXitSession*) gc->proto_data; + const char* profilelist[] = { + CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_FULLNAME, CP_PROFILE_FIRSTNAME, + CP_PROFILE_LASTNAME, CP_PROFILE_REGCOUNTRY, CP_PROFILE_STATUS, CP_PROFILE_AVATAR }; + + mxit_send_suggest_search( session, 20, input, ARRAY_SIZE( profilelist ), profilelist ); +} + + +/*------------------------------------------------------------------------ + * Display the search input form. + * + * @param action The action object + */ +static void mxit_cb_search_begin( PurplePluginAction* action ) +{ + PurpleConnection* gc = (PurpleConnection*) action->context; + + purple_request_input( gc, _( "Search for user" ), + _( "Search for a MXit contact" ), + _( "Type search information" ), + NULL, FALSE, FALSE, NULL, + _("_Search"), G_CALLBACK( mxit_user_search_cb ), + _("_Cancel"), NULL, + purple_connection_get_account( gc ), NULL, NULL, + gc); +} + + +/*------------------------------------------------------------------------ * Associate actions with the MXit plugin. * * @param plugin The MXit protocol plugin @@ -412,6 +465,14 @@ action = purple_plugin_action_new( _( "About..." ), mxit_cb_action_about ); m = g_list_append( m, action ); + /* suggested friends */ + action = purple_plugin_action_new( _( "Suggested friends..." ), mxit_cb_suggested_friends ); + m = g_list_append( m, action ); + + /* search for users */ + action = purple_plugin_action_new( _( "Search for Users..." ), mxit_cb_search_begin ); + m = g_list_append( m, action ); + return m; } diff -r f1fd3df53e74 -r 245dd63f9d42 libpurple/protocols/mxit/profile.c --- a/libpurple/protocols/mxit/profile.c Fri Mar 25 08:36:10 2011 +0000 +++ b/libpurple/protocols/mxit/profile.c Tue Mar 29 06:55:54 2011 +0000 @@ -181,3 +181,43 @@ purple_notify_userinfo( session->con, username, info, NULL, NULL ); purple_notify_user_info_destroy( info ); } + +/*------------------------------------------------------------------------ + * Display the profiles of search results. + * + * @param session The MXit session object + * @param entries The list of profile entries + */ +void mxit_show_search_results( struct MXitSession* session, GList* entries ) +{ + PurpleNotifySearchResults* results; + PurpleNotifySearchColumn* column; + + if ( !entries ) { + mxit_popup( PURPLE_NOTIFY_MSG_INFO, _( "No results" ), _( "No users found." ) ); + return; + } + + results = purple_notify_searchresults_new(); + if ( !results ) + return; + + /* define columns */ + column = purple_notify_searchresults_column_new( _( "UserId" ) ); + purple_notify_searchresults_column_add( results, column ); + + while (entries != NULL) { + struct MXitProfile* profile = ( struct MXitProfile *) entries->data; + GList* row; + + /* column values */ + row = g_list_append( NULL, g_strdup( profile->userid ) ); + + purple_notify_searchresults_row_add( results, row ); + entries = g_list_next( entries ); + } + + // TODO: add buttons + + purple_notify_searchresults( session->con, NULL, NULL, NULL, results, NULL, NULL ); +} diff -r f1fd3df53e74 -r 245dd63f9d42 libpurple/protocols/mxit/profile.h --- a/libpurple/protocols/mxit/profile.h Fri Mar 25 08:36:10 2011 +0000 +++ b/libpurple/protocols/mxit/profile.h Tue Mar 29 06:55:54 2011 +0000 @@ -32,6 +32,7 @@ struct MXitProfile { /* required */ char loginname[64]; /* name user uses to log into MXit with (aka 'mxitid') */ + char userid[51]; /* internal UserId (only in search results) */ char nickname[101]; /* user's own display name (aka 'nickname', aka 'fullname', aka 'alias') in MXit */ char birthday[16]; /* user's birthday "YYYY-MM-DD" */ gboolean male; /* true if the user's gender is male (otherwise female) */ @@ -54,6 +55,7 @@ struct MXitSession; void mxit_show_profile( struct MXitSession* session, const char* username, struct MXitProfile* profile ); +void mxit_show_search_results( struct MXitSession* session, GList* entries ); gboolean validateDate( const char* bday ); diff -r f1fd3df53e74 -r 245dd63f9d42 libpurple/protocols/mxit/protocol.c --- a/libpurple/protocols/mxit/protocol.c Fri Mar 25 08:36:10 2011 +0000 +++ b/libpurple/protocols/mxit/protocol.c Tue Mar 29 06:55:54 2011 +0000 @@ -535,7 +535,7 @@ return; } - /* + /* * the mxit server has flood detection and it prevents you from sending messages to fast. * this is a self defense mechanism, a very annoying feature. so the client must ensure that * it does not send messages too fast otherwise mxit will ignore the user for 30 seconds. @@ -717,7 +717,7 @@ "ms=%s%c%s%c%i%c%s%c" /* "ms"=password\1version\1maxreplyLen\1name\1 */ "%s%c%i%c%s%c%s%c" /* dateOfBirth\1gender\1location\1capabilities\1 */ "%s%c%i%c%s%c%s" /* dc\1features\1dialingcode\1locale */ - "%c%i%c%i", /* \1protocolVer\1lastRosterUpdate */ + "%c%i%c%i", /* \1protocolVer\1lastRosterUpdate */ session->encpwd, CP_FLD_TERM, clientVersion, CP_FLD_TERM, CP_MAX_FILESIZE, CP_FLD_TERM, profile->nickname, CP_FLD_TERM, profile->birthday, CP_FLD_TERM, ( profile->male ) ? 1 : 0, CP_FLD_TERM, MXIT_DEFAULT_LOC, CP_FLD_TERM, MXIT_CP_CAP, CP_FLD_TERM, session->distcode, CP_FLD_TERM, features, CP_FLD_TERM, session->dialcode, CP_FLD_TERM, locale, @@ -884,7 +884,7 @@ * @param session The MXit session object * @param max Maximum number of results to return * @param nr_attribs Number of attributes being requested - * @param attribute The names of the attributes + * @param attribute The names of the attributes */ void mxit_send_suggest_friends( struct MXitSession* session, int max, unsigned int nr_attrib, const char* attribute[] ) { @@ -1882,6 +1882,43 @@ /*------------------------------------------------------------------------ + * Process a received suggest-contacts packet. + * + * @param session The MXit session object + * @param records The packet's data records + * @param rcount The number of data records + */ +static void mxit_parse_cmd_suggestcontacts( struct MXitSession* session, struct record** records, int rcount ) +{ + int i; + GList* entries = NULL; + + /* + * searchType \1 numSuggestions \1 total \1 numAttributes \1 name0 \1 name1 \1 ... \1 nameN \0 + * userid \1 contactType \1 value0 \1 value1 ... valueN \0 + * ... + * userid \1 contactType \1 value0 \1 value1 ... valueN + */ + + for ( i = 1; i < rcount; i ++ ) { + struct record* rec = records[i]; + struct MXitProfile* profile = g_new0( struct MXitProfile, 1 ); + + g_strlcpy( profile->userid, rec->fields[0]->data, sizeof( profile->userid ) ); + // TODO: Decoce other profile fields. + + entries = g_list_append( entries, profile ); + } + + /* display */ + mxit_show_search_results( session, entries ); + + /* cleanup */ + g_list_foreach( entries, (GFunc)g_free, NULL ); +} + + +/*------------------------------------------------------------------------ * Return the length of a multimedia chunk * * @return The actual chunk data length in bytes @@ -2132,6 +2169,11 @@ mxit_parse_cmd_extprofile( session, &packet->records[2], packet->rcount - 2 ); break; + case CP_CMD_SUGGESTCONTACTS : + /* suggest contacts */ + mxit_parse_cmd_suggestcontacts( session, &packet->records[2], packet->rcount - 2 ); + break; + case CP_CMD_MOOD : /* mood update */ case CP_CMD_UPDATE :