# HG changeset patch
# User andrew.victor@mxit.com
# Date 1302546423 0
# Node ID 12676cfd4a1e0bf401ebb06cffbb1cca4992960b
# Parent 80bbed4cb649834756082280780140a1e5d8ef4d# Parent ba00769a1493dccb86ac6316ec848c5ad68fc6ed
propagate from branch 'im.pidgin.pidgin' (head 726c5220207c01e8799797c7d6d4455d23159281)
to branch 'im.pidgin.pidgin.mxit' (head 02bbb3e7ba9e029ba05484caae8c91a948bb0b35)
diff -r ba00769a1493 -r 12676cfd4a1e ChangeLog
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/actions.c
--- a/libpurple/protocols/mxit/actions.c Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/actions.c Mon Apr 11 18:27:03 2011 +0000
@@ -186,6 +186,43 @@
g_string_append( attributes, attrib );
acount++;
+#if 0
+ /* update about me */
+ name = purple_request_fields_get_string( fields, "aboutme" );
+ if ( !name )
+ profile->aboutme[0] = '\0';
+ else
+ g_strlcpy( profile->aboutme, name, sizeof( profile->aboutme ) );
+ g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_ABOUTME, CP_PROFILE_TYPE_UTF8, profile->aboutme );
+ g_string_append( attributes, attrib );
+ acount++;
+
+ /* update where am i */
+ name = purple_request_fields_get_string( fields, "whereami" );
+ if ( !name)
+ profile->whereami[0] = '\0';
+ else
+ g_strlcpy( profile->whereami, name, sizeof( profile->whereami ) );
+ g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_WHEREAMI, CP_PROFILE_TYPE_UTF8, profile->whereami );
+ g_string_append( attributes, attrib );
+ acount++;
+#endif
+
+ /* update flags */
+ field = purple_request_fields_get_field( fields, "searchable" );
+ if ( purple_request_field_bool_get_value( field ) ) /* is searchable -> clear not-searchable flag */
+ profile->flags &= ~CP_PROF_NOT_SEARCHABLE;
+ else
+ profile->flags |= CP_PROF_NOT_SEARCHABLE;
+ field = purple_request_fields_get_field( fields, "suggestable" );
+ if ( purple_request_field_bool_get_value( field ) ) /* is suggestable -> clear not-suggestable flag */
+ profile->flags &= ~CP_PROF_NOT_SUGGESTABLE;
+ else
+ profile->flags |= CP_PROF_NOT_SUGGESTABLE;
+ g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%i", CP_PROFILE_FLAGS, CP_PROFILE_TYPE_LONG, profile->flags);
+ g_string_append( attributes, attrib );
+ acount++;
+
/* send the profile update to MXit */
mxit_send_extprofile_update( session, session->encpwd, acount, attributes->str );
g_string_free( attributes, TRUE );
@@ -209,7 +246,6 @@
struct MXitProfile* profile = session->profile;
PurpleRequestFields* fields = NULL;
- PurpleRequestFieldGroup* group = NULL;
PurpleRequestField* field = NULL;
purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_action_profile\n" );
@@ -222,65 +258,92 @@
}
fields = purple_request_fields_new();
- group = purple_request_field_group_new( NULL );
- purple_request_fields_add_group( fields, group );
+
+ /* Security information - PIN, etc */
+ {
+ PurpleRequestFieldGroup* security_group = purple_request_field_group_new( "PIN" );
-#if 0
- /* UID (read-only) */
- if ( session->uid ) {
- field = purple_request_field_string_new( "mxitid", _( "Your UID" ), session->uid, FALSE );
- purple_request_field_string_set_editable( field, FALSE );
- purple_request_field_group_add_field( group, field );
+ /* pin */
+ field = purple_request_field_string_new( "pin", _( "PIN" ), session->acc->password, FALSE );
+ purple_request_field_string_set_masked( field, TRUE );
+ purple_request_field_group_add_field( security_group, field );
+
+ field = purple_request_field_string_new( "pin2", _( "Verify PIN" ), session->acc->password, FALSE );
+ purple_request_field_string_set_masked( field, TRUE );
+ purple_request_field_group_add_field( security_group, field );
+
+ purple_request_fields_add_group( fields, security_group );
}
-#endif
- /* pin */
- field = purple_request_field_string_new( "pin", _( "PIN" ), session->acc->password, FALSE );
- purple_request_field_string_set_masked( field, TRUE );
- purple_request_field_group_add_field( group, field );
- field = purple_request_field_string_new( "pin2", _( "Verify PIN" ), session->acc->password, FALSE );
- purple_request_field_string_set_masked( field, TRUE );
- purple_request_field_group_add_field( group, field );
+ /* Public information - what other users can see */
+ {
+ PurpleRequestFieldGroup* public_group = purple_request_field_group_new( "Public information" );
+
+ /* display name */
+ field = purple_request_field_string_new( "name", _( "Display Name" ), profile->nickname, FALSE );
+ purple_request_field_group_add_field( public_group, field );
- /* display name */
- field = purple_request_field_string_new( "name", _( "Display Name" ), profile->nickname, FALSE );
- purple_request_field_group_add_field( group, field );
+ /* birthday */
+ field = purple_request_field_string_new( "bday", _( "Birthday" ), profile->birthday, FALSE );
+ purple_request_field_group_add_field( public_group, field );
+ if ( profile->flags & CP_PROF_DOBLOCKED )
+ purple_request_field_string_set_editable( field, FALSE );
- /* birthday */
- field = purple_request_field_string_new( "bday", _( "Birthday" ), profile->birthday, FALSE );
- purple_request_field_group_add_field( group, field );
- if ( profile->flags & CP_PROF_DOBLOCKED )
- purple_request_field_string_set_editable( field, FALSE );
+ /* gender */
+ field = purple_request_field_choice_new( "male", _( "Gender" ), ( profile->male ) ? 1 : 0 );
+ purple_request_field_choice_add( field, _( "Female" ) ); /* 0 */
+ purple_request_field_choice_add( field, _( "Male" ) ); /* 1 */
+ purple_request_field_group_add_field( public_group, field );
+
+ /* first name */
+ field = purple_request_field_string_new( "firstname", _( "First Name" ), profile->firstname, FALSE );
+ purple_request_field_group_add_field( public_group, field );
- /* gender */
- field = purple_request_field_choice_new( "male", _( "Gender" ), ( profile->male ) ? 1 : 0 );
- purple_request_field_choice_add( field, _( "Female" ) ); /* 0 */
- purple_request_field_choice_add( field, _( "Male" ) ); /* 1 */
- purple_request_field_group_add_field( group, field );
+ /* last name */
+ field = purple_request_field_string_new( "lastname", _( "Last Name" ), profile->lastname, FALSE );
+ purple_request_field_group_add_field( public_group, field );
+
+ /* about me */
+ field = purple_request_field_string_new( "aboutme", _( "About Me" ), profile->aboutme, FALSE);
+ purple_request_field_group_add_field( public_group, field );
- /* hidden */
- field = purple_request_field_bool_new( "hidden", _( "Hide my number" ), profile->hidden );
- purple_request_field_group_add_field( group, field );
+ /* where I live */
+ field = purple_request_field_string_new( "whereami", _( "Where I Live" ), profile->whereami, FALSE);
+ purple_request_field_group_add_field( public_group, field );
+
+ purple_request_fields_add_group( fields, public_group );
+ }
- /* title */
- field = purple_request_field_string_new( "title", _( "Title" ), profile->title, FALSE );
- purple_request_field_group_add_field( group, field );
+ /* Private information - what only MXit can see */
+ {
+ PurpleRequestFieldGroup* private_group = purple_request_field_group_new( "Private information" );
+
+ /* title */
+ field = purple_request_field_string_new( "title", _( "Title" ), profile->title, FALSE );
+ purple_request_field_group_add_field( private_group, field );
- /* first name */
- field = purple_request_field_string_new( "firstname", _( "First Name" ), profile->firstname, FALSE );
- purple_request_field_group_add_field( group, field );
+ /* email */
+ field = purple_request_field_string_new( "email", _( "Email" ), profile->email, FALSE );
+ purple_request_field_group_add_field( private_group, field );
- /* last name */
- field = purple_request_field_string_new( "lastname", _( "Last Name" ), profile->lastname, FALSE );
- purple_request_field_group_add_field( group, field );
+ /* mobile number */
+ field = purple_request_field_string_new( "mobilenumber", _( "Mobile Number" ), profile->mobilenr, FALSE );
+ purple_request_field_group_add_field( private_group, field );
- /* email */
- field = purple_request_field_string_new( "email", _( "Email" ), profile->email, FALSE );
- purple_request_field_group_add_field( group, field );
+ /* hidden number */
+ field = purple_request_field_bool_new( "hidden", _( "Hide my number" ), profile->hidden );
+ purple_request_field_group_add_field( private_group, field );
- /* mobile number */
- field = purple_request_field_string_new( "mobilenumber", _( "Mobile Number" ), profile->mobilenr, FALSE );
- purple_request_field_group_add_field( group, field );
+ /* is searchable */
+ field = purple_request_field_bool_new( "searchable", _( "Can be searched" ), ( ( profile->flags & CP_PROF_NOT_SEARCHABLE ) == 0) );
+ purple_request_field_group_add_field( private_group, field );
+
+ /* is suggestable */
+ field = purple_request_field_bool_new( "suggestable", _( "Can be suggested" ), ( ( profile->flags & CP_PROF_NOT_SUGGESTABLE ) == 0 ) );
+ purple_request_field_group_add_field( private_group, field );
+
+ purple_request_fields_add_group( fields, private_group );
+ }
/* (reference: "libpurple/request.h") */
purple_request_fields( gc, _( "Profile" ), _( "Update your Profile" ), _( "Here you can update your MXit profile" ), fields, _( "Set" ),
@@ -314,7 +377,7 @@
{
char version[256];
- g_snprintf( version, sizeof( version ),
+ g_snprintf( version, sizeof( version ),
"MXit Client Protocol v%i.%i\n\n"
"Author:\nPieter Loubser\n\n"
"Contributors:\nAndrew Victor\n\n"
@@ -326,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
@@ -349,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 ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/login.c
--- a/libpurple/protocols/mxit/login.c Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/login.c Mon Apr 11 18:27:03 2011 +0000
@@ -141,9 +141,9 @@
}
/* This timer might already exist if we're registering a new account */
- if ( session->q_timer == 0 ) {
+ if ( session->q_slow_timer_id == 0 ) {
/* start the tx queue manager timer */
- session->q_timer = purple_timeout_add_seconds( 2, mxit_manage_queue_slow, session );
+ session->q_slow_timer_id = purple_timeout_add_seconds( 2, mxit_manage_queue_slow, session );
}
}
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/markup.c
--- a/libpurple/protocols/mxit/markup.c Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/markup.c Mon Apr 11 18:27:03 2011 +0000
@@ -235,7 +235,6 @@
*/
static void mxit_show_split_message( struct RXMsgData* mx )
{
- const char* cont = "continuing...\n";
GString* msg = NULL;
char* ch = NULL;
int pos = 0;
@@ -245,7 +244,6 @@
int l_gt = 0;
int stop = 0;
int tags = 0;
- int segs = 0;
gboolean intag = FALSE;
/*
@@ -319,21 +317,20 @@
stop--;
}
- /* build the string */
- if ( segs )
- g_string_prepend( msg, cont );
-
/* push message to pidgin */
serv_got_im( mx->session->con, mx->from, msg->str, mx->flags, mx->timestamp );
g_string_free( msg, TRUE );
msg = NULL;
+ /* next part need this flag set */
+ mx->flags |= PURPLE_MESSAGE_RAW;
+
tags = 0;
- segs++;
start = stop + 1;
+ pos = start;
}
-
- pos++;
+ else
+ pos++;
}
if ( start != pos ) {
@@ -343,8 +340,6 @@
ch[pos] = '\0';
msg = g_string_new( &ch[start] );
ch[pos] = '\n';
- if ( segs )
- g_string_prepend( msg, cont );
/* push message to pidgin */
serv_got_im( mx->session->con, mx->from, msg->str, mx->flags, mx->timestamp );
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/multimx.c
--- a/libpurple/protocols/mxit/multimx.c Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/multimx.c Mon Apr 11 18:27:03 2011 +0000
@@ -177,22 +177,13 @@
/*------------------------------------------------------------------------
* Another user has join the GroupChat, add them to the member-list.
*
- * @param session The MXit session object
- * @param multimx The MultiMX room object
+ * @param convo The Conversation object
* @param nickname The nickname of the user who joined the room
*/
-static void member_added(struct MXitSession* session, struct multimx* multimx, const char* nickname)
+static void member_added(PurpleConversation* convo, const char* nickname)
{
- PurpleConversation *convo;
-
purple_debug_info(MXIT_PLUGIN_ID, "member_added: '%s'\n", nickname);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc);
- if (convo == NULL) {
- purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
- return;
- }
-
purple_conv_chat_add_user(PURPLE_CONV_CHAT(convo), nickname, NULL, PURPLE_CBFLAGS_NONE, TRUE);
}
@@ -200,79 +191,61 @@
/*------------------------------------------------------------------------
* Another user has left the GroupChat, remove them from the member-list.
*
- * @param session The MXit session object
- * @param multimx The MultiMX room object
+ * @param convo The Conversation object
* @param nickname The nickname of the user who left the room
*/
-static void member_removed(struct MXitSession* session, struct multimx* multimx, const char* nickname)
+static void member_removed(PurpleConversation* convo, const char* nickname)
{
- PurpleConversation *convo;
-
purple_debug_info(MXIT_PLUGIN_ID, "member_removed: '%s'\n", nickname);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc);
- if (convo == NULL) {
- purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
- return;
- }
-
purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nickname, NULL);
}
/*------------------------------------------------------------------------
- * A user was kicked from the GroupChat.
+ * A user was kicked from the GroupChat, remove them from the member-list.
*
- * @param session The MXit session object
- * @param multimx The MultiMX room object
+ * @param convo The Conversation object
* @param nickname The nickname of the user who was kicked
*/
-static void member_kicked(struct MXitSession* session, struct multimx* multimx, const char* nickname)
+static void member_kicked(PurpleConversation* convo, const char* nickname)
{
- PurpleConversation *convo;
-
purple_debug_info(MXIT_PLUGIN_ID, "member_kicked: '%s'\n", nickname);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc);
- if (convo == NULL) {
- purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
- return;
- }
+ purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nickname, _("was kicked"));
+}
+
- /* who was kicked? - compare to our original nickname */
- if (purple_utf8_strcasecmp(nickname, multimx->nickname) == 0)
- {
- /* you were kicked */
- purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "MXit", _("You have been kicked from this MultiMX."), PURPLE_MESSAGE_SYSTEM, time(NULL));
- purple_conv_chat_clear_users(PURPLE_CONV_CHAT(convo));
- serv_got_chat_left(session->con, multimx->chatid);
- }
- else
- purple_conv_chat_remove_user(PURPLE_CONV_CHAT(convo), nickname, _("was kicked"));
+/*------------------------------------------------------------------------
+ * You were kicked from the GroupChat.
+ *
+ * @param convo The Conversation object
+ * @param session The MXit session object
+ * @param multimx The MultiMX room object
+ */
+static void you_kicked(PurpleConversation* convo, struct MXitSession* session, struct multimx* multimx)
+{
+ purple_debug_info(MXIT_PLUGIN_ID, "you_kicked\n");
+
+ purple_conv_chat_write(PURPLE_CONV_CHAT(convo), "MXit", _("You have been kicked from this MultiMX."), PURPLE_MESSAGE_SYSTEM, time(NULL));
+ purple_conv_chat_clear_users(PURPLE_CONV_CHAT(convo));
+ serv_got_chat_left(session->con, multimx->chatid);
}
/*------------------------------------------------------------------------
* Update the full GroupChat member list.
*
- * @param session The MXit session object
- * @param multimx The MultiMX room object
+ * @param convo The Conversation object
* @param data The nicknames of the users in the room (separated by \n)
*/
-static void member_update(struct MXitSession* session, struct multimx* multimx, char* data)
+static void member_update(PurpleConversation* convo, char* data)
{
- PurpleConversation *convo;
gchar** userlist;
int i = 0;
purple_debug_info(MXIT_PLUGIN_ID, "member_update: '%s'\n", data);
- convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, session->acc);
- if (convo == NULL) {
- purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
- return;
- }
-
/* Clear list */
purple_conv_chat_clear_users(PURPLE_CONV_CHAT(convo));
@@ -402,27 +375,38 @@
/* Must be a service message */
char* ofs;
+ PurpleConversation* convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, multimx->roomname, mx->session->acc);
+ if (convo == NULL) {
+ purple_debug_error(MXIT_PLUGIN_ID, "Conversation '%s' not found\n", multimx->roomname);
+ return;
+ }
+
/* Determine if somebody has joined or left - update member-list */
if ((ofs = strstr(msg, " has joined")) != NULL) {
/* Somebody has joined */
*ofs = '\0';
- member_added(mx->session, multimx, msg);
+ member_added(convo, msg);
mx->processed = TRUE;
}
else if ((ofs = strstr(msg, " has left")) != NULL) {
/* Somebody has left */
*ofs = '\0';
- member_removed(mx->session, multimx, msg);
+ member_removed(convo, msg);
mx->processed = TRUE;
}
else if ((ofs = strstr(msg, " has been kicked")) != NULL) {
/* Somebody has been kicked */
*ofs = '\0';
- member_kicked(mx->session, multimx, msg);
+ member_kicked(convo, msg);
+ mx->processed = TRUE;
+ }
+ else if (strcmp(msg, "You have been kicked.") == 0) {
+ /* You have been kicked */
+ you_kicked(convo, mx->session, multimx);
mx->processed = TRUE;
}
else if (g_str_has_prefix(msg, "The following users are in this MultiMx:") == TRUE) {
- member_update(mx->session, multimx, msg + strlen("The following users are in this MultiMx:") + 1);
+ member_update(convo, msg + strlen("The following users are in this MultiMx:") + 1);
mx->processed = TRUE;
}
else {
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/mxit.c
--- a/libpurple/protocols/mxit/mxit.c Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/mxit.c Mon Apr 11 18:27:03 2011 +0000
@@ -565,25 +565,23 @@
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_LASTSEEN,
- CP_PROFILE_STATUS, CP_PROFILE_AVATAR };
+ CP_PROFILE_STATUS, CP_PROFILE_AVATAR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME };
purple_debug_info( MXIT_PLUGIN_ID, "mxit_get_info: '%s'\n", who );
/* find the buddy information for this contact (reference: "libpurple/blist.h") */
buddy = purple_find_buddy( session->acc, who );
- if ( !buddy ) {
- purple_debug_warning( MXIT_PLUGIN_ID, "mxit_get_info: unable to find the buddy '%s'\n", who );
- return;
- }
+ if ( buddy ) {
+ /* user is in our contact-list, so it's not an invite */
+ contact = purple_buddy_get_protocol_data( buddy );
+ if ( !contact )
+ return;
- contact = purple_buddy_get_protocol_data( buddy );
- if ( !contact )
- return;
-
- /* only MXit users have profiles */
- if ( contact->type != MXIT_TYPE_MXIT ) {
- mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "No profile available" ), _( "This contact does not have a profile." ) );
- return;
+ /* only MXit users have profiles */
+ if ( contact->type != MXIT_TYPE_MXIT ) {
+ mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "No profile available" ), _( "This contact does not have a profile." ) );
+ return;
+ }
}
/* send profile request */
@@ -628,7 +626,7 @@
return;
/* send a new invite */
- mxit_send_invite( session, contact->username, contact->alias, contact->groupname );
+ mxit_send_invite( session, contact->username, contact->alias, contact->groupname, NULL );
}
@@ -664,7 +662,7 @@
/*========================================================================================================================*/
static PurplePluginProtocolInfo proto_info = {
- OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_IM_IMAGE, /* options */
+ OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_IM_IMAGE | OPT_PROTO_INVITE_MESSAGE, /* options */
NULL, /* user_splits */
NULL, /* protocol_options */
{ /* icon_spec */
@@ -692,7 +690,7 @@
mxit_set_status, /* set_status */
NULL, /* set_idle */
NULL, /* change_passwd */
- mxit_add_buddy, /* add_buddy [roster.c] */
+ NULL, /* add_buddy [roster.c] */
NULL, /* add_buddies */
mxit_remove_buddy, /* remove_buddy [roster.c] */
NULL, /* remove_buddies */
@@ -743,7 +741,7 @@
mxit_get_moods, /* get_moods */
NULL, /* set_public_alias */
NULL, /* get_public_alias */
- NULL, /* add_buddy_with_invite */
+ mxit_add_buddy, /* add_buddy_with_invite */
NULL /* add_buddies_with_invite */
};
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/mxit.h
--- a/libpurple/protocols/mxit/mxit.h Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/mxit.h Mon Apr 11 18:27:03 2011 +0000
@@ -162,7 +162,8 @@
struct tx_queue queue; /* transmit packet queue (FIFO mode) */
gint64 last_tx; /* timestamp of last packet sent */
int outack; /* outstanding ack packet */
- guint q_timer; /* timer handler for managing queue */
+ guint q_slow_timer_id; /* timer handle for slow tx queue */
+ guint q_fast_timer_id; /* timer handle for fast tx queue */
/* receive */
char rx_lbuf[16]; /* receive byte buffer (socket packet length) */
@@ -172,6 +173,7 @@
char rx_state; /* current receiver state */
gint64 last_rx; /* timestamp of last packet received */
GList* active_chats; /* list of all our contacts we received messages from (active chats) */
+ GList* invites; /* list of all the invites that we have received */
/* groupchat */
GList* rooms; /* active groupchat rooms */
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/profile.c
--- a/libpurple/protocols/mxit/profile.c Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/profile.c Mon Apr 11 18:27:03 2011 +0000
@@ -23,6 +23,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
+#define _XOPEN_SOURCE
+#include
+
#include "internal.h"
#include "purple.h"
@@ -34,7 +37,7 @@
/*------------------------------------------------------------------------
* Returns true if it is a valid date.
*
- * @param bday Date-of-Birth string
+ * @param bday Date-of-Birth string (YYYY-MM-DD)
* @return TRUE if valid, else FALSE
*/
gboolean validateDate( const char* bday )
@@ -101,6 +104,40 @@
/*------------------------------------------------------------------------
+ * Calculate an Age from the date-of-birth.
+ *
+ * @param date Date-of-Birth string (YYYY-MM-DD)
+ * @return The age
+ */
+static int calculateAge( const char* date )
+{
+ time_t t;
+ struct tm now, bdate;
+ int age;
+
+ if ( ( !date ) || ( strlen( date ) == 0 ) )
+ return 0;
+
+ /* current time */
+ t = time(NULL);
+ localtime_r( &t, &now );
+
+ /* decode hdate */
+ memset( &bdate, 0, sizeof( struct tm ) );
+ strptime( date, "%Y-%m-%d", &bdate );
+
+ /* calculate difference */
+ age = now.tm_year - bdate.tm_year;
+ if ( now.tm_mon < bdate.tm_mon ) /* is before month of birth */
+ age--;
+ else if ( (now.tm_mon == bdate.tm_mon ) && ( now.tm_mday < bdate.tm_mday ) ) /* before birthday in current month */
+ age--;
+
+ return age;
+}
+
+
+/*------------------------------------------------------------------------
* Returns timestamp field in date & time format (DD-MM-YYYY HH:MM:SS)
*
* @param msecs The timestamps (milliseconds since epoch)
@@ -120,9 +157,9 @@
/*------------------------------------------------------------------------
* Display the profile information.
*
- * @param session The MXit session object
- * @param username The username who's profile information this is
- * @param profile The profile
+ * @param session The MXit session object
+ * @param username The username who's profile information this is
+ * @param profile The profile
*/
void mxit_show_profile( struct MXitSession* session, const char* username, struct MXitProfile* profile )
{
@@ -146,6 +183,11 @@
purple_notify_user_info_add_pair( info, _( "Last Name" ), profile->lastname );
purple_notify_user_info_add_pair( info, _( "Country" ), profile->regcountry );
+ if ( strlen( profile->aboutme ) > 0 )
+ purple_notify_user_info_add_pair( info, _( "About Me" ), profile->aboutme );
+ if ( strlen( profile->whereami ) > 0 )
+ purple_notify_user_info_add_pair( info, _( "Where I Live" ), profile->whereami );
+
purple_notify_user_info_add_section_break( info );
if ( contact ) {
@@ -172,7 +214,86 @@
/* hidden number */
purple_notify_user_info_add_pair( info, _( "Hidden Number" ), ( contact->flags & MXIT_CFLAG_HIDDEN ) ? _( "Yes" ) : _( "No" ) );
}
+ else {
+ /* this is an invite */
+ contact = get_mxit_invite_contact( session, username );
+ if ( contact ) {
+ /* invite found */
+
+ if ( contact->msg )
+ purple_notify_user_info_add_pair( info, _( "Invite Message" ), contact->msg );
+
+ if ( contact->imgid ) {
+ /* this invite has a avatar */
+ char* img_text;
+ img_text = g_strdup_printf( "
", contact->imgid );
+ purple_notify_user_info_add_pair( info, _( "Photo" ), img_text );
+ }
+
+ if ( contact->statusMsg )
+ purple_notify_user_info_add_pair( info, _( "Status Message" ), contact->statusMsg );
+ }
+ }
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 searchType The type of search (CP_SUGGEST_*)
+ * @param maxResults The maximum number of results
+ * @param entries The list of profile entries
+ */
+void mxit_show_search_results( struct MXitSession* session, int searchType, int maxResults, GList* entries )
+{
+ PurpleNotifySearchResults* results;
+ PurpleNotifySearchColumn* column;
+ gchar* text;
+
+ 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 );
+ column = purple_notify_searchresults_column_new( _( "Display Name" ) );
+ purple_notify_searchresults_column_add( results, column );
+ column = purple_notify_searchresults_column_new( _( "Gender" ) );
+ purple_notify_searchresults_column_add( results, column );
+ column = purple_notify_searchresults_column_new( _( "Age" ) );
+ purple_notify_searchresults_column_add( results, column );
+ column = purple_notify_searchresults_column_new( _( "Where I live" ) );
+ 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 ) );
+ row = g_list_append( row, g_strdup( profile->nickname ) );
+ row = g_list_append( row, g_strdup( profile->male ? "Male" : "Female" ) );
+ row = g_list_append( row, g_strdup_printf( "%i", calculateAge( profile->birthday ) ) );
+ row = g_list_append( row, g_strdup( profile->whereami ) );
+
+ purple_notify_searchresults_row_add( results, row );
+ entries = g_list_next( entries );
+ }
+
+ // TODO: add buttons
+
+ text = g_strdup_printf( _( "We found %i contacts that match your search." ), maxResults );
+
+ purple_notify_searchresults( session->con, NULL, text, NULL, results, NULL, NULL );
+
+ g_free( text);
+}
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/profile.h
--- a/libpurple/protocols/mxit/profile.h Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/profile.h Mon Apr 11 18:27:03 2011 +0000
@@ -32,26 +32,30 @@
struct MXitProfile {
/* required */
char loginname[64]; /* name user uses to log into MXit with (aka 'mxitid') */
- char nickname[64]; /* user's own display name (aka 'nickname', aka 'fullname', aka 'alias') in MXit */
+ char userid[51]; /* internal UserId (only in search results) */
+ char nickname[101]; /* user's own display name (aka 'display name', 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) */
char pin[16]; /* user's password */
/* optional */
- char title[32]; /* user's title */
- char firstname[64]; /* user's first name */
- char lastname[64]; /* user's last name (aka 'surname') */
- char email[64]; /* user's email address */
+ char title[21]; /* user's title */
+ char firstname[51]; /* user's first name */
+ char lastname[51]; /* user's last name (aka 'surname') */
+ char email[201]; /* user's email address */
char mobilenr[21]; /* user's mobile number */
char regcountry[3]; /* user's registered country code */
- gint64 flags; /* user's profile flags */
+ char whereami[51]; /* where am I / where I live */
+ char aboutme[513]; /* about me */
+
+ int flags; /* user's profile flags */
gint64 lastonline; /* user's last-online timestamp */
-
gboolean hidden; /* set if the user's msisdn should remain hidden */
};
struct MXitSession;
void mxit_show_profile( struct MXitSession* session, const char* username, struct MXitProfile* profile );
+void mxit_show_search_results( struct MXitSession* session, int searchType, int maxResults, GList* entries );
gboolean validateDate( const char* bday );
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/protocol.c
--- a/libpurple/protocols/mxit/protocol.c Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/protocol.c Mon Apr 11 18:27:03 2011 +0000
@@ -535,28 +535,31 @@
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.
* this is what we are trying to avoid here..
*/
- if ( session->last_tx > ( now - MXIT_TX_DELAY ) ) {
- /* we need to wait a little before sending the next packet, so schedule a wakeup call */
- gint64 tdiff = now - ( session->last_tx );
- guint delay = ( MXIT_TX_DELAY - tdiff ) + 9;
- if ( delay <= 0 )
- delay = MXIT_TX_DELAY;
- purple_timeout_add( delay, mxit_manage_queue_fast, session );
- }
- else {
- /* get the next packet from the queue to send */
- packet = pop_tx_packet( session );
- if ( packet != NULL ) {
- /* there was a packet waiting to be sent to the server, now is the time to do something about it */
-
- /* send the packet to MXit server */
- mxit_send_packet( session, packet );
+ if ( session->q_fast_timer_id == 0 ) {
+ /* the fast timer has not been set yet */
+ if ( session->last_tx > ( now - MXIT_TX_DELAY ) ) {
+ /* we need to wait a little before sending the next packet, so schedule a wakeup call */
+ gint64 tdiff = now - ( session->last_tx );
+ guint delay = ( MXIT_TX_DELAY - tdiff ) + 9;
+ if ( delay <= 0 )
+ delay = MXIT_TX_DELAY;
+ session->q_fast_timer_id = purple_timeout_add( delay, mxit_manage_queue_fast, session );
+ }
+ else {
+ /* get the next packet from the queue to send */
+ packet = pop_tx_packet( session );
+ if ( packet != NULL ) {
+ /* there was a packet waiting to be sent to the server, now is the time to do something about it */
+
+ /* send the packet to MXit server */
+ mxit_send_packet( session, packet );
+ }
}
}
}
@@ -587,6 +590,7 @@
{
struct MXitSession* session = (struct MXitSession*) user_data;
+ session->q_fast_timer_id = 0;
mxit_manage_queue( session );
/* stop running */
@@ -713,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,
@@ -844,7 +848,7 @@
* @param session The MXit session object
* @param password The new password to be used for logging in (optional)
* @param nr_attrib The number of attributes
- * @param attributes String containing the attributes and settings seperated by '0x01'
+ * @param attributes String containing the attribute-name, attribute-type and value (seperated by '\01')
*/
void mxit_send_extprofile_update( struct MXitSession* session, const char* password, unsigned int nr_attrib, const char* attributes )
{
@@ -853,7 +857,7 @@
int datalen;
unsigned int i;
- parts = g_strsplit( attributes, "\01", ( MXIT_MAX_ATTRIBS * 3 ) );
+ parts = g_strsplit( attributes, "\01", 1 + ( nr_attrib * 3 ) );
/* convert the packet to a byte stream */
datalen = snprintf( data, sizeof( data ),
@@ -880,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[] )
{
@@ -890,8 +894,8 @@
/* convert the packet to a byte stream */
datalen = snprintf( data, sizeof( data ),
- "ms=%i%c%s%c%i%c%i", /* inputType \1 input \ 1 maxSuggestions \1 numAttributes \1 name0 ... \1 nameN */
- CP_SUGGEST_FRIENDS, CP_FLD_TERM, "", CP_FLD_TERM, max, CP_FLD_TERM, nr_attrib );
+ "ms=%i%c%s%c%i%c%i%c%i", /* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */
+ CP_SUGGEST_FRIENDS, CP_FLD_TERM, "", CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib );
/* add attributes */
for ( i = 0; i < nr_attrib; i++ )
@@ -919,8 +923,8 @@
/* convert the packet to a byte stream */
datalen = snprintf( data, sizeof( data ),
- "ms=%i%c%s%c%i%c%i", /* inputType \1 input \ 1 maxSuggestions \1 numAttributes \1 name0 ... \1 nameN */
- CP_SUGGEST_SEARCH, CP_FLD_TERM, text, CP_FLD_TERM, max, CP_FLD_TERM, nr_attrib );
+ "ms=%i%c%s%c%i%c%i%c%i", /* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */
+ CP_SUGGEST_SEARCH, CP_FLD_TERM, text, CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib );
/* add attributes */
for ( i = 0; i < nr_attrib; i++ )
@@ -987,8 +991,9 @@
* @param username The username of the contact being invited
* @param alias Our alias for the contact
* @param groupname Group in which contact should be stored.
+ * @param message Invite message
*/
-void mxit_send_invite( struct MXitSession* session, const char* username, const char* alias, const char* groupname )
+void mxit_send_invite( struct MXitSession* session, const char* username, const char* alias, const char* groupname, const char* message )
{
char data[CP_MAX_PACKET];
int datalen;
@@ -997,7 +1002,7 @@
datalen = snprintf( data, sizeof( data ),
"ms=%s%c%s%c%s%c%i%c%s", /* "ms"=group\1username\1alias\1type\1msg */
groupname, CP_FLD_TERM, username, CP_FLD_TERM, alias,
- CP_FLD_TERM, MXIT_TYPE_MXIT, CP_FLD_TERM, ""
+ CP_FLD_TERM, MXIT_TYPE_MXIT, CP_FLD_TERM, ( message ? message : "" )
);
/* queue packet for transmission */
@@ -1441,7 +1446,7 @@
const char* statusmsg;
const char* profilelist[] = { CP_PROFILE_BIRTHDATE, CP_PROFILE_GENDER, CP_PROFILE_HIDENUMBER, CP_PROFILE_FULLNAME,
CP_PROFILE_TITLE, CP_PROFILE_FIRSTNAME, CP_PROFILE_LASTNAME, CP_PROFILE_EMAIL,
- CP_PROFILE_MOBILENR, CP_PROFILE_FLAGS };
+ CP_PROFILE_MOBILENR, CP_PROFILE_WHEREAMI, CP_PROFILE_ABOUTME, CP_PROFILE_FLAGS };
purple_account_set_int( session->acc, MXIT_CONFIG_STATE, MXIT_STATE_LOGIN );
@@ -1624,10 +1629,9 @@
if ( rec->fcount >= 5 ) {
/* there is a personal invite message attached */
- contact->msg = strdup( rec->fields[4]->data );
+ if ( ( rec->fields[4]->data ) && ( strlen( rec->fields[4]->data ) > 0 ) )
+ contact->msg = strdup( rec->fields[4]->data );
}
- else
- contact->msg = NULL;
/* handle the subscription */
if ( contact-> type == MXIT_TYPE_MULTIMX ) { /* subscription to a MultiMX room */
@@ -1850,6 +1854,14 @@
/* last seen online */
profile->lastonline = strtoll( fvalue, NULL, 10 );
}
+ else if ( strcmp( CP_PROFILE_WHEREAMI, fname ) == 0 ) {
+ /* where am I */
+ g_strlcpy( profile->whereami, fvalue, sizeof( profile->whereami ) );
+ }
+ else if ( strcmp( CP_PROFILE_ABOUTME, fname ) == 0) {
+ /* about me */
+ g_strlcpy( profile->aboutme, fvalue, sizeof( profile->aboutme ) );
+ }
else {
/* invalid profile attribute */
purple_debug_error( MXIT_PLUGIN_ID, "Invalid profile attribute received '%s' \n", fname );
@@ -1857,18 +1869,127 @@
}
if ( profile != session->profile ) {
- /* update avatar (if necessary) */
- if ( avatarId )
- mxit_update_buddy_avatar( session, mxitId, avatarId );
-
- /* if this is not our profile, just display it */
- mxit_show_profile( session, mxitId, profile );
- g_free( profile );
+ /* not our own profile */
+ struct contact* contact = NULL;
+
+ contact = get_mxit_invite_contact( session, mxitId );
+ if ( contact ) {
+ /* this is an invite, so update its profile info */
+ if ( ( statusMsg ) && ( strlen( statusMsg ) > 0 ) ) {
+ /* update the status message */
+ if ( contact->statusMsg )
+ g_free( contact->statusMsg );
+ contact->statusMsg = strdup( statusMsg );
+ }
+ else
+ contact->statusMsg = NULL;
+ if ( contact->profile )
+ g_free( contact->profile );
+ contact->profile = profile;
+ if ( ( avatarId ) && ( strlen( avatarId ) > 0 ) ) {
+ /* avatar must be requested for this invite before we can display it */
+ mxit_get_avatar( session, mxitId, avatarId );
+ if ( contact->avatarId )
+ g_free( contact->avatarId );
+ contact->avatarId = strdup( avatarId );
+ }
+ else {
+ /* display what we have */
+ contact->avatarId = NULL;
+ mxit_show_profile( session, mxitId, profile );
+ }
+ }
+ else {
+ /* this is a contact */
+ if ( avatarId )
+ mxit_update_buddy_avatar( session, mxitId, avatarId );
+ mxit_show_profile( session, mxitId, profile );
+ g_free( profile );
+ }
}
}
/*------------------------------------------------------------------------
+ * 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 )
+{
+ GList* entries = NULL;
+ int searchType;
+ int maxResults;
+ int count;
+ int i;
+
+ /*
+ * 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
+ */
+
+ /* the type of results */
+ searchType = atoi( records[0]->fields[0]->data );
+
+ /* the maximum number of results */
+ maxResults = atoi( records[0]->fields[2]->data );
+
+ /* set the count for attributes */
+ count = atoi( records[0]->fields[3]->data );
+
+ for ( i = 1; i < rcount; i ++ ) {
+ struct record* rec = records[i];
+ struct MXitProfile* profile = g_new0( struct MXitProfile, 1 );
+ int j;
+
+ g_strlcpy( profile->userid, rec->fields[0]->data, sizeof( profile->userid ) );
+ // TODO: ContactType - User or Service
+
+ for ( j = 0; j < count; j++ ) {
+ char* fname;
+ char* fvalue = "";
+
+ fname = records[0]->fields[4 + j]->data; /* field name */
+ if ( records[i]->fcount > ( 2 + j ) )
+ fvalue = records[i]->fields[2 + j]->data; /* field value */
+
+ purple_debug_info( MXIT_PLUGIN_ID, " %s: field='%s' value='%s'\n", profile->userid, fname, fvalue );
+
+ if ( strcmp( CP_PROFILE_BIRTHDATE, fname ) == 0 ) {
+ /* birthdate */
+ g_strlcpy( profile->birthday, fvalue, sizeof( profile->birthday ) );
+ }
+ else if ( strcmp( CP_PROFILE_GENDER, fname ) == 0 ) {
+ /* gender */
+ profile->male = ( fvalue[0] == '1' );
+ }
+ else if ( strcmp( CP_PROFILE_FULLNAME, fname ) == 0 ) {
+ /* nickname */
+ g_strlcpy( profile->nickname, fvalue, sizeof( profile->nickname ) );
+ }
+ else if ( strcmp( CP_PROFILE_WHEREAMI, fname ) == 0 ) {
+ /* where am I */
+ g_strlcpy( profile->whereami, fvalue, sizeof( profile->whereami ) );
+ }
+ /* ignore other attibutes */
+ }
+
+ entries = g_list_append( entries, profile );
+ }
+
+ /* display */
+ mxit_show_search_results( session, searchType, maxResults, 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
@@ -1960,6 +2081,7 @@
case CP_CHUNK_GET_AVATAR : /* get avatars */
{
struct getavatar_chunk chunk;
+ struct contact* contact = NULL;
/* decode the chunked data */
memset( &chunk, 0, sizeof ( struct getavatar_chunk ) );
@@ -1968,9 +2090,18 @@
/* update avatar image */
if ( chunk.data ) {
purple_debug_info( MXIT_PLUGIN_ID, "updating avatar for contact '%s'\n", chunk.mxitid );
- purple_buddy_icons_set_for_user( session->acc, chunk.mxitid, g_memdup( chunk.data, chunk.length), chunk.length, chunk.avatarid );
+
+ contact = get_mxit_invite_contact( session, chunk.mxitid );
+ if ( contact ) {
+ /* this is an invite (add image to the internal image store) */
+ contact->imgid = purple_imgstore_add_with_id( chunk.data, chunk.length, NULL );
+ mxit_show_profile( session, chunk.mxitid, contact->profile );
+ }
+ else {
+ /* this is a contact's avatar, so update it */
+ purple_buddy_icons_set_for_user( session->acc, chunk.mxitid, g_memdup( chunk.data, chunk.length), chunk.length, chunk.avatarid );
+ }
}
-
}
break;
@@ -2119,6 +2250,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 :
@@ -2637,9 +2773,13 @@
if ( session->http_timer_id > 0 )
purple_timeout_remove( session->http_timer_id );
- /* remove queue manager timer */
- if ( session->q_timer > 0 )
- purple_timeout_remove( session->q_timer );
+ /* remove slow queue manager timer */
+ if ( session->q_slow_timer_id > 0 )
+ purple_timeout_remove( session->q_slow_timer_id );
+
+ /* remove fast queue manager timer */
+ if ( session->q_fast_timer_id > 0 )
+ purple_timeout_remove( session->q_fast_timer_id );
/* remove all groupchat rooms */
while ( session->rooms != NULL ) {
@@ -2663,6 +2803,23 @@
g_list_free( session->active_chats );
session->active_chats = NULL;
+ /* clear the internal invites */
+ while ( session->invites != NULL ) {
+ struct contact* contact = (struct contact*) session->invites->data;
+
+ session->invites = g_list_remove( session->invites, contact );
+
+ if ( contact->msg )
+ g_free( contact->msg );
+ if ( contact->statusMsg )
+ g_free( contact->statusMsg );
+ if ( contact->profile )
+ g_free( contact->profile );
+ g_free( contact );
+ }
+ g_list_free( session->invites );
+ session->invites = NULL;
+
/* free profile information */
if ( session->profile )
free( session->profile );
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/protocol.h
--- a/libpurple/protocols/mxit/protocol.h Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/protocol.h Mon Apr 11 18:27:03 2011 +0000
@@ -110,7 +110,6 @@
/* Client settings */
#define MAX_QUEUE_SIZE ( 1 << 5 ) /* tx queue size (32 packets) */
#define MXIT_POPUP_WIN_NAME "MXit Notification" /* popup window name */
-#define MXIT_MAX_ATTRIBS 10 /* maximum profile attributes supported */
#define MXIT_DEFAULT_LOCALE "en" /* default locale setting */
#define MXIT_DEFAULT_LOC "planetpurple" /* the default location for registration */
@@ -194,14 +193,19 @@
#define CP_PROFILE_REGCOUNTRY "registeredcountry" /* Registered Country Code (UTF8 String) */
#define CP_PROFILE_FLAGS "flags" /* Profile flags (Bitset) */
#define CP_PROFILE_LASTSEEN "lastseen" /* Last-Online timestamp */
+#define CP_PROFILE_WHEREAMI "whereami" /* Where am I / Where I live */
+#define CP_PROFILE_ABOUTME "aboutme" /* About me */
/* extended profile field types */
-#define CP_PROFILE_TYPE_BOOL 0x02 /* boolean profile attribute type */
-#define CP_PROFILE_TYPE_INT 0x05 /* integer profile attribute type */
-#define CP_PROFILE_TYPE_UTF8 0x0A /* UTF8 string profile attribute type */
-#define CP_PROFILE_TYPE_DATE 0x0B /* date-time profile attribute type */
+#define CP_PROFILE_TYPE_BOOL 0x02 /* boolean (0 or 1) */
+#define CP_PROFILE_TYPE_INT 0x05 /* integer (32-bit) */
+#define CP_PROFILE_TYPE_LONG 0x06 /* long (64-bit) */
+#define CP_PROFILE_TYPE_UTF8 0x0A /* UTF8 string */
+#define CP_PROFILE_TYPE_DATE 0x0B /* date-time (ISO 8601 format) */
/* profile flags */
+#define CP_PROF_NOT_SEARCHABLE 0x02 /* user cannot be searched for */
+#define CP_PROF_NOT_SUGGESTABLE 0x08 /* user cannot be suggested as friend */
#define CP_PROF_DOBLOCKED 0x40 /* date-of-birth cannot be changed */
/* suggestion types */
@@ -305,7 +309,7 @@
void mxit_send_suggest_friends( struct MXitSession* session, int max, unsigned int nr_attrib, const char* attribute[] );
void mxit_send_suggest_search( struct MXitSession* session, int max, const char* text, unsigned int nr_attrib, const char* attribute[] );
-void mxit_send_invite( struct MXitSession* session, const char* username, const char* alias, const char* groupname );
+void mxit_send_invite( struct MXitSession* session, const char* username, const char* alias, const char* groupname, const char* message );
void mxit_send_remove( struct MXitSession* session, const char* username );
void mxit_send_allow_sub( struct MXitSession* session, const char* username, const char* alias );
void mxit_send_deny_sub( struct MXitSession* session, const char* username );
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/roster.c
--- a/libpurple/protocols/mxit/roster.c Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/roster.c Mon Apr 11 18:27:03 2011 +0000
@@ -564,8 +564,8 @@
buddy = g_slist_nth_data( list, i );
if ( !purple_buddy_get_protocol_data( buddy ) ) {
- const gchar *alias = purple_buddy_get_alias( buddy );
- const gchar *name = purple_buddy_get_name( buddy );
+ const gchar* alias = purple_buddy_get_alias( buddy );
+ const gchar* name = purple_buddy_get_name( buddy );
/* this buddy should be removed, because we did not receive him in our roster update from MXit */
purple_debug_info( MXIT_PLUGIN_ID, "Removed 'old' buddy from the blist '%s' (%s)\n", alias, name );
@@ -592,9 +592,16 @@
/* send a allow subscription packet to MXit */
mxit_send_allow_sub( invite->session, invite->contact->username, invite->contact->alias );
+ /* remove the invite from our internal invites list */
+ invite->session->invites = g_list_remove( invite->session->invites, invite->contact );
+
/* freeup invite object */
if ( invite->contact->msg )
g_free( invite->contact->msg );
+ if ( invite->contact->statusMsg )
+ g_free( invite->contact->statusMsg );
+ if ( invite->contact->profile )
+ g_free( invite->contact->profile );
g_free( invite->contact );
g_free( invite );
}
@@ -614,9 +621,16 @@
/* send a deny subscription packet to MXit */
mxit_send_deny_sub( invite->session, invite->contact->username );
+ /* remove the invite from our internal invites list */
+ invite->session->invites = g_list_remove( invite->session->invites, invite->contact );
+
/* freeup invite object */
if ( invite->contact->msg )
g_free( invite->contact->msg );
+ if ( invite->contact->statusMsg )
+ g_free( invite->contact->statusMsg );
+ if ( invite->contact->profile )
+ g_free( invite->contact->profile );
g_free( invite->contact );
g_free( invite );
}
@@ -639,12 +653,42 @@
invite->session = session;
invite->contact = contact;
+ /* add the invite to our internal invites list */
+ invite->session->invites = g_list_append( invite->session->invites, invite->contact );
+
/* (reference: "libpurple/account.h") */
purple_account_request_authorization( session->acc, contact->username, NULL, contact->alias, contact->msg, FALSE, mxit_cb_buddy_auth, mxit_cb_buddy_deny, invite );
}
/*------------------------------------------------------------------------
+ * Return the contact object for a mxit invite
+ *
+ * @param session The MXit session object
+ * @param username The username of the contact
+ * @return The contact object for the inviting user
+ */
+struct contact* get_mxit_invite_contact( struct MXitSession* session, const char* username )
+{
+ struct contact* con = NULL;
+ struct contact* match = NULL;
+ int i;
+
+ /* run through all the invites and try and find the match */
+ for ( i = 0; i < g_list_length( session->invites ); i++ ) {
+ con = g_list_nth_data( session->invites, i );
+ if ( strcmp( con->username, username ) == 0 ) {
+ /* invite found */
+ match = con;
+ break;
+ }
+ }
+
+ return match;
+}
+
+
+/*------------------------------------------------------------------------
* Return TRUE if this is a MXit Chatroom contact.
*
* @param session The MXit session object
@@ -680,8 +724,9 @@
* @param gc The connection object
* @param buddy The new buddy
* @param group The group of the new buddy
+ * @param message The invite message
*/
-void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group )
+void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group, const char* message )
{
struct MXitSession* session = (struct MXitSession*) gc->proto_data;
GSList* list = NULL;
@@ -702,7 +747,7 @@
* you accept an invite. so in that case the user is already
* in our blist and ready to be chatted to.
*/
- mxit_send_invite( session, buddy_name, buddy_alias, group_name );
+ mxit_send_invite( session, buddy_name, buddy_alias, group_name, message );
}
else {
purple_debug_info( MXIT_PLUGIN_ID, "mxit_add_buddy (scenario 2) (list:%i)\n", g_slist_length( list ) );
diff -r ba00769a1493 -r 12676cfd4a1e libpurple/protocols/mxit/roster.h
--- a/libpurple/protocols/mxit/roster.h Sun Apr 10 19:21:27 2011 +0000
+++ b/libpurple/protocols/mxit/roster.h Mon Apr 11 18:27:03 2011 +0000
@@ -121,6 +121,10 @@
char customMood[16]; /* custom mood */
char* statusMsg; /* status message */
char* avatarId; /* avatarId */
+
+ /* invites only */
+ void* profile; /* user's profile (if available) */
+ int imgid; /* avatar image id in the imgstore */
};
/* Presence / Status */
@@ -140,9 +144,10 @@
void mxit_new_subscription( struct MXitSession* session, struct contact* contact );
void mxit_update_blist( struct MXitSession* session );
gboolean is_mxit_chatroom_contact( struct MXitSession* session, const char* username );
+struct contact* get_mxit_invite_contact( struct MXitSession* session, const char* username );
/* libPurple callbacks */
-void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group );
+void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group, const char* message );
void mxit_remove_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group );
void mxit_buddy_alias( PurpleConnection* gc, const char* who, const char* alias );
void mxit_buddy_group( PurpleConnection* gc, const char* who, const char* old_group, const char* new_group );