changeset 30360:eafb928fe614

propagate from branch 'im.pidgin.pidgin.mxit' (head ad23bba01aa6026230a0aa76ea2e27d0dfb5c106) to branch 'im.pidgin.pidgin' (head 54b2ac9fc179bd46065882041bbaa7b4b6bafce6)
author John Bailey <rekkanoryo@rekkanoryo.org>
date Thu, 13 May 2010 22:51:00 +0000
parents 129f973c38b5 (current diff) 478a75d3100f (diff)
children 46275cca345e 859bb4ab3efe 4463cd2aba2d
files
diffstat 14 files changed, 200 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/mxit/actions.c	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/actions.c	Thu May 13 22:51:00 2010 +0000
@@ -35,89 +35,6 @@
 #include	"profile.h"
 
 
-/* MXit Moods */
-static const char*	moods[] = {
-	/* 0 */		N_("None"),
-	/* 1 */		N_("Angry"),
-	/* 2 */		N_("Excited"),
-	/* 3 */		N_("Grumpy"),
-	/* 4 */		N_("Happy"),
-	/* 5 */		N_("In Love"),
-	/* 6 */		N_("Invincible"),
-	/* 7 */		N_("Sad"),
-	/* 8 */		N_("Hot"),
-	/* 9 */		N_("Sick"),
-	/* 10 */	N_("Sleepy")
-};
-
-
-/*------------------------------------------------------------------------
- * The user has selected to change their current mood.
- *
- *  @param gc		The connection object
- *  @param fields	The fields from the request pop-up
- */
-static void mxit_cb_set_mood( PurpleConnection* gc, PurpleRequestFields* fields )
-{
-	struct MXitSession*		session	= (struct MXitSession*) gc->proto_data;
-	int						mood	= purple_request_fields_get_choice( fields, "mood" );
-
-	purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_set_mood (%i)\n", mood );
-
-	if ( !PURPLE_CONNECTION_IS_VALID( gc ) ) {
-		purple_debug_error( MXIT_PLUGIN_ID, "Unable to set mood; account offline.\n" );
-		return;
-	}
-
-	/* Save the new mood in session */
-	session->mood = mood;
-
-	/* now send the update to MXit */
-	mxit_send_mood( session, mood );
-}
-
-
-/*------------------------------------------------------------------------
- * Create and display the mood selection window to the user.
- *
- *  @param action	The action object
- */
-static void mxit_cb_action_mood( PurplePluginAction* action )
-{
-	PurpleConnection*			gc		= (PurpleConnection*) action->context;
-	struct MXitSession*			session	= (struct MXitSession*) gc->proto_data;
-
-	PurpleRequestFields*		fields	= NULL;
-	PurpleRequestFieldGroup*	group	= NULL;
-	PurpleRequestField*			field	= NULL;
-	unsigned int				i		= 0;
-
-	purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_action_mood\n" );
-
-	fields = purple_request_fields_new();
-	group = purple_request_field_group_new( NULL );
-	purple_request_fields_add_group( fields, group );
-
-	/* show current mood */
-	field = purple_request_field_string_new( "current", _( "Current Mood" ), _( moods[session->mood] ), FALSE );
-	purple_request_field_string_set_editable( field, FALSE );	/* current mood field is not editable */
-	purple_request_field_group_add_field( group, field );
-
-	/* add all moods to list */
-	field = purple_request_field_choice_new( "mood", _( "New Mood" ), 0 );
-	for ( i = 0; i < ARRAY_SIZE( moods ); i++ ) {
-		purple_request_field_choice_add( field, _( moods[i] ) );
-	}
-	purple_request_field_set_required( field, TRUE );
-	purple_request_field_choice_set_default_value( field, session->mood );
-	purple_request_field_group_add_field( group, field );
-
-	/* (reference: "libpurple/request.h") */
-	purple_request_fields( gc, _( "Mood" ), _( "Change your Mood" ), _( "How do you feel right now?" ), fields, _( "Set" ),
-			G_CALLBACK( mxit_cb_set_mood ), _( "Cancel" ), NULL, purple_connection_get_account( gc ), NULL, NULL, gc );
-}
-
-
 /*------------------------------------------------------------------------
  * The user has selected to change their profile.
  *
@@ -409,10 +326,6 @@
 	PurplePluginAction*		action	= NULL;
 	GList*					m		= NULL;
 
-	/* display / change mood */
-	action = purple_plugin_action_new( _( "Change Mood..." ), mxit_cb_action_mood );
-	m = g_list_append( m, action );
-
 	/* display / change profile */
 	action = purple_plugin_action_new( _( "Change Profile..." ), mxit_cb_action_profile );
 	m = g_list_append( m, action );
--- a/libpurple/protocols/mxit/login.c	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/login.c	Thu May 13 22:51:00 2010 +0000
@@ -67,7 +67,7 @@
 	/* configure the connection (reference: "libpurple/connection.h") */
 	con = purple_account_get_connection( account );
 	con->proto_data = session;
-	con->flags |= PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_HTML;
+	con->flags |= PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_NO_URLDESC | PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_SUPPORT_MOODS;
 	session->con = con;
 
 	/* add account */
--- a/libpurple/protocols/mxit/multimx.c	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/multimx.c	Thu May 13 22:51:00 2010 +0000
@@ -142,6 +142,10 @@
 	multimx->chatid = groupchatID++;
 	multimx->state = state;
 
+	/* determine our nickname (from profile) */
+	if (session->profile && (session->profile->nickname[0] != '\0'))
+		multimx->nickname = g_strdup(session->profile->nickname);
+
 	/* Add to GroupChat list */
 	session->rooms = g_list_append(session->rooms, multimx);
 
@@ -160,6 +164,10 @@
 	/* Remove from GroupChat list */
 	session->rooms = g_list_remove(session->rooms, multimx);
 
+	/* free nickname */
+	if (multimx->nickname)
+		g_free(multimx->nickname);
+
 	/* Deallocate it */
 	free (multimx);
 	multimx = NULL;
@@ -213,6 +221,38 @@
 
 
 /*------------------------------------------------------------------------
+ * A user was kicked from the GroupChat.
+ *
+ *  @param session		The MXit session object
+ *  @param multimx		The MultiMX room object
+ *  @param nickname		The nickname of the user who was kicked
+ */
+static void member_kicked(struct MXitSession* session, struct multimx* multimx, 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;
+	}
+
+	/* 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"));
+}
+
+
+/*------------------------------------------------------------------------
  * Update the full GroupChat member list.
  *
  *  @param session		The MXit session object
@@ -375,6 +415,12 @@
 			member_removed(mx->session, multimx, 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);
+			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);
 			mx->processed = TRUE;
@@ -582,8 +628,8 @@
 	mxit_send_message(session, multimx->roomid, message, TRUE, FALSE);
 	
 	/* Determine our nickname to display */
-	if (session->profile && (session->profile->nickname[0] != '\0'))		/* default is profile name (since that's what everybody else sees) */
-		 nickname = session->profile->nickname;
+	if (multimx->nickname)
+		nickname = multimx->nickname;
 	else
 		nickname = purple_account_get_alias(purple_connection_get_account(gc));		/* local alias */
 
--- a/libpurple/protocols/mxit/multimx.h	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/multimx.h	Thu May 13 22:51:00 2010 +0000
@@ -41,6 +41,7 @@
 	char	roomname[MXIT_CP_MAX_ALIAS_LEN];	/* name of the room */
 	char	roomid[MXIT_CP_MAX_JID_LEN];		/* internal JID for room */
 	int		chatid;								/* libpurple chat ID */
+	char*	nickname;							/* our nickname in the room */
 	short	state;								/* state */
 };
 
--- a/libpurple/protocols/mxit/mxit.c	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/mxit.c	Thu May 13 22:51:00 2010 +0000
@@ -92,6 +92,9 @@
 		goto skip;
 	con = purple_account_get_connection( account );
 
+//	/* determine if it's a command-response to send */
+//	is_command = g_str_has_prefix( parts[4], "::type=reply|" );
+
 	/* send click message back to MXit */
 	mxit_send_message( con->proto_data, parts[3], parts[4], FALSE, is_command );
 
@@ -418,6 +421,24 @@
 	char*					statusmsg1;
 	char*					statusmsg2;
 
+	/* Handle mood changes */
+	if (purple_status_type_get_primitive(purple_status_get_type(status)) == PURPLE_STATUS_MOOD) {
+		const char* moodid = purple_status_get_attr_string( status, PURPLE_MOOD_NAME );
+		int mood;
+
+		/* convert the purple mood to a mxit mood */
+		mood = mxit_convert_mood( moodid );
+		if ( mood < 0 ) {
+			/* error, mood not found */
+			purple_debug_info( MXIT_PLUGIN_ID, "Mood status NOT found! (id = %s)\n", moodid );
+			return;
+		}
+
+		/* update mood state */
+		mxit_send_mood( session, mood );
+		return;
+	}
+
 	/* get the status id (reference: "libpurple/status.h") */
 	statusid = purple_status_get_id( status );
 
@@ -635,7 +656,7 @@
 	mxit_get_text_table,	/* get_account_text_table */
 	NULL,					/* initiate_media */
 	NULL,					/* get_media_caps */
-	NULL,					/* get_moods */
+	mxit_get_moods,			/* get_moods */
 	NULL,					/* set_public_alias */
 	NULL					/* get_public_alias */
 };
--- a/libpurple/protocols/mxit/mxit.h	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/mxit.h	Thu May 13 22:51:00 2010 +0000
@@ -151,7 +151,6 @@
 
 	/* personal (profile) */
 	struct MXitProfile*	profile;					/* user's profile information */
-	int					mood;						/* user's current mood */
 
 	/* libpurple */
 	PurpleAccount*		acc;						/* pointer to the libpurple internal account struct */
--- a/libpurple/protocols/mxit/protocol.c	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/protocol.c	Thu May 13 22:51:00 2010 +0000
@@ -962,6 +962,31 @@
 
 
 /*------------------------------------------------------------------------
+ * Send a message event packet.
+ *
+ *  @param session		The MXit session object
+ *  @param to           The username of the original sender (ie, recipient of the event)
+ *  @param id			The identifier of the event (received in message)
+ *  @param event		Identified the type of event
+ */
+void mxit_send_msgevent( struct MXitSession* session, const char* to, const char* id, int event)
+{
+	char		data[CP_MAX_PACKET];
+	int			datalen;
+
+	purple_debug_info( MXIT_PLUGIN_ID, "mxit_send_msgevent: to=%s id=%s event=%i\n", to, id, event );
+
+	/* convert the packet to a byte stream */
+	datalen = sprintf( data,	"ms=%s%c%s%c%i",		/* "ms"=contactAddress \1 id \1 event */
+								to, CP_FLD_TERM, id, CP_FLD_TERM, event
+	);
+
+	/* queue packet for transmission */
+	mxit_queue_packet( session, data, datalen, CP_CMD_MSGEVENT );
+}
+
+
+/*------------------------------------------------------------------------
  * Send packet to create a MultiMX room.
  *
  *  @param session		The MXit session object
@@ -1355,6 +1380,12 @@
 		return;
 	}
 
+	if ( msgflags & CP_MSG_NOTIFY_DELIVERY ) {
+		/* delivery notification is requested */
+		if ( records[0]->fcount >= 4 )
+			mxit_send_msgevent( session, records[0]->fields[0]->data, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED );
+	}
+
 	/* create and initialise new markup struct */
 	mx = g_new0( struct RXMsgData, 1 );
 	mx->msg = g_string_sized_new( msglen );
@@ -1917,6 +1948,8 @@
 				/* profile update */
 		case CP_CMD_SPLASHCLICK :
 				/* splash-screen clickthrough */
+		case CP_CMD_MSGEVENT :
+				/* event message */
 				break;
 
 		default :
@@ -2020,6 +2053,7 @@
 				mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Profile Error" ), _( errdesc ) );
 				break;
 		case CP_CMD_SPLASHCLICK :
+		case CP_CMD_MSGEVENT :
 				/* ignore error */
 				break;
 		case CP_CMD_PING :
--- a/libpurple/protocols/mxit/protocol.h	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/protocol.h	Thu May 13 22:51:00 2010 +0000
@@ -72,6 +72,9 @@
 #define		MXIT_CF_EXT_MARKUP		0x040000
 #define		MXIT_CF_PLAIN_PWD		0x080000
 #define		MXIT_CF_NO_GATEWAYS		0x100000
+#define		MXIT_CF_NO_AVATARS		0x200000
+#define		MXIT_CF_GAMING			0x400000
+#define		MXIT_CF_GAMING_UPDATE	0x800000
 
 /* Client features supported by this implementation */
 #define		MXIT_CP_FEATURES		( MXIT_CF_FILE_TRANSFER | MXIT_CF_FILE_ACCESS | MXIT_CF_AUDIO | MXIT_CF_MARKUP | MXIT_CF_EXT_MARKUP | MXIT_CF_NO_GATEWAYS | MXIT_CF_IMAGES | MXIT_CF_COMMANDS | MXIT_CF_VIBES | MXIT_CF_MIDP2 )
@@ -126,6 +129,7 @@
 #define		CP_CMD_MEDIA			0x001B					/* (27) get multimedia message */
 #define		CP_CMD_SPLASHCLICK		0x001F					/* (31) splash-screen clickthrough */
 #define		CP_CMD_STATUS			0x0020					/* (32) set shown presence & status */
+#define		CP_CMD_MSGEVENT			0x0023					/* (35) Raise message event */ 
 #define		CP_CMD_MOOD				0x0029					/* (41) set mood */
 #define		CP_CMD_KICK				0x002B					/* (43) login kick */
 #define		CP_CMD_GRPCHAT_CREATE	0x002C					/* (44) create new groupchat */
@@ -147,6 +151,8 @@
 #define		RX_STATE_PROC			0x03					/* process read data */
 
 /* message flags */
+#define		CP_MSG_NOTIFY_DELIVERY	0x0002					/* request delivery notification */
+#define		CP_MSG_NOTIFY_READ		0x0004					/* request read notification */
 #define		CP_MSG_ENCRYPTED		0x0010					/* message is encrypted */
 #define		CP_MSG_MARKUP			0x0200					/* message may contain markup */
 #define		CP_MSG_EMOTICON			0x0400					/* message may contain custom emoticons */
@@ -164,6 +170,9 @@
 #define		CP_MSGTYPE_FORM			0x06					/* mxit custom form */
 #define		CP_MSGTYPE_COMMAND		0x07					/* mxit command */
 
+/* message event types */
+#define		CP_MSGEVENT_DELIVERED	0x02					/* message was delivered */
+#define		CP_MSGEVENT_DISPLAYED	0x04					/* message was viewed */
 
 /* extended profile attribute fields */
 #define		CP_PROFILE_BIRTHDATE	"birthdate"				/* Birthdate (String - ISO 8601 format) */
@@ -284,6 +293,7 @@
 void mxit_send_deny_sub( struct MXitSession* session, const char* username );
 void mxit_send_update_contact( struct MXitSession* session, const char* username, const char* alias, const char* groupname );
 void mxit_send_splashclick( struct MXitSession* session, const char* splashid );
+void mxit_send_msgevent( struct MXitSession* session, const char* to, const char* id, int event);
 
 void mxit_send_file( struct MXitSession* session, const char* username, const char* filename, const unsigned char* buf, int buflen );
 void mxit_send_file_reject( struct MXitSession* session, const char* fileid );
--- a/libpurple/protocols/mxit/roster.c	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/roster.c	Thu May 13 22:51:00 2010 +0000
@@ -81,6 +81,12 @@
 		statuslist = g_list_append( statuslist, type );
 	}
 
+	/* add Mood option */
+	type = purple_status_type_new_with_attrs(PURPLE_STATUS_MOOD, "mood", NULL, FALSE, TRUE, TRUE,
+		PURPLE_MOOD_NAME, _("Mood Name"), purple_value_new( PURPLE_TYPE_STRING ),
+		NULL);
+	statuslist = g_list_append( statuslist, type );
+
 	return statuslist;
 }
 
@@ -127,6 +133,57 @@
  * Moods
  */
 
+/* moods (reference: libpurple/status.h) */
+static PurpleMood mxit_moods[] = {
+	{"angry",		N_("Angry"),		NULL},
+	{"excited",		N_("Excited"),		NULL},
+	{"grumpy",		N_("Grumpy"),		NULL},
+	{"happy",		N_("Happy"),		NULL},
+	{"in_love",		N_("In love"),		NULL},
+	{"invincible",	N_("Invincible"),	NULL},
+	{"sad",			N_("Sad"),			NULL},
+	{"hot",			N_("Hot"),			NULL},
+	{"sick",		N_("Sick"),			NULL},
+	{"sleepy",		N_("Sleepy"),		NULL},
+	/* Mark the last record. */
+	{ NULL, NULL, NULL }
+};
+
+
+/*------------------------------------------------------------------------
+ * Returns the MXit mood code, given the unique mood ID.
+ *
+ *  @param id		The mood ID
+ *  @return			The MXit mood code
+ */
+int mxit_convert_mood( const char* id )
+{
+	unsigned int	i;
+
+	/* Mood is being unset */
+	if ( id == NULL )
+		return MXIT_MOOD_NONE;
+
+	for ( i = 0; i < ARRAY_SIZE( mxit_moods ) - 1; i++ ) {
+		if ( strcmp( mxit_moods[i].mood, id ) == 0 )	/* mood found! */
+			return i + 1;		/* because MXIT_MOOD_NONE is 0 */
+	}
+
+	return -1;
+}
+
+
+/*------------------------------------------------------------------------
+ * Return the list of MXit-supported moods.
+ *
+ *  @param account	The MXit account object
+ */
+PurpleMood* mxit_get_moods(PurpleAccount *account)
+{
+	return mxit_moods;
+}
+
+
 /*------------------------------------------------------------------------
  * Returns the MXit mood as a string, given the MXit mood's ID.
  *
@@ -259,6 +316,12 @@
 			else
 				purple_prpl_got_user_status( session->acc, newbuddy->name, mxit_statuses[contact->presence].id, NULL );
 
+			/* update the buddy's mood */
+			if ( contact->mood == MXIT_MOOD_NONE )
+				purple_prpl_got_user_status_deactive( session->acc, newbuddy->name, "mood" );
+			else
+				purple_prpl_got_user_status( session->acc, newbuddy->name, "mood", PURPLE_MOOD_NAME, mxit_moods[contact->mood-1].mood, NULL );
+
 			/* update avatar */
 			if ( contact->avatarId ) {
 				mxit_get_avatar( session, newbuddy->name, contact->avatarId );
@@ -346,6 +409,12 @@
 
 	/* update the buddy's status (reference: "libpurple/prpl.h") */
 	purple_prpl_got_user_status( session->acc, contact->username, mxit_statuses[contact->presence].id, NULL );
+
+	/* update the buddy's mood */
+	if ( contact->mood == MXIT_MOOD_NONE )
+		purple_prpl_got_user_status_deactive( session->acc, contact->username, "mood" );
+	else
+		purple_prpl_got_user_status( session->acc, contact->username, "mood", PURPLE_MOOD_NAME, mxit_moods[contact->mood-1].mood, NULL );
 }
 
 
@@ -388,6 +457,10 @@
 	contact->presence = presence;	
 	contact->mood = mood;
 
+	/* validate mood */
+	if (( contact->mood < MXIT_MOOD_NONE ) || ( contact->mood > MXIT_MOOD_SLEEPY ))
+		contact->mood = MXIT_MOOD_NONE;
+
 	g_strlcpy( contact->customMood, customMood, sizeof( contact->customMood ) );
 	// TODO: Download custom mood frame.
 
@@ -419,6 +492,12 @@
 		purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, "message", contact->statusMsg, NULL );
 	else
 		purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, NULL );
+
+	/* update the buddy's mood */
+	if ( contact->mood == MXIT_MOOD_NONE )
+		purple_prpl_got_user_status_deactive( session->acc, username, "mood" );
+	else
+		purple_prpl_got_user_status( session->acc, username, "mood", PURPLE_MOOD_NAME, mxit_moods[contact->mood-1].mood, NULL );
 }
 
 
--- a/libpurple/protocols/mxit/roster.h	Thu May 13 22:45:19 2010 +0000
+++ b/libpurple/protocols/mxit/roster.h	Thu May 13 22:51:00 2010 +0000
@@ -119,6 +119,7 @@
 const char* mxit_convert_subtype_to_name( short subtype );
 
 /* Moods */
+int mxit_convert_mood( const char* id );
 const char* mxit_convert_mood_to_name( short id );
 
 /* MXit Protocol callbacks */
@@ -134,6 +135,7 @@
 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 );
 void mxit_rename_group( PurpleConnection* gc, const char* old_name, PurpleGroup* group, GList* moved_buddies );
+PurpleMood* mxit_get_moods(PurpleAccount *account);
 
 
 #endif		/* _MXIT_ROSTER_H_ */
--- a/pidgin/pixmaps/emotes/small/16/Makefile.am	Thu May 13 22:45:19 2010 +0000
+++ b/pidgin/pixmaps/emotes/small/16/Makefile.am	Thu May 13 22:51:00 2010 +0000
@@ -5,7 +5,10 @@
     cinema.png \
     disappointed.png \
     embarrassed.png \
+    grumpy.png \
+    hot.png \
     internet.png \
+    invincible.png \
     music.png \
     restroom.png \
     search.png \
Binary file pidgin/pixmaps/emotes/small/16/grumpy.png has changed
Binary file pidgin/pixmaps/emotes/small/16/hot.png has changed
Binary file pidgin/pixmaps/emotes/small/16/invincible.png has changed