/soc/2012/tomkiewicz/gg: 734fc6da6179: Gadu-Gadu: initial multil...
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Tue Aug 7 14:25:08 EDT 2012
Changeset: 734fc6da6179954c70ef19ca029c3c40d09aa72e
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2012-08-07 20:23 +0200
Branch: soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/734fc6da6179
Description:
Gadu-Gadu: initial multilogon support
diffstat:
libpurple/protocols/gg/Makefile.am | 2 +
libpurple/protocols/gg/gg.c | 158 ++++++++++++++++++++++++++----------
libpurple/protocols/gg/gg.h | 6 +-
libpurple/protocols/gg/utils.c | 10 ++
libpurple/protocols/gg/utils.h | 2 +
5 files changed, 131 insertions(+), 47 deletions(-)
diffs (truncated from 408 to 300 lines):
diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -82,6 +82,8 @@ GGSOURCES = \
validator.h \
xml.c \
xml.h \
+ multilogon.c \
+ multilogon.h \
oauth/oauth.c \
oauth/oauth.h \
oauth/oauth-parameter.c \
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
@@ -49,10 +49,12 @@
#include "deprecated.h"
#include "purplew.h"
#include "libgadu-events.h"
+#include "multilogon.h"
/* Prototypes */
-static void ggp_set_status(PurpleAccount *account, PurpleStatus *status);
static int ggp_to_gg_status(PurpleStatus *status, char **msg);
+static void ggp_set_purplestatus(PurpleAccount *account, PurpleStatus *status);
+static gboolean ggp_set_status(PurpleAccount *account, int status, const gchar* msg);
typedef struct
{
@@ -295,7 +297,6 @@ static void ggp_action_change_status_bro
GGPInfo *info = purple_connection_get_protocol_data(gc);
int selected_field;
PurpleAccount *account = purple_connection_get_account(gc);
- PurpleStatus *status;
selected_field = purple_request_fields_get_choice(fields, "status_broadcasting");
@@ -304,9 +305,7 @@ static void ggp_action_change_status_bro
else
info->status_broadcasting = FALSE;
- status = purple_account_get_active_status(account);
-
- ggp_set_status(account, status);
+ ggp_set_purplestatus(account, purple_account_get_active_status(account));
}
static void ggp_action_change_status_broadcasting(PurplePluginAction *action)
@@ -454,6 +453,7 @@ static void ggp_generic_status_handler(P
char *status_msg = NULL;
ggp_buddy_data *buddy_data;
PurpleBuddy *buddy;
+ PurpleAccount *account = purple_connection_get_account(gc);
from = g_strdup_printf("%u", uin);
buddy = purple_find_buddy(purple_connection_get_account(gc), from);
@@ -508,13 +508,19 @@ static void ggp_generic_status_handler(P
}
buddy_data->blocked = (status == GG_STATUS_BLOCKED);
+ if (uin == ggp_str_to_uin(purple_account_get_username(account)))
+ {
+ purple_debug_info("gg", "own status changed to %s [%s]\n", st,
+ status_msg ? status_msg : "");
+ }
+
purple_debug_info("gg", "status of %u is %s [%s]\n", uin, st,
status_msg ? status_msg : "");
if (status_msg == NULL) {
- purple_prpl_got_user_status(purple_connection_get_account(gc),
+ purple_prpl_got_user_status(account,
from, st, NULL);
} else {
- purple_prpl_got_user_status(purple_connection_get_account(gc),
+ purple_prpl_got_user_status(account,
from, st, "message", status_msg, NULL);
g_free(status_msg);
}
@@ -784,7 +790,7 @@ static void ggp_pubdir_reply_handler(Pur
*
* Image receiving, some code borrowed from Kadu http://www.kadu.net
*/
-static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev)
+void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event_msg *ev, gboolean multilogon)
{
GGPInfo *info = purple_connection_get_protocol_data(gc);
PurpleConversation *conv;
@@ -792,38 +798,38 @@ static void ggp_recv_message_handler(Pur
gchar *msg;
gchar *tmp;
time_t mtime;
- uin_t sender = ev->event.msg.sender;
+ uin_t sender = ev->sender;
- if (ev->event.msg.message == NULL)
+ if (ev->message == NULL)
{
purple_debug_warning("gg", "ggp_recv_message_handler: NULL as message pointer\n");
return;
}
- from = g_strdup_printf("%lu", (unsigned long int)ev->event.msg.sender);
+ from = g_strdup_printf("%lu", (unsigned long int)ev->sender);
- tmp = g_strdup_printf("%s", ev->event.msg.message);
+ tmp = g_strdup_printf("%s", ev->message);
purple_str_strip_char(tmp, '\r');
msg = g_markup_escape_text(tmp, -1);
g_free(tmp);
- if (ev->event.msg.msgclass & GG_CLASS_QUEUED)
- mtime = ev->event.msg.time;
+ if (ev->msgclass & GG_CLASS_QUEUED)
+ mtime = ev->time;
else
mtime = time(NULL);
/* We got richtext message */
- if (ev->event.msg.formats_length)
+ if (ev->formats_length)
{
gboolean got_image = FALSE, bold = FALSE, italic = FALSE, under = FALSE;
- char *cformats = (char *)ev->event.msg.formats;
- char *cformats_end = cformats + ev->event.msg.formats_length;
+ char *cformats = (char *)ev->formats;
+ char *cformats_end = cformats + ev->formats_length;
gint increased_len = 0;
struct gg_msg_richtext_format *actformat;
struct gg_msg_richtext_image *actimage;
GString *message = g_string_new(msg);
- purple_debug_info("gg", "ggp_recv_message_handler: richtext msg from (%s): %s %i formats\n", from, msg, ev->event.msg.formats_length);
+ purple_debug_info("gg", "ggp_recv_message_handler: richtext msg from (%s): %s %i formats\n", from, msg, ev->formats_length);
while (cformats < cformats_end)
{
@@ -860,7 +866,7 @@ static void ggp_recv_message_handler(Pur
continue;
}
- gg_image_request(info->session, ev->event.msg.sender,
+ gg_image_request(info->session, ev->sender,
actimage->size, actimage->crc32);
placeholder = ggp_image_pending_placeholder(actimage->crc32);
@@ -920,36 +926,48 @@ static void ggp_recv_message_handler(Pur
}
}
- purple_debug_info("gg", "ggp_recv_message_handler: msg from (%s): %s (class = %d; rcpt_count = %d)\n",
- from, msg, ev->event.msg.msgclass,
- ev->event.msg.recipients_count);
+ purple_debug_info("gg", "ggp_recv_message_handler: msg from (%s): %s (class = %d; rcpt_count = %d; multilogon = %d)\n",
+ from, msg, ev->msgclass,
+ ev->recipients_count,
+ multilogon);
- if (ev->event.msg.recipients_count == 0) {
+ if (multilogon && ev->recipients_count != 0) {
+ purple_debug_warning("gg", "ggp_recv_message_handler: conference multilogon messages are not yet handled\n");
+ } else if (multilogon) {
+ PurpleAccount *account = purple_connection_get_account(gc);
+ PurpleConversation *conv;
+ const gchar *who = ggp_uin_to_str(ev->sender); // not really sender
+ conv = purple_find_conversation_with_account(
+ PURPLE_CONV_TYPE_IM, who, account);
+ if (conv == NULL)
+ conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, who);
+ purple_conversation_write(conv, purple_account_get_username(account), msg, PURPLE_MESSAGE_SEND, mtime);
+ } else if (ev->recipients_count == 0) {
serv_got_im(gc, from, msg, 0, mtime);
} else {
const char *chat_name;
int chat_id;
chat_name = ggp_confer_find_by_participants(gc,
- ev->event.msg.recipients,
- ev->event.msg.recipients_count);
+ ev->recipients,
+ ev->recipients_count);
if (chat_name == NULL) {
chat_name = ggp_confer_add_new(gc, NULL);
serv_got_joined_chat(gc, info->chats_count, chat_name);
ggp_confer_participants_add_uin(gc, chat_name,
- ev->event.msg.sender);
+ ev->sender);
ggp_confer_participants_add(gc, chat_name,
- ev->event.msg.recipients,
- ev->event.msg.recipients_count);
+ ev->recipients,
+ ev->recipients_count);
}
conv = ggp_confer_find_by_name(gc, chat_name);
chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
serv_got_chat_in(gc, chat_id,
- ggp_buddylist_get_buddy_name(gc, ev->event.msg.sender),
+ ggp_buddylist_get_buddy_name(gc, ev->sender),
PURPLE_MESSAGE_RECV, msg, mtime);
}
g_free(msg);
@@ -1057,7 +1075,7 @@ static void ggp_callback_recv(gpointer _
/* Nothing happened. */
break;
case GG_EVENT_MSG:
- ggp_recv_message_handler(gc, ev);
+ ggp_recv_message_handler(gc, &ev->event.msg, FALSE);
break;
case GG_EVENT_ACK:
/* Changing %u to %i fixes compiler warning */
@@ -1150,6 +1168,12 @@ static void ggp_callback_recv(gpointer _
case GG_EVENT_USERLIST100_REPLY:
ggp_roster_reply(gc, &ev->event.userlist100_reply);
break;
+ case GG_EVENT_MULTILOGON_MSG:
+ ggp_multilogon_msg(gc, &ev->event.multilogon_msg);
+ break;
+ case GG_EVENT_MULTILOGON_INFO:
+ ggp_multilogon_info(gc, &ev->event.multilogon_info);
+ break;
default:
purple_debug_error("gg",
"unsupported event type=%d\n", ev->type);
@@ -1520,6 +1544,7 @@ static void ggp_login(PurpleAccount *acc
ggp_image_setup(gc);
ggp_avatar_setup(gc);
ggp_roster_setup(gc);
+ ggp_multilogon_setup(gc);
glp->uin = ggp_str_to_uin(purple_account_get_username(account));
glp->password = ggp_convert_to_cp1250(purple_account_get_password(account));
@@ -1548,6 +1573,7 @@ static void ggp_login(PurpleAccount *acc
glp->async = 1;
glp->status = ggp_to_gg_status(status, &glp->status_descr);
+ info->old_status = g_strdup(glp->status_descr);
encryption_type = purple_account_get_string(account, "encryption",
"opportunistic_tls");
@@ -1619,8 +1645,28 @@ static void ggp_close(PurpleConnection *
if (info) {
PurpleStatus *status = purple_account_get_active_status(account);
- if (info->session != NULL) {
- ggp_set_status(account, status);
+ if (info->session != NULL)
+ {
+ const gchar *status_msg = purple_status_get_attr_string(status, "message");
+
+ if (ggp_set_status(account,
+ status_msg ? GG_STATUS_NOT_AVAIL_DESCR : GG_STATUS_NOT_AVAIL,
+ status_msg))
+ {
+ struct gg_event *ev;
+ guint64 wait_start = ggp_microtime(), now;
+ int sleep_time = 5000;
+ while ((ev = gg_watch_fd(info->session)) != NULL)
+ {
+ if (ev->type == GG_EVENT_DISCONNECT_ACK)
+ break;
+ now = ggp_microtime();
+ if (now - wait_start + sleep_time >= 100000)
+ break;
+ usleep(sleep_time);
+ sleep_time *= 2;
+ }
+ }
gg_logoff(info->session);
gg_free_session(info->session);
}
@@ -1636,7 +1682,9 @@ static void ggp_close(PurpleConnection *
ggp_image_cleanup(gc);
ggp_avatar_cleanup(gc);
ggp_roster_cleanup(gc);
+ ggp_multilogon_cleanup(gc);
+ g_free(info->old_status);
if (info->inpa > 0)
purple_input_remove(info->inpa);
@@ -1858,30 +1906,48 @@ static int ggp_to_gg_status(PurpleStatus
}
}
-static void ggp_set_status(PurpleAccount *account, PurpleStatus *status)
+static void ggp_set_purplestatus(PurpleAccount *account, PurpleStatus *status)
+{
+ int new_status;
+ gchar *new_msg = NULL;
+
+ if (!purple_status_is_active(status))
+ return;
+
+ new_status = ggp_to_gg_status(status, &new_msg);
+
+ ggp_set_status(account, new_status, new_msg);
+ g_free(new_msg);
More information about the Commits
mailing list