📄 oscar.c
字号:
{ gchar *ret = NULL; const gchar *charsetstr1, *charsetstr2; purple_debug_info("oscar", "Parsing IM part, charset=0x%04hx, charsubset=0x%04hx, datalen=%hd\n", charset, charsubset, datalen); if ((datalen == 0) || (data == NULL)) return NULL; if (charset == AIM_CHARSET_UNICODE) { charsetstr1 = "UCS-2BE"; charsetstr2 = "UTF-8"; } else if (charset == AIM_CHARSET_CUSTOM) { if ((sourcesn != NULL) && isdigit(sourcesn[0])) charsetstr1 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); else charsetstr1 = "ISO-8859-1"; charsetstr2 = "UTF-8"; } else if (charset == AIM_CHARSET_ASCII) { /* Should just be "ASCII" */ charsetstr1 = "ASCII"; charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); } else if (charset == 0x000d) { /* Mobile AIM client on a Nokia 3100 and an LG VX6000 */ charsetstr1 = "ISO-8859-1"; charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); } else { /* Unknown, hope for valid UTF-8... */ charsetstr1 = "UTF-8"; charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); } ret = purple_plugin_oscar_convert_to_utf8(data, datalen, charsetstr1, FALSE); if (ret == NULL) ret = purple_plugin_oscar_convert_to_utf8(data, datalen, charsetstr2, TRUE); if (ret == NULL) { char *str, *salvage, *tmp; str = g_malloc(datalen + 1); strncpy(str, data, datalen); str[datalen] = '\0'; salvage = purple_utf8_salvage(str); tmp = g_strdup_printf(_("(There was an error receiving this message. Either you and %s have different encodings selected, or %s has a buggy client.)"), sourcesn, sourcesn); ret = g_strdup_printf("%s %s", salvage, tmp); g_free(tmp); g_free(str); g_free(salvage); } return ret;}/** * Figure out what encoding to use when sending a given outgoing message. */static voidpurple_plugin_oscar_convert_to_best_encoding(PurpleConnection *gc, const char *destsn, const gchar *from, gchar **msg, int *msglen_int, guint16 *charset, guint16 *charsubset){ OscarData *od = gc->proto_data; PurpleAccount *account = purple_connection_get_account(gc); GError *err = NULL; aim_userinfo_t *userinfo = NULL; const gchar *charsetstr; gsize msglen; /* Attempt to send as ASCII */ if (oscar_charset_check(from) == AIM_CHARSET_ASCII) { *msg = g_convert(from, strlen(from), "ASCII", "UTF-8", NULL, &msglen, NULL); *charset = AIM_CHARSET_ASCII; *charsubset = 0x0000; *msglen_int = msglen; return; } /* * If we're sending to an ICQ user, and they are in our * buddy list, and they are advertising the Unicode * capability, and they are online, then attempt to send * as UCS-2BE. */ if ((destsn != NULL) && aim_sn_is_icq(destsn)) userinfo = aim_locate_finduserinfo(od, destsn); if ((userinfo != NULL) && (userinfo->capabilities & OSCAR_CAPABILITY_UNICODE)) { PurpleBuddy *b; b = purple_find_buddy(account, destsn); if ((b != NULL) && (PURPLE_BUDDY_IS_ONLINE(b))) { *msg = g_convert(from, strlen(from), "UCS-2BE", "UTF-8", NULL, &msglen, NULL); if (*msg != NULL) { *charset = AIM_CHARSET_UNICODE; *charsubset = 0x0000; *msglen_int = msglen; return; } } } /* * If this is AIM then attempt to send as ISO-8859-1. If this is * ICQ then attempt to send as the user specified character encoding. */ charsetstr = "ISO-8859-1"; if ((destsn != NULL) && aim_sn_is_icq(destsn)) charsetstr = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); /* * XXX - We need a way to only attempt to convert if we KNOW "from" * can be converted to "charsetstr" */ *msg = g_convert(from, strlen(from), charsetstr, "UTF-8", NULL, &msglen, NULL); if (*msg != NULL) { *charset = AIM_CHARSET_CUSTOM; *charsubset = 0x0000; *msglen_int = msglen; return; } /* * Nothing else worked, so send as UCS-2BE. */ *msg = g_convert(from, strlen(from), "UCS-2BE", "UTF-8", NULL, &msglen, &err); if (*msg != NULL) { *charset = AIM_CHARSET_UNICODE; *charsubset = 0x0000; *msglen_int = msglen; return; } purple_debug_error("oscar", "Error converting a Unicode message: %s\n", err->message); g_error_free(err); purple_debug_error("oscar", "This should NEVER happen! Sending UTF-8 text flagged as ASCII.\n"); *msg = g_strdup(from); *msglen_int = strlen(*msg); *charset = AIM_CHARSET_ASCII; *charsubset = 0x0000; return;}/** * Looks for %n, %d, or %t in a string, and replaces them with the * specified name, date, and time, respectively. * * @param str The string that may contain the special variables. * @param name The sender name. * * @return A newly allocated string where the special variables are * expanded. This should be g_free'd by the caller. */static gchar *purple_str_sub_away_formatters(const char *str, const char *name){ char *c; GString *cpy; time_t t; struct tm *tme; g_return_val_if_fail(str != NULL, NULL); g_return_val_if_fail(name != NULL, NULL); /* Create an empty GString that is hopefully big enough for most messages */ cpy = g_string_sized_new(1024); t = time(NULL); tme = localtime(&t); c = (char *)str; while (*c) { switch (*c) { case '%': if (*(c + 1)) { switch (*(c + 1)) { case 'n': /* append name */ g_string_append(cpy, name); c++; break; case 'd': /* append date */ g_string_append(cpy, purple_date_format_short(tme)); c++; break; case 't': /* append time */ g_string_append(cpy, purple_time_format(tme)); c++; break; default: g_string_append_c(cpy, *c); } } else { g_string_append_c(cpy, *c); } break; default: g_string_append_c(cpy, *c); } c++; } return g_string_free(cpy, FALSE);}static gchar *oscar_caps_to_string(OscarCapability caps){ GString *str; const gchar *tmp; guint bit = 1; str = g_string_new(""); if (!caps) { return NULL; } else while (bit <= OSCAR_CAPABILITY_LAST) { if (bit & caps) { switch (bit) { case OSCAR_CAPABILITY_BUDDYICON: tmp = _("Buddy Icon"); break; case OSCAR_CAPABILITY_TALK: tmp = _("Voice"); break; case OSCAR_CAPABILITY_DIRECTIM: tmp = _("AIM Direct IM"); break; case OSCAR_CAPABILITY_CHAT: tmp = _("Chat"); break; case OSCAR_CAPABILITY_GETFILE: tmp = _("Get File"); break; case OSCAR_CAPABILITY_SENDFILE: tmp = _("Send File"); break; case OSCAR_CAPABILITY_GAMES: case OSCAR_CAPABILITY_GAMES2: tmp = _("Games"); break; case OSCAR_CAPABILITY_ADDINS: tmp = _("Add-Ins"); break; case OSCAR_CAPABILITY_SENDBUDDYLIST: tmp = _("Send Buddy List"); break; case OSCAR_CAPABILITY_ICQ_DIRECT: tmp = _("ICQ Direct Connect"); break; case OSCAR_CAPABILITY_APINFO: tmp = _("AP User"); break; case OSCAR_CAPABILITY_ICQRTF: tmp = _("ICQ RTF"); break; case OSCAR_CAPABILITY_EMPTY: tmp = _("Nihilist"); break; case OSCAR_CAPABILITY_ICQSERVERRELAY: tmp = _("ICQ Server Relay"); break; case OSCAR_CAPABILITY_UNICODEOLD: tmp = _("Old ICQ UTF8"); break; case OSCAR_CAPABILITY_TRILLIANCRYPT: tmp = _("Trillian Encryption"); break; case OSCAR_CAPABILITY_UNICODE: tmp = _("ICQ UTF8"); break; case OSCAR_CAPABILITY_HIPTOP: tmp = _("Hiptop"); break; case OSCAR_CAPABILITY_SECUREIM: tmp = _("Security Enabled"); break; case OSCAR_CAPABILITY_VIDEO: tmp = _("Video Chat"); break; /* Not actually sure about this one... WinAIM doesn't show anything */ case OSCAR_CAPABILITY_ICHATAV: tmp = _("iChat AV"); break; case OSCAR_CAPABILITY_LIVEVIDEO: tmp = _("Live Video"); break; case OSCAR_CAPABILITY_CAMERA: tmp = _("Camera"); break; default: tmp = NULL; break; } if (tmp) g_string_append_printf(str, "%s%s", (*(str->str) == '\0' ? "" : ", "), tmp); } bit <<= 1; } return g_string_free(str, FALSE);}static char *oscar_icqstatus(int state) { /* Make a cute little string that shows the status of the dude or dudet */ if (state & AIM_ICQ_STATE_CHAT) return g_strdup_printf(_("Free For Chat")); else if (state & AIM_ICQ_STATE_DND) return g_strdup_printf(_("Do Not Disturb")); else if (state & AIM_ICQ_STATE_OUT) return g_strdup_printf(_("Not Available")); else if (state & AIM_ICQ_STATE_BUSY) return g_strdup_printf(_("Occupied")); else if (state & AIM_ICQ_STATE_AWAY) return g_strdup_printf(_("Away")); else if (state & AIM_ICQ_STATE_WEBAWARE) return g_strdup_printf(_("Web Aware")); else if (state & AIM_ICQ_STATE_INVISIBLE) return g_strdup_printf(_("Invisible")); else return g_strdup_printf(_("Online"));}static voidoscar_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *name, const char *value){ if (value && value[0]) { purple_notify_user_info_add_pair(user_info, name, value); }}static voidoscar_user_info_convert_and_add_pair(PurpleAccount *account, PurpleNotifyUserInfo *user_info, const char *name, const char *value){ gchar *utf8; if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, value))) { purple_notify_user_info_add_pair(user_info, name, utf8); g_free(utf8); }}static voidoscar_string_convert_and_append(PurpleAccount *account, GString *str, const char *newline, const char *name, const char *value){ gchar *utf8; if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, value))) { g_string_append_printf(str, "%s<b>%s:</b> %s", newline, name, utf8); g_free(utf8); }}static voidoscar_user_info_convert_and_add(PurpleAccount *account, PurpleNotifyUserInfo *user_info, const char *name, const char *value){ gchar *utf8; if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, value))) { purple_notify_user_info_add_pair(user_info, name, value); g_free(utf8); }}static void oscar_string_append_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo){ OscarData *od; PurpleAccount *account; PurplePresence *presence = NULL; PurpleStatus *status = NULL; PurpleGroup *g = NULL; struct buddyinfo *bi = NULL; char *tmp; od = gc->proto_data; account = purple_connection_get_account(gc); if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL))) return; if (userinfo == NULL) userinfo = aim_locate_finduserinfo(od, b->name); if (b == NULL) b = purple_find_buddy(account, userinfo->sn); if (b != NULL) { g = purple_buddy_get_group(b); presence = purple_buddy_get_presence(b); status = purple_presence_get_active_status(presence); } if (userinfo != NULL) bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->sn)); if (b != NULL) { if (purple_presence_is_online(presence)) { if (aim_sn_is_icq(b->name)) { PurpleStatus *status = purple_presence_get_active_status(presence); oscar_user_info_add_pair(user_info, _("Status"), purple_status_get_name(status)); } } else { tmp = aim_ssi_itemlist_findparentname(od->ssi.local, b->name); if (aim_ssi_waitingforauth(od->ssi.local, tmp, b->name)) oscar_user_info_add_pair(user_info, _("Status"), _("Not Authorized")); else oscar_user_info_add_pair(user_info, _("Status"), _("Offline"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -