📄 oscar.c
字号:
else gaim_debug_warning("oscar", "String is not valid UTF-8.\n"); } return ret;}/* * We try decoding using two different character sets. The charset * specified in the IM determines the order in which we attempt to * decode. We do this because there are lots of broken ICQ clients * that don't correctly send non-ASCII messages. And if Gaim isn't * able to deal with that crap, then people complain like banshees. * charsetstr1 is always set to what the correct encoding should be. */static gchar *gaim_plugin_oscar_decode_im_part(GaimAccount *account, const char *sourcesn, fu16_t charset, fu16_t charsubset, fu8_t *data, fu16_t datalen){ gchar *ret = NULL; const gchar *charsetstr1, *charsetstr2; gaim_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 = gaim_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 = gaim_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 = gaim_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); } else { /* Unknown, hope for valid UTF-8... */ charsetstr1 = "UTF-8"; charsetstr2 = gaim_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); } ret = gaim_plugin_oscar_convert_to_utf8(data, datalen, charsetstr1, FALSE); if (ret == NULL) ret = gaim_plugin_oscar_convert_to_utf8(data, datalen, charsetstr2, TRUE); if (ret == NULL) ret = g_strdup(_("(There was an error receiving this message. The buddy you are speaking to most likely has a buggy client.)")); return ret;}static voidgaim_plugin_oscar_convert_to_best_encoding(GaimConnection *gc, const char *destsn, const gchar *from, gchar **msg, gsize *msglen, fu16_t *charset, fu16_t *charsubset){ OscarData *od = gc->proto_data; GaimAccount *account = gaim_connection_get_account(gc); GError *err = NULL; aim_userinfo_t *userinfo = NULL; const gchar *charsetstr; /* 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; return; } /* * If we're sending to an ICQ user, and they are advertising the * Unicode capability, then attempt to send as UCS-2BE. */ if ((destsn != NULL) && isdigit(destsn[0])) userinfo = aim_locate_finduserinfo(od->sess, destsn); if ((userinfo != NULL) && (userinfo->capabilities & AIM_CAPS_ICQUTF8)) { *msg = g_convert(from, strlen(from), "UCS-2BE", "UTF-8", NULL, msglen, NULL); if (*msg != NULL) { *charset = AIM_CHARSET_UNICODE; *charsubset = 0x0000; 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) && isdigit(destsn[0])) charsetstr = gaim_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); *msg = g_convert(from, strlen(from), charsetstr, "UTF-8", NULL, msglen, NULL); if (*msg != NULL) { *charset = AIM_CHARSET_CUSTOM; *charsubset = 0x0000; 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; return; } gaim_debug_error("oscar", "Error converting a Unicode message: %s\n", err->message); g_error_free(err); gaim_debug_error("oscar", "This should NEVER happen! Sending UTF-8 text flagged as ASCII.\n"); *msg = g_strdup(from); *msglen = strlen(*msg); *charset = AIM_CHARSET_ASCII; *charsubset = 0x0000; return;}gchar *oscar_caps_to_string(guint caps){ GString *str; gchar *tmp; guint bit = 1; str = g_string_new(""); if (!caps) { return NULL; } else while (bit <= AIM_CAPS_LAST) { if (bit & caps) { switch (bit) { case AIM_CAPS_BUDDYICON: tmp = _("Buddy Icon"); break; case AIM_CAPS_TALK: tmp = _("Voice"); break; case AIM_CAPS_DIRECTIM: tmp = _("AIM Direct IM"); break; case AIM_CAPS_CHAT: tmp = _("Chat"); break; case AIM_CAPS_GETFILE: tmp = _("Get File"); break; case AIM_CAPS_SENDFILE: tmp = _("Send File"); break; case AIM_CAPS_GAMES: case AIM_CAPS_GAMES2: tmp = _("Games"); break; case AIM_CAPS_ADDINS: tmp = _("Add-Ins"); break; case AIM_CAPS_SENDBUDDYLIST: tmp = _("Send Buddy List"); break; case AIM_CAPS_ICQ_DIRECT: tmp = _("ICQ Direct Connect"); break; case AIM_CAPS_APINFO: tmp = _("AP User"); break; case AIM_CAPS_ICQRTF: tmp = _("ICQ RTF"); break; case AIM_CAPS_EMPTY: tmp = _("Nihilist"); break; case AIM_CAPS_ICQSERVERRELAY: tmp = _("ICQ Server Relay"); break; case AIM_CAPS_ICQUTF8OLD: tmp = _("Old ICQ UTF8"); break; case AIM_CAPS_TRILLIANCRYPT: tmp = _("Trillian Encryption"); break; case AIM_CAPS_ICQUTF8: tmp = _("ICQ UTF8"); break; case AIM_CAPS_HIPTOP: tmp = _("Hiptop"); break; case AIM_CAPS_SECUREIM: tmp = _("Security Enabled"); break; case AIM_CAPS_VIDEO: tmp = _("Video Chat"); break; /* Not actually sure about this one... WinAIM doesn't show anything */ case AIM_CAPS_ICHATAV: tmp = _("iChat AV"); break; case AIM_CAPS_LIVEVIDEO: tmp = _("Live Video"); break; case AIM_CAPS_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 void oscar_string_append(GString *str, char *newline, char *name, char *value){ gchar *utf8; if (value && value[0] && (utf8 = gaim_utf8_try_convert(value))) { g_string_append_printf(str, "%s<b>%s:</b> %s", newline, name, utf8); g_free(utf8); }}static void oscar_string_append_info(GaimConnection *gc, GString *str, char *newline, GaimBuddy *b, aim_userinfo_t *userinfo){ OscarData *od = gc->proto_data; GaimAccount *account = gaim_connection_get_account(gc); GaimGroup *g = NULL; struct buddyinfo *bi = NULL; char *tmp; if ((str == NULL) || (str == NULL) || (newline == NULL) || ((b == NULL) && (userinfo == NULL))) return; if (userinfo == NULL) userinfo = aim_locate_finduserinfo(od->sess, b->name); if (b == NULL) b = gaim_find_buddy(gc->account, userinfo->sn); if (b != NULL) g = gaim_find_buddys_group(b); if (userinfo != NULL) bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(account, userinfo->sn)); if (b != NULL) { if (GAIM_BUDDY_IS_ONLINE(b)) { if (isdigit(b->name[0])) { tmp = oscar_icqstatus((b->uc & 0xffff0000) >> 16); oscar_string_append(str, newline, _("Status"), tmp); g_free(tmp); } } else { tmp = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name); if (aim_ssi_waitingforauth(od->sess->ssi.local, tmp, b->name)) oscar_string_append(str, newline, _("Status"), _("Not Authorized")); else oscar_string_append(str, newline, _("Status"), _("Offline")); } } if ((bi != NULL) && (bi->ipaddr != 0)) { tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", (bi->ipaddr & 0xff000000) >> 24, (bi->ipaddr & 0x00ff0000) >> 16, (bi->ipaddr & 0x0000ff00) >> 8, (bi->ipaddr & 0x000000ff)); oscar_string_append(str, newline, _("IP Address"), tmp); g_free(tmp); } if ((userinfo != NULL) && (userinfo->capabilities != 0)) { tmp = oscar_caps_to_string(userinfo->capabilities); oscar_string_append(str, newline, _("Capabilities"), tmp); g_free(tmp); } if ((b != NULL) && (b->name != NULL) && (g != NULL) && (g->name != NULL)) { tmp = aim_ssi_getcomment(od->sess->ssi.local, g->name, b->name); if (tmp != NULL) { char *tmp2 = g_markup_escape_text(tmp, strlen(tmp)); g_free(tmp); oscar_string_append(str, newline, _("Buddy Comment"), tmp2); g_free(tmp2); } } if ((bi != NULL) && (bi->availmsg != NULL) && !(b->uc & UC_UNAVAILABLE)) { tmp = g_markup_escape_text(bi->availmsg, strlen(bi->availmsg)); oscar_string_append(str, newline, _("Available"), tmp); g_free(tmp); }}static char *extract_name(const char *name) { char *tmp, *x; int i, j; if (!name) return NULL; x = strchr(name, '-'); if (!x) return NULL; x = strchr(++x, '-'); if (!x) return NULL; tmp = g_strdup(++x); for (i = 0, j = 0; x[i]; i++) { char hex[3]; if (x[i] != '%') { tmp[j++] = x[i]; continue; } strncpy(hex, x + ++i, 2); hex[2] = 0; i++; tmp[j++] = strtol(hex, NULL, 16); } tmp[j] = 0; return tmp;}static struct chat_connection *find_oscar_chat(GaimConnection *gc, int id) { GSList *g = ((OscarData *)gc->proto_data)->oscar_chats; struct chat_connection *c = NULL; while (g) { c = (struct chat_connection *)g->data; if (c->id == id) break; g = g->next; c = NULL; } return c;}static struct chat_connection *find_oscar_chat_by_conn(GaimConnection *gc, aim_conn_t *conn) { GSList *g = ((OscarData *)gc->proto_data)->oscar_chats; struct chat_connection *c = NULL; while (g) { c = (struct chat_connection *)g->data; if (c->conn == conn) break; g = g->next; c = NULL; } return c;}static struct chat_connection *find_oscar_chat_by_conv(GaimConnection *gc, GaimConversation *conv) { GSList *g = ((OscarData *)gc->proto_data)->oscar_chats; struct chat_connection *c = NULL; while (g) { c = (struct chat_connection *)g->data; if (c->conv == conv) break; g = g->next; c = NULL; } return c;}/***************************************************************************** * Begin scary direct im stuff *****************************************************************************/static struct oscar_direct_im *oscar_direct_im_find(OscarData *od, const char *who) { GSList *d = od->direct_ims; struct oscar_direct_im *m = NULL; while (d) { m = (struct oscar_direct_im *)d->data; if (!aim_sncmp(who, m->name)) return m; d = d->next; } return NULL;}static void oscar_direct_im_destroy(OscarData *od, struct oscar_direct_im *dim){ gaim_debug_info("oscar", "destroying Direct IM for %s.\n", dim->name); od->direct_ims = g_slist_remove(od->direct_ims, dim); if (dim->gpc_pend) { dim->killme = TRUE; return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -