/cpw/tomkiewicz/gg11: ddcc82637afa: Gadu-Gadu: incoming images w...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Sat Sep 15 03:33:38 EDT 2012


Changeset: ddcc82637afa2ec8f441ae51be8a772b4161804d
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-09-15 09:33 +0200
Branch:	 default
URL: http://hg.pidgin.im/cpw/tomkiewicz/gg11/rev/ddcc82637afa

Description:

Gadu-Gadu: incoming images works again

diffstat:

 libpurple/protocols/gg/chat.c            |    5 -
 libpurple/protocols/gg/gg.c              |    7 +
 libpurple/protocols/gg/gg.h              |    2 +
 libpurple/protocols/gg/image.c           |  157 ++++++++++++++--------------
 libpurple/protocols/gg/image.h           |    7 +-
 libpurple/protocols/gg/message-prpl.c    |  169 ++++++++++++++++++++++++++++++-
 libpurple/protocols/gg/message-prpl.h    |    4 +
 libpurple/protocols/gg/resolver-purple.c |    2 +-
 libpurple/protocols/gg/utils.c           |   19 +++
 libpurple/protocols/gg/utils.h           |    4 +
 10 files changed, 289 insertions(+), 87 deletions(-)

diffs (truncated from 651 to 300 lines):

diff --git a/libpurple/protocols/gg/chat.c b/libpurple/protocols/gg/chat.c
--- a/libpurple/protocols/gg/chat.c
+++ b/libpurple/protocols/gg/chat.c
@@ -55,11 +55,6 @@ void ggp_chat_setup(PurpleConnection *gc
 	ggp_chat_session_data *sdata = g_new0(ggp_chat_session_data, 1);
 
 	accdata->chat_data = sdata;
-
-	sdata->chats = NULL;
-	sdata->chats_count = 0;
-	sdata->got_all_chats_info = FALSE;
-	sdata->pending_joins = NULL;
 }
 
 void ggp_chat_cleanup(PurpleConnection *gc)
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -301,6 +301,11 @@ static void ggp_callback_recv(gpointer _
 		case GG_EVENT_NONE:
 			/* Nothing happened. */
 			break;
+		case GG_EVENT_CONN_FAILED:
+			purple_connection_error (gc,
+				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
+				_("Server disconnected"));
+			break;
 		case GG_EVENT_MSG:
 			ggp_message_got(gc, &ev->event.msg);
 			break;
@@ -627,6 +632,7 @@ static void ggp_login(PurpleAccount *acc
 	ggp_multilogon_setup(gc);
 	ggp_status_setup(gc);
 	ggp_chat_setup(gc);
+	ggp_message_setup(gc);
 
 	glp->uin = ggp_str_to_uin(purple_account_get_username(account));
 	glp->password = ggp_convert_to_cp1250(purple_account_get_password(account));
@@ -737,6 +743,7 @@ static void ggp_close(PurpleConnection *
 		ggp_multilogon_cleanup(gc);
 		ggp_status_cleanup(gc);
 		ggp_chat_cleanup(gc);
+		ggp_message_cleanup(gc);
 
 		if (info->inpa > 0)
 			purple_input_remove(info->inpa);
diff --git a/libpurple/protocols/gg/gg.h b/libpurple/protocols/gg/gg.h
--- a/libpurple/protocols/gg/gg.h
+++ b/libpurple/protocols/gg/gg.h
@@ -36,6 +36,7 @@
 #include "multilogon.h"
 #include "status.h"
 #include "chat.h"
+#include "message-prpl.h"
 
 #define PUBDIR_RESULTS_MAX 20
 
@@ -51,6 +52,7 @@ typedef struct {
 	ggp_multilogon_session_data *multilogon_data;
 	ggp_status_session_data *status_data;
 	ggp_chat_session_data *chat_data;
+	ggp_message_session_data *message_data;
 } GGPInfo;
 
 typedef struct
diff --git a/libpurple/protocols/gg/image.c b/libpurple/protocols/gg/image.c
--- a/libpurple/protocols/gg/image.c
+++ b/libpurple/protocols/gg/image.c
@@ -36,13 +36,7 @@
 #include "utils.h"
 
 #define GGP_PENDING_IMAGE_ID_PREFIX "gg-pending-image-"
-
-typedef struct
-{
-	uin_t from;
-	gchar *text;
-	time_t mtime;
-} ggp_image_pending_message;
+#define GGP_IMAGE_MAX_SIZE 255000
 
 typedef struct
 {
@@ -50,13 +44,16 @@ typedef struct
 	gchar *conv_name;
 } ggp_image_pending_image;
 
-static void ggp_image_pending_message_free(gpointer data)
+typedef struct
 {
-	ggp_image_pending_message *pending_message =
-		(ggp_image_pending_message*)data;
-	g_free(pending_message->text);
-	g_free(pending_message);
-}
+	GList *listeners;
+} ggp_image_requested;
+
+typedef struct
+{
+	ggp_image_request_cb cb;
+	gpointer user_data;
+} ggp_image_requested_listener;
 
 static void ggp_image_pending_image_free(gpointer data)
 {
@@ -66,6 +63,13 @@ static void ggp_image_pending_image_free
 	g_free(pending_image);
 }
 
+static void ggp_image_requested_free(gpointer data)
+{
+	ggp_image_requested *req = data;
+	g_list_free_full(req->listeners, g_free);
+	g_free(req);
+}
+
 static inline ggp_image_connection_data *
 ggp_image_get_imgdata(PurpleConnection *gc)
 {
@@ -77,7 +81,9 @@ void ggp_image_setup(PurpleConnection *g
 {
 	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
 	
-	imgdata->pending_messages = NULL;
+	imgdata->incoming_images = g_hash_table_new_full(
+		g_int64_hash, g_int64_equal,
+		g_free, ggp_image_requested_free);
 	imgdata->pending_images = g_hash_table_new_full(NULL, NULL, NULL,
 		ggp_image_pending_image_free);
 }
@@ -86,8 +92,7 @@ void ggp_image_cleanup(PurpleConnection 
 {
 	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
 	
-	g_list_free_full(imgdata->pending_messages,
-		&ggp_image_pending_message_free);
+	g_hash_table_destroy(imgdata->incoming_images);
 	g_hash_table_destroy(imgdata->pending_images);
 }
 
@@ -101,24 +106,6 @@ const char * ggp_image_pending_placehold
 	return buff;
 }
 
-void ggp_image_got_im(PurpleConnection *gc, uin_t from, gchar *text,
-	time_t mtime)
-{
-	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
-	ggp_image_pending_message *pending_message =
-		g_new(ggp_image_pending_message, 1);
-	
-	purple_debug_info("gg", "ggp_image_got_im: received message with "
-		"images from %u: %s\n", from, text);
-	
-	pending_message->from = from;
-	pending_message->text = text;
-	pending_message->mtime = mtime;
-	
-	imgdata->pending_messages = g_list_append(imgdata->pending_messages,
-		pending_message);
-}
-
 ggp_image_prepare_result ggp_image_prepare(PurpleConnection *gc, const int id,
 	const char *conv_name, struct gg_msg_richtext_image *image_info)
 {
@@ -173,65 +160,41 @@ void ggp_image_recv(PurpleConnection *gc
 {
 	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
 	int stored_id;
-	const char *imgtag_search;
-	gchar *imgtag_replace;
-	GList *pending_messages_it;
+	ggp_image_requested *req;
+	GList *it;
+	uint64_t id;
 	
 	stored_id = purple_imgstore_add_with_id(
 		g_memdup(image_reply->image, image_reply->size),
 		image_reply->size,
 		image_reply->filename);
 	
+	id = ((uint64_t)image_reply->crc32 << 32) | image_reply->size;
+	
 	purple_debug_info("gg", "ggp_image_recv: got image "
-		"[id=%d, crc=%u, size=%u, filename=\"%s\"]\n",
+		"[stored_id=%d, crc=%u, size=%u, id=%016llx]\n",
 		stored_id,
 		image_reply->crc32,
 		image_reply->size,
-		image_reply->filename);
+		id);
 
-	imgtag_search = ggp_image_pending_placeholder(image_reply->crc32);
-	imgtag_replace = g_strdup_printf("<img src=\""
-		PURPLE_STORED_IMAGE_PROTOCOL "%u\">", stored_id);
+	req = g_hash_table_lookup(imgdata->incoming_images, &id);
+	if (!req)
+	{
+		purple_debug_warning("gg", "ggp_image_recv: "
+			"image %016llx wasn't requested\n", id);
+		return;
+	}
 
-	pending_messages_it = g_list_first(imgdata->pending_messages);
-	while (pending_messages_it)
+	it = g_list_first(req->listeners);
+	while (it)
 	{
-		ggp_image_pending_message *pending_message =
-			(ggp_image_pending_message*)pending_messages_it->data;
-		gchar *newText;
+		ggp_image_requested_listener *listener = it->data;
+		it = g_list_next(it);
 		
-		if (strstr(pending_message->text, imgtag_search) == NULL)
-		{
-			pending_messages_it = g_list_next(pending_messages_it);
-			continue;
-		}
-		
-		purple_debug_misc("gg", "ggp_image_recv: found message "
-			"containing image: %s\n", pending_message->text);
-		
-		newText = purple_strreplace(pending_message->text,
-			imgtag_search, imgtag_replace);
-		g_free(pending_message->text);
-		pending_message->text = newText;
-
-		if (strstr(pending_message->text,
-			"<img id=\"" GGP_PENDING_IMAGE_ID_PREFIX) == NULL)
-		{
-			purple_debug_info("gg", "ggp_image_recv: "
-				"message is ready to display\n");
-			serv_got_im(gc, ggp_uin_to_str(pending_message->from),
-				pending_message->text,
-				PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES,
-				pending_message->mtime);
-			
-			ggp_image_pending_message_free(pending_message);
-			imgdata->pending_messages = g_list_remove(
-				imgdata->pending_messages, pending_message);
-		}
-		
-		pending_messages_it = g_list_next(pending_messages_it);
+		listener->cb(gc, id, stored_id, listener->user_data);
 	}
-	g_free(imgtag_replace);
+	g_hash_table_remove(imgdata->incoming_images, &id);
 }
 
 void ggp_image_send(PurpleConnection *gc,
@@ -293,3 +256,41 @@ void ggp_image_send(PurpleConnection *gc
 	g_hash_table_remove(imgdata->pending_images,
 		GINT_TO_POINTER(image_request->crc32));
 }
+
+void ggp_image_request(PurpleConnection *gc, uin_t uin, uint64_t id,
+	ggp_image_request_cb cb, gpointer user_data)
+{
+	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
+	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
+	ggp_image_requested *req;
+	ggp_image_requested_listener *listener;
+	uint32_t crc = id >> 32;
+	uint32_t size = id;
+	
+	if (size > GGP_IMAGE_MAX_SIZE && crc <= GGP_IMAGE_MAX_SIZE)
+	{
+		uint32_t tmp;
+		purple_debug_warning("gg", "ggp_image_request: "
+			"crc and size are swapped!\n");
+		tmp = crc;
+		crc = size;
+		size = tmp;
+	}
+	
+	req = g_hash_table_lookup(imgdata->incoming_images, &id);
+	if (!req)
+	{
+		req = g_new0(ggp_image_requested, 1);
+		g_hash_table_insert(imgdata->incoming_images,
+			ggp_uint64dup(id), req);
+		purple_debug_info("gg", "ggp_image_request: "
+			"requesting image %016llx\n", id);
+		if (gg_image_request(accdata->session, uin, size, crc) != 0)
+			purple_debug_error("gg", "ggp_image_request: failed\n");
+	}
+	
+	listener = g_new0(ggp_image_requested_listener, 1);
+	listener->cb = cb;
+	listener->user_data = user_data;
+	req->listeners = g_list_append(req->listeners, listener);
+}
diff --git a/libpurple/protocols/gg/image.h b/libpurple/protocols/gg/image.h
--- a/libpurple/protocols/gg/image.h
+++ b/libpurple/protocols/gg/image.h
@@ -37,7 +37,7 @@
 
 typedef struct



More information about the Commits mailing list