Mercurial > pidgin
changeset 22512:b65997110933
The patch to msn to allow sending custom smileys. Doesn't send all the custom smileys correctly at the moment. References #1187.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Fri, 07 Mar 2008 23:19:47 +0000 |
parents | 0ae4d67bd6b1 |
children | 98167ea7c093 |
files | libpurple/protocols/msn/msn.c libpurple/protocols/msn/object.c libpurple/protocols/msn/object.h libpurple/protocols/msn/slp.c libpurple/protocols/msn/user.c |
diffstat | 5 files changed, 219 insertions(+), 64 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/msn/msn.c Fri Mar 07 23:14:23 2008 +0000 +++ b/libpurple/protocols/msn/msn.c Fri Mar 07 23:19:47 2008 +0000 @@ -32,6 +32,7 @@ #include "pluginpref.h" #include "prefs.h" #include "session.h" +#include "smiley.h" #include "state.h" #include "util.h" #include "cmds.h" @@ -82,6 +83,12 @@ time_t when; } MsnIMData; +typedef struct +{ + char *smile; + MsnObject *obj; +} MsnEmoticon; + static const char * msn_normalize(const PurpleAccount *account, const char *str) { @@ -115,6 +122,7 @@ return FALSE; msn_switchboard_send_msg(swboard, msg, TRUE); + msn_message_destroy(msg); return TRUE; } @@ -911,6 +919,97 @@ return FALSE; } +static GString* +msn_msg_emoticon_add(GString *current, MsnEmoticon *emoticon) +{ + MsnObject *obj; + char *strobj; + + if (emoticon == NULL) + return current; + + obj = emoticon->obj; + + if (!obj) + return current; + + strobj = msn_object_to_string(obj); + + if (current) + g_string_append_printf(current, "\t%s\t%s", + emoticon->smile, strobj); + else { + current = g_string_new(""); + g_string_printf(current,"%s\t%s", + emoticon->smile, strobj); + } + + g_free(strobj); + + return current; +} + +static void +msn_send_emoticons(MsnSwitchBoard *swboard, GString *body) +{ + MsnMessage *msg; + + g_return_if_fail(body != NULL); + + msg = msn_message_new(MSN_MSG_SLP); + msn_message_set_content_type(msg, "text/x-mms-emoticon"); + msn_message_set_flag(msg, 'N'); + msn_message_set_bin_data(msg, body->str, body->len); + + msn_switchboard_send_msg(swboard, msg, TRUE); + msn_message_destroy(msg); +} + +static void msn_emoticon_destroy(MsnEmoticon *emoticon) +{ + if (emoticon->obj) + msn_object_destroy(emoticon->obj); + g_free(emoticon->smile); + g_free(emoticon); +} + +static GSList* msn_msg_grab_emoticons(const char *msg, const char *username) +{ + GSList *list; + GList *smileys; + PurpleSmiley *smiley; + PurpleStoredImage *img; + char *ptr; + MsnEmoticon *emoticon; + int length; + + list = NULL; + smileys = purple_smileys_get_all(); + length = strlen(msg); + + for (; smileys; smileys = g_list_delete_link(smileys, smileys)) { + smiley = smileys->data; + + ptr = g_strstr_len(msg, length, purple_smiley_get_shortcut(smiley)); + + if (!ptr) + continue; + + img = purple_smiley_get_stored_image(smiley); + + emoticon = g_new0(MsnEmoticon, 1); + emoticon->smile = g_strdup(purple_smiley_get_shortcut(smiley)); + emoticon->obj = msn_object_new_from_image(img, + purple_imgstore_get_filename(img), + username, MSN_OBJECT_EMOTICON); + + purple_imgstore_unref(img); + list = g_slist_prepend(list, emoticon); + } + + return list; +} + static int msn_send_im(PurpleConnection *gc, const char *who, const char *message, PurpleMessageFlags flags) @@ -920,9 +1019,11 @@ MsnMessage *msg; char *msgformat; char *msgtext; + const char *username; purple_debug_info("MSNP14","send IM {%s} to %s\n",message,who); account = purple_connection_get_account(gc); + username = purple_account_get_username(account); if (buddy) { PurplePresence *p = purple_buddy_get_presence(buddy); @@ -955,10 +1056,13 @@ g_free(msgtext); purple_debug_info("MSNP14","prepare to send online Message\n"); - if (g_ascii_strcasecmp(who, purple_account_get_username(account))) + if (g_ascii_strcasecmp(who, username)) { MsnSession *session; MsnSwitchBoard *swboard; + MsnEmoticon *smile; + GSList *smileys; + GString *emoticons = NULL; session = gc->proto_data; if(msn_user_is_yahoo(account,who)){ @@ -968,6 +1072,19 @@ }else{ purple_debug_info("MSNP14","send via switchboard\n"); swboard = msn_session_get_swboard(session, who, MSN_SB_FLAG_IM); + smileys = msn_msg_grab_emoticons(message, username); + while (smileys) { + smile = (MsnEmoticon*)smileys->data; + emoticons = msn_msg_emoticon_add(emoticons, smile); + msn_emoticon_destroy(smile); + smileys = g_slist_delete_link(smileys, smileys); + } + + if (emoticons) { + msn_send_emoticons(swboard, emoticons); + g_string_free(emoticons, TRUE); + } + msn_switchboard_send_msg(swboard, msg, TRUE); } }
--- a/libpurple/protocols/msn/object.c Fri Mar 07 23:14:23 2008 +0000 +++ b/libpurple/protocols/msn/object.c Fri Mar 07 23:19:47 2008 +0000 @@ -23,6 +23,10 @@ */ #include "object.h" #include "debug.h" +/* Sha1 stuff */ +#include "cipher.h" +/* Base64 stuff */ +#include "util.h" #define GET_STRING_TAG(field, id) \ if ((tag = strstr(str, id "=\"")) != NULL) \ @@ -104,6 +108,74 @@ return obj; } +MsnObject* +msn_object_new_from_image(PurpleStoredImage *img, const char *location, + const char *creator, MsnObjectType type) +{ + MsnObject *msnobj; + + PurpleCipherContext *ctx; + char *buf; + gconstpointer data; + size_t size; + char *base64; + unsigned char digest[20]; + + msnobj = NULL; + + if (img == NULL) + return msnobj; + + size = purple_imgstore_get_size(img); + data = purple_imgstore_get_data(img); + + /* New object */ + msnobj = msn_object_new(); + msn_object_set_local(msnobj); + msn_object_set_type(msnobj, type); + msn_object_set_location(msnobj, location); + msn_object_set_creator(msnobj, creator); + + msn_object_set_image(msnobj, img); + + /* Compute the SHA1D field. */ + memset(digest, 0, sizeof(digest)); + + ctx = purple_cipher_context_new_by_name("sha1", NULL); + purple_cipher_context_append(ctx, data, size); + purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL); + + base64 = purple_base64_encode(digest, sizeof(digest)); + msn_object_set_sha1d(msnobj, base64); + g_free(base64); + + msn_object_set_size(msnobj, size); + + /* Compute the SHA1C field. */ + buf = g_strdup_printf( + "Creator%sSize%dType%dLocation%sFriendly%sSHA1D%s", + msn_object_get_creator(msnobj), + msn_object_get_size(msnobj), + msn_object_get_type(msnobj), + msn_object_get_location(msnobj), + msn_object_get_friendly(msnobj), + msn_object_get_sha1d(msnobj)); + + memset(digest, 0, sizeof(digest)); + + purple_cipher_context_reset(ctx, NULL); + purple_cipher_context_append(ctx, (const guchar *)buf, strlen(buf)); + purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL); + purple_cipher_context_destroy(ctx); + g_free(buf); + + base64 = purple_base64_encode(digest, sizeof(digest)); + msn_object_set_sha1c(msnobj, base64); + g_free(base64); + + return msnobj; +} + void msn_object_destroy(MsnObject *obj) {
--- a/libpurple/protocols/msn/object.h Fri Mar 07 23:14:23 2008 +0000 +++ b/libpurple/protocols/msn/object.h Fri Mar 07 23:19:47 2008 +0000 @@ -71,6 +71,19 @@ MsnObject *msn_object_new_from_string(const char *str); /** + * Creates a MsnObject structure from a stored image + * + * @param img The image associated to object + * @param location The object location as stored in MsnObject + * @param creator The creator of the object + * @param type The type of the object + * + * @return A new MsnObject structure + */ +MsnObject *msn_object_new_from_image(PurpleStoredImage *img, + const char *location, const char *creator, MsnObjectType type); + +/** * Destroys an MsnObject structure. * * @param obj The object structure.
--- a/libpurple/protocols/msn/slp.c Fri Mar 07 23:14:23 2008 +0000 +++ b/libpurple/protocols/msn/slp.c Fri Mar 07 23:19:47 2008 +0000 @@ -31,6 +31,8 @@ #include "user.h" #include "switchboard.h" +#include "smiley.h" + /* ms to delay between sending buddy icon requests to the server. */ #define BUDDY_ICON_DELAY 20000 /*debug SLP*/ @@ -261,6 +263,7 @@ char *msnobj_data; PurpleStoredImage *img; int type; + char *path; /* Send Ok */ content = g_strdup_printf("SessionID: %lu\r\n\r\n", @@ -278,23 +281,24 @@ type = msn_object_get_type(obj); g_free(msnobj_data); - if (!(type == MSN_OBJECT_USERTILE)) + if ((type != MSN_OBJECT_USERTILE) && (type != MSN_OBJECT_EMOTICON)) { purple_debug_error("msn", "Wrong object?\n"); msn_object_destroy(obj); g_return_if_reached(); } - img = msn_object_get_image(obj); + path = g_build_filename(purple_smileys_get_storing_dir(), + obj->location, NULL); + msn_object_destroy(obj); + img = purple_imgstore_new_from_file(path); + g_free(path); if (img == NULL) { purple_debug_error("msn", "Wrong object.\n"); - msn_object_destroy(obj); g_return_if_reached(); } - msn_object_destroy(obj); - slpsession = msn_slplink_find_slp_session(slplink, slpcall->session_id); @@ -319,6 +323,7 @@ #endif msn_slpmsg_set_image(slpmsg, img); msn_slplink_queue_slpmsg(slplink, slpmsg); + purple_imgstore_unref(img); } else if (!strcmp(euf_guid, "5D3E02AB-6190-11D3-BBBB-00C04F795683")) {
--- a/libpurple/protocols/msn/user.c Fri Mar 07 23:14:23 2008 +0000 +++ b/libpurple/protocols/msn/user.c Fri Mar 07 23:19:47 2008 +0000 @@ -238,69 +238,17 @@ void msn_user_set_buddy_icon(MsnUser *user, PurpleStoredImage *img) { - MsnObject *msnobj = msn_user_get_object(user); + MsnObject *msnobj; g_return_if_fail(user != NULL); - if (img == NULL) - msn_user_set_object(user, NULL); - else - { - PurpleCipherContext *ctx; - char *buf; - gconstpointer data = purple_imgstore_get_data(img); - size_t size = purple_imgstore_get_size(img); - char *base64; - unsigned char digest[20]; - - if (msnobj == NULL) - { - msnobj = msn_object_new(); - msn_object_set_local(msnobj); - msn_object_set_type(msnobj, MSN_OBJECT_USERTILE); - msn_object_set_location(msnobj, "TFR2C2.tmp"); - msn_object_set_creator(msnobj, msn_user_get_passport(user)); - - msn_user_set_object(user, msnobj); - } - - msn_object_set_image(msnobj, img); - - /* Compute the SHA1D field. */ - memset(digest, 0, sizeof(digest)); + msnobj = msn_object_new_from_image(img, "TFR2C2.tmp", + user->passport, MSN_OBJECT_USERTILE); - ctx = purple_cipher_context_new_by_name("sha1", NULL); - purple_cipher_context_append(ctx, data, size); - purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL); - - base64 = purple_base64_encode(digest, sizeof(digest)); - msn_object_set_sha1d(msnobj, base64); - g_free(base64); - - msn_object_set_size(msnobj, size); + if (!msnobj) + purple_debug_error("msn", "Unable to open buddy icon from %s!\n", user->passport); - /* Compute the SHA1C field. */ - buf = g_strdup_printf( - "Creator%sSize%dType%dLocation%sFriendly%sSHA1D%s", - msn_object_get_creator(msnobj), - msn_object_get_size(msnobj), - msn_object_get_type(msnobj), - msn_object_get_location(msnobj), - msn_object_get_friendly(msnobj), - msn_object_get_sha1d(msnobj)); - - memset(digest, 0, sizeof(digest)); - - purple_cipher_context_reset(ctx, NULL); - purple_cipher_context_append(ctx, (const guchar *)buf, strlen(buf)); - purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL); - purple_cipher_context_destroy(ctx); - g_free(buf); - - base64 = purple_base64_encode(digest, sizeof(digest)); - msn_object_set_sha1c(msnobj, base64); - g_free(base64); - } + msn_user_set_object(user, msnobj); } /*add group id to User object*/