diff options
Diffstat (limited to 'libpurple/protocols/oscar/oscar.c')
-rw-r--r-- | libpurple/protocols/oscar/oscar.c | 272 |
1 files changed, 256 insertions, 16 deletions
diff --git a/libpurple/protocols/oscar/oscar.c b/libpurple/protocols/oscar/oscar.c index c4c59e4d39..9eb30bd942 100644 --- a/libpurple/protocols/oscar/oscar.c +++ b/libpurple/protocols/oscar/oscar.c @@ -61,6 +61,11 @@ #define OSCAR_STATUS_ID_FREE4CHAT "free4chat" #define OSCAR_STATUS_ID_CUSTOM "custom" #define OSCAR_STATUS_ID_MOBILE "mobile" +#define OSCAR_STATUS_ID_EVIL "evil" +#define OSCAR_STATUS_ID_DEPRESSION "depression" +#define OSCAR_STATUS_ID_ATHOME "athome" +#define OSCAR_STATUS_ID_ATWORK "atwork" +#define OSCAR_STATUS_ID_LUNCH "lunch" #define AIMHASHDATA "http://pidgin.im/aim_data.php3" @@ -68,7 +73,7 @@ static OscarCapability purple_caps = (OSCAR_CAPABILITY_CHAT | OSCAR_CAPABILITY_BUDDYICON | OSCAR_CAPABILITY_DIRECTIM | OSCAR_CAPABILITY_SENDFILE | OSCAR_CAPABILITY_UNICODE | OSCAR_CAPABILITY_INTEROPERATE | - OSCAR_CAPABILITY_SHORTCAPS | OSCAR_CAPABILITY_TYPING); + OSCAR_CAPABILITY_SHORTCAPS | OSCAR_CAPABILITY_TYPING | OSCAR_CAPABILITY_ICQSERVERRELAY | OSCAR_CAPABILITY_NEWCAPS | OSCAR_CAPABILITY_XTRAZ); static guint8 features_aim[] = {0x01, 0x01, 0x01, 0x02}; static guint8 features_icq[] = {0x01, 0x06}; @@ -180,6 +185,7 @@ static int purple_parse_incoming_im(OscarData *, FlapConnection *, FlapFrame *, static int purple_parse_misses (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_clientauto (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_userinfo (OscarData *, FlapConnection *, FlapFrame *, ...); +static int purple_got_infoblock (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_motd (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_chatnav_info (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_conv_chat_join (OscarData *, FlapConnection *, FlapFrame *, ...); @@ -190,6 +196,7 @@ static int purple_email_parseupdate(OscarData *, FlapConnection *, FlapFrame *, static int purple_icon_parseicon (OscarData *, FlapConnection *, FlapFrame *, ...); static int oscar_icon_req (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_msgack (OscarData *, FlapConnection *, FlapFrame *, ...); +static int purple_parse_ratechange (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_evilnotify (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_searcherror(OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_searchreply(OscarData *, FlapConnection *, FlapFrame *, ...); @@ -672,7 +679,7 @@ static gchar *oscar_caps_to_string(OscarCapability caps) { GString *str; const gchar *tmp; - guint bit = 1; + guint64 bit = 1; str = g_string_new(""); @@ -703,6 +710,10 @@ static gchar *oscar_caps_to_string(OscarCapability caps) case OSCAR_CAPABILITY_GAMES2: tmp = _("Games"); break; + case OSCAR_CAPABILITY_XTRAZ: + case OSCAR_CAPABILITY_NEWCAPS: + tmp = _("ICQ Xtraz"); + break; case OSCAR_CAPABILITY_ADDINS: tmp = _("Add-Ins"); break; @@ -784,6 +795,16 @@ static char *oscar_icqstatus(int state) { return g_strdup(_("Web Aware")); else if (state & AIM_ICQ_STATE_INVISIBLE) return g_strdup(_("Invisible")); + else if (state & AIM_ICQ_STATE_EVIL) + return g_strdup(_("Evil")); + else if (state & AIM_ICQ_STATE_DEPRESSION) + return g_strdup(_("Depression")); + else if (state & AIM_ICQ_STATE_ATHOME) + return g_strdup(_("At home")); + else if (state & AIM_ICQ_STATE_ATWORK) + return g_strdup(_("At work")); + else if (state & AIM_ICQ_STATE_LUNCH) + return g_strdup(_("At lunch")); else return g_strdup(_("Online")); } @@ -961,6 +982,16 @@ static void oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUser } } + if (presence) { + const char *mood; + const char *description; + status = purple_presence_get_status(presence, "mood"); + mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME); + description = icq_get_custom_icon_description(mood); + if (description && *description) + purple_notify_user_info_add_pair(user_info, _("Mood"), _(description)); + } + purple_notify_user_info_add_pair(user_info, _("Status"), message); g_free(message); } @@ -2240,6 +2271,16 @@ static int purple_parse_oncoming(OscarData *od, FlapConnection *conn, FlapFrame status_id = OSCAR_STATUS_ID_AWAY; else if (type & AIM_ICQ_STATE_INVISIBLE) status_id = OSCAR_STATUS_ID_INVISIBLE; + else if (type & AIM_ICQ_STATE_EVIL) + status_id = OSCAR_STATUS_ID_EVIL; + else if (type & AIM_ICQ_STATE_DEPRESSION) + status_id = OSCAR_STATUS_ID_DEPRESSION; + else if (type & AIM_ICQ_STATE_ATHOME) + status_id = OSCAR_STATUS_ID_ATHOME; + else if (type & AIM_ICQ_STATE_ATWORK) + status_id = OSCAR_STATUS_ID_ATWORK; + else if (type & AIM_ICQ_STATE_LUNCH) + status_id = OSCAR_STATUS_ID_LUNCH; else status_id = OSCAR_STATUS_ID_AVAILABLE; } else { @@ -2552,7 +2593,9 @@ incomingim_chan2(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo, { PurpleConnection *gc; PurpleAccount *account; + PurpleMessageFlags flags = 0; char *message = NULL; + char *rtfmsg = NULL; g_return_val_if_fail(od != NULL, 0); g_return_val_if_fail(od->gc != NULL, 0); @@ -2582,6 +2625,20 @@ incomingim_chan2(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo, } } + if (args->info.rtfmsg.rtfmsg != NULL) + { + if (args->encoding != NULL) + { + char *encoding = NULL; + encoding = oscar_encoding_extract(args->encoding); + rtfmsg = oscar_encoding_to_utf8(account, encoding, args->info.rtfmsg.rtfmsg, + strlen(args->info.rtfmsg.rtfmsg)); + g_free(encoding); + } else { + if (g_utf8_validate(args->info.rtfmsg.rtfmsg, strlen(args->info.rtfmsg.rtfmsg), NULL)) + rtfmsg = g_strdup(args->info.rtfmsg.rtfmsg); + } + } if (args->type & OSCAR_CAPABILITY_CHAT) { char *encoding, *utf8name, *tmp; @@ -2667,10 +2724,28 @@ incomingim_chan2(OscarData *od, FlapConnection *conn, aim_userinfo_t *userinfo, else if (args->type & OSCAR_CAPABILITY_ICQSERVERRELAY) { - purple_debug_error("oscar", "Got an ICQ Server Relay message of " + purple_debug_info("oscar", "Got an ICQ Server Relay message of " "type %d\n", args->info.rtfmsg.msgtype); - } + purple_debug_info("oscar", "Sending X-Status Reply\n"); + if(args->info.rtfmsg.msgtype == 26) + icq_relay_xstatus(od, userinfo->bn, args->cookie); + + if(args->info.rtfmsg.msgtype == 1) + { + if(rtfmsg) + { + serv_got_im(gc, userinfo->bn, rtfmsg, flags, + time(NULL)); + } + else + { + serv_got_im(gc, userinfo->bn, + args->info.rtfmsg.rtfmsg, flags, + time(NULL)); + } + } + } else { purple_debug_error("oscar", "Unknown request class %hu\n", @@ -3250,6 +3325,29 @@ static int purple_parse_clientauto_ch4(OscarData *od, char *who, guint16 reason, } break; + case 0x0006: { /* Reply from an ICQ status message request */ + char *statusmsg, **splitmsg; + PurpleNotifyUserInfo *user_info; + + /* Split at (carriage return/newline)'s, then rejoin later with BRs between. */ + statusmsg = oscar_icqstatus(state); + splitmsg = g_strsplit(msg, "\r\n", 0); + + user_info = purple_notify_user_info_new(); + + purple_notify_user_info_add_pair(user_info, _("UIN"), who); + purple_notify_user_info_add_pair(user_info, _("Status"), statusmsg); + purple_notify_user_info_add_section_break(user_info); + purple_notify_user_info_add_pair(user_info, NULL, g_strjoinv("<BR>", splitmsg)); + + g_free(statusmsg); + g_strfreev(splitmsg); + + purple_notify_userinfo(gc, who, user_info, NULL, NULL); + purple_notify_user_info_destroy(user_info); + + } break; + default: { purple_debug_warning("oscar", "Received an unknown client auto-response from %s. " @@ -3497,6 +3595,55 @@ static int purple_parse_userinfo(OscarData *od, FlapConnection *conn, FlapFrame return 1; } +static int purple_got_infoblock(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) +{ + PurpleConnection *gc = od->gc; + PurpleAccount *account = purple_connection_get_account(gc); + PurpleBuddy *b; + PurplePresence *presence; + PurpleStatus *status; + gchar *message = NULL; + + va_list ap; + aim_userinfo_t *userinfo; + + va_start(ap, fr); + userinfo = va_arg(ap, aim_userinfo_t *); + va_end(ap); + + b = purple_find_buddy(account, userinfo->bn); + if (b == NULL) + return 1; + + if (!oscar_util_valid_name_icq(userinfo->bn)) + { + if (strcmp(purple_buddy_get_name(b), userinfo->bn) != 0) + serv_got_alias(gc, purple_buddy_get_name(b), userinfo->bn); + else + serv_got_alias(gc, purple_buddy_get_name(b), NULL); + } + + presence = purple_buddy_get_presence(b); + status = purple_presence_get_active_status(presence); + + if (purple_status_is_online(status) && !purple_status_is_available(status) && + userinfo->flags & AIM_FLAG_AWAY && userinfo->away_len > 0 && + userinfo->away != NULL && userinfo->away_encoding != NULL) + { + gchar *charset = oscar_encoding_extract(userinfo->away_encoding); + message = oscar_encoding_to_utf8(account, charset, + userinfo->away, + userinfo->away_len); + g_free(charset); + purple_prpl_got_user_status(account, userinfo->bn, + purple_status_get_id(status), + "message", message, NULL); + g_free(message); + } + + return 1; +} + static int purple_parse_motd(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { char *msg; @@ -4848,6 +4995,16 @@ oscar_set_extendedstatus(PurpleConnection *gc) data |= AIM_ICQ_STATE_CHAT; else if (!strcmp(status_id, OSCAR_STATUS_ID_INVISIBLE)) data |= AIM_ICQ_STATE_INVISIBLE; + else if (!strcmp(status_id, OSCAR_STATUS_ID_EVIL)) + data |= AIM_ICQ_STATE_EVIL; + else if (!strcmp(status_id, OSCAR_STATUS_ID_DEPRESSION)) + data |= AIM_ICQ_STATE_DEPRESSION; + else if (!strcmp(status_id, OSCAR_STATUS_ID_ATWORK)) + data |= AIM_ICQ_STATE_ATWORK; + else if (!strcmp(status_id, OSCAR_STATUS_ID_ATHOME)) + data |= AIM_ICQ_STATE_ATHOME; + else if (!strcmp(status_id, OSCAR_STATUS_ID_LUNCH)) + data |= AIM_ICQ_STATE_LUNCH; else if (!strcmp(status_id, OSCAR_STATUS_ID_CUSTOM)) data |= AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY; @@ -5009,6 +5166,12 @@ oscar_set_status(PurpleAccount *account, PurpleStatus *status) pc = purple_account_get_connection(account); od = purple_connection_get_protocol_data(pc); + /* There's no need to do the stuff below for mood updates. */ + if (purple_status_type_get_primitive(purple_status_get_type(status)) == PURPLE_STATUS_MOOD) { + aim_locate_setcaps(od, purple_caps); + return; + } + /* Set the AIM-style away message for both AIM and ICQ accounts */ oscar_set_info_and_status(account, FALSE, NULL, TRUE, status); @@ -5961,6 +6124,11 @@ int oscar_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMes return 0; } +PurpleMood* oscar_get_purple_moods(PurpleAccount *account) +{ + return icq_get_purple_moods(account); +} + const char *oscar_list_icon_icq(PurpleAccount *a, PurpleBuddy *b) { const char *name = b ? purple_buddy_get_name(b) : NULL; @@ -6031,12 +6199,17 @@ const char *oscar_list_emblem(PurpleBuddy *b) return "admin"; if (userinfo->flags & AIM_FLAG_ACTIVEBUDDY) return "bot"; - if (userinfo->capabilities & OSCAR_CAPABILITY_HIPTOP) - return "hiptop"; if (userinfo->capabilities & OSCAR_CAPABILITY_SECUREIM) return "secure"; if (userinfo->icqinfo.status & AIM_ICQ_STATE_BIRTHDAY) return "birthday"; + + /* Make the mood icon override anything below this. */ + if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOOD)) + return NULL; + + if (userinfo->capabilities & OSCAR_CAPABILITY_HIPTOP) + return "hiptop"; } return NULL; } @@ -6259,9 +6432,53 @@ oscar_status_types(PurpleAccount *account) purple_value_new(PURPLE_TYPE_STRING), NULL); status_types = g_list_prepend(status_types, type); - type = purple_status_type_new_full(PURPLE_STATUS_AVAILABLE, + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, OSCAR_STATUS_ID_FREE4CHAT, - _("Free For Chat"), TRUE, is_icq, FALSE); + _("Free For Chat"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + + status_types = g_list_prepend(status_types, type); + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_EVIL, + _("Evil"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_DEPRESSION, + _("Depression"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_ATHOME, + _("At home"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_ATWORK, + _("At work"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + + status_types = g_list_prepend(status_types, type); + + + type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, + OSCAR_STATUS_ID_LUNCH, + _("Lunch"), TRUE, is_icq, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, @@ -6271,9 +6488,12 @@ oscar_status_types(PurpleAccount *account) purple_value_new(PURPLE_TYPE_STRING), NULL); status_types = g_list_prepend(status_types, type); - type = purple_status_type_new_full(PURPLE_STATUS_INVISIBLE, + type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE, OSCAR_STATUS_ID_INVISIBLE, - NULL, TRUE, TRUE, FALSE); + NULL, TRUE, TRUE, FALSE, + "message", _("Message"), + purple_value_new(PURPLE_TYPE_STRING), NULL); + status_types = g_list_prepend(status_types, type); type = purple_status_type_new_full(PURPLE_STATUS_MOBILE, OSCAR_STATUS_ID_MOBILE, NULL, FALSE, FALSE, TRUE); @@ -6306,9 +6526,14 @@ oscar_status_types(PurpleAccount *account) NULL, TRUE, TRUE, FALSE); status_types = g_list_prepend(status_types, type); - status_types = g_list_reverse(status_types); + type = purple_status_type_new_with_attrs(PURPLE_STATUS_MOOD, + "mood", NULL, TRUE, is_icq, TRUE, + PURPLE_MOOD_NAME, _("Mood Name"), purple_value_new(PURPLE_TYPE_STRING), + PURPLE_MOOD_COMMENT, _("Mood Comment"), purple_value_new(PURPLE_TYPE_STRING), + NULL); + status_types = g_list_prepend(status_types, type); - return status_types; + return g_list_reverse(status_types); } static void oscar_ssi_editcomment(struct name_data *data, const char *text) { @@ -6480,6 +6705,23 @@ oscar_close_directim(gpointer object, gpointer ignored) } } +static void oscar_get_icqxstatusmsg (PurpleBlistNode *node, gpointer ignore) +{ + PurpleBuddy *buddy; + PurpleConnection *gc; + PurpleAccount *account; + + + g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(node)); + + buddy = (PurpleBuddy *)node; + gc = purple_account_get_connection(buddy->account); + account = purple_connection_get_account(gc); + purple_debug_info("oscar", "Manual X-Status Get From %s to %s:\n", purple_buddy_get_name(buddy), account->username); + + icq_im_xstatus_request(gc->proto_data, purple_buddy_get_name(buddy)); +} + static void oscar_get_aim_info_cb(PurpleBlistNode *node, gpointer ignore) { @@ -6529,15 +6771,13 @@ oscar_buddy_menu(PurpleBuddy *buddy) { menu = g_list_prepend(menu, act); } -#if 0 if (od->icq) { - act = purple_menu_action_new(_("Get Status Msg"), - PURPLE_CALLBACK(oscar_get_icqstatusmsg), + act = purple_menu_action_new(_("Get X-Status Msg"), + PURPLE_CALLBACK(oscar_get_icqxstatusmsg), NULL, NULL); menu = g_list_prepend(menu, act); } -#endif if (userinfo && oscar_util_name_compare(purple_account_get_username(account), bname) && |