📄 yahoochat.c
字号:
void yahoo_process_chat_message(PurpleConnection *gc, struct yahoo_packet *pkt){ char *room = NULL, *who = NULL, *msg = NULL, *msg2; int msgtype = 1, utf8 = 1; /* default to utf8 */ PurpleConversation *c = NULL; GSList *l; for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; switch (pair->key) { case 97: utf8 = strtol(pair->value, NULL, 10); break; case 104: room = yahoo_string_decode(gc, pair->value, TRUE); break; case 109: who = pair->value; break; case 117: msg = pair->value; break; case 124: msgtype = strtol(pair->value, NULL, 10); break; } } c = purple_find_chat(gc, YAHOO_CHAT_ID); if (!who || !c) { if (room) g_free(room); /* we still get messages after we part, funny that */ return; } if (!msg) { purple_debug(PURPLE_DEBUG_MISC, "yahoo", "Got a message packet with no message.\nThis probably means something important, but we're ignoring it.\n"); return; } msg2 = yahoo_string_decode(gc, msg, utf8); msg = yahoo_codes_to_html(msg2); g_free(msg2); if (msgtype == 2 || msgtype == 3) { char *tmp; tmp = g_strdup_printf("/me %s", msg); g_free(msg); msg = tmp; } serv_got_chat_in(gc, YAHOO_CHAT_ID, who, 0, msg, time(NULL)); g_free(msg); g_free(room);}void yahoo_process_chat_addinvite(PurpleConnection *gc, struct yahoo_packet *pkt){ GSList *l; char *room = NULL; char *msg = NULL; char *who = NULL; for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; switch (pair->key) { case 104: room = yahoo_string_decode(gc, pair->value, TRUE); break; case 129: /* room id? */ break; case 126: /* ??? */ break; case 117: msg = yahoo_string_decode(gc, pair->value, FALSE); break; case 119: who = pair->value; break; case 118: /* us */ break; } } if (room && who) { GHashTable *components; components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_replace(components, g_strdup("room"), g_strdup(room)); if (!yahoo_privacy_check(gc, who) || (purple_account_get_bool(purple_connection_get_account(gc), "ignore_invites", FALSE))) { purple_debug_info("yahoo", "Invite to room %s from %s has been dropped.\n", room, who); if (room != NULL) g_free(room); if (msg != NULL) g_free(msg); return; } serv_got_chat_invite(gc, room, who, msg, components); } if (room) g_free(room); if (msg) g_free(msg);}void yahoo_process_chat_goto(PurpleConnection *gc, struct yahoo_packet *pkt){ if (pkt->status == -1) purple_notify_error(gc, NULL, _("Failed to join buddy in chat"), _("Maybe they're not in a chat?"));}/* * Functions dealing with conferences * I think conference names are always ascii. */void yahoo_conf_leave(struct yahoo_data *yd, const char *room, const char *dn, GList *who){ struct yahoo_packet *pkt; GList *w; purple_debug_misc("yahoo", "leaving conference %s\n", room); pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash_str(pkt, 1, dn); for (w = who; w; w = w->next) { const char *name = purple_conv_chat_cb_get_name(w->data); yahoo_packet_hash_str(pkt, 3, name); } yahoo_packet_hash_str(pkt, 57, room); yahoo_packet_send_and_free(pkt, yd);}static int yahoo_conf_send(PurpleConnection *gc, const char *dn, const char *room, GList *members, const char *what){ struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt; GList *who; char *msg, *msg2; int utf8 = 1; msg = yahoo_html_to_codes(what); msg2 = yahoo_string_encode(gc, msg, &utf8); pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash_str(pkt, 1, dn); for (who = members; who; who = who->next) { const char *name = purple_conv_chat_cb_get_name(who->data); yahoo_packet_hash_str(pkt, 53, name); } yahoo_packet_hash(pkt, "ss", 57, room, 14, msg2); if (utf8) yahoo_packet_hash_str(pkt, 97, "1"); /* utf-8 */ yahoo_packet_send_and_free(pkt, yd); g_free(msg); g_free(msg2); return 0;}static void yahoo_conf_join(struct yahoo_data *yd, PurpleConversation *c, const char *dn, const char *room, const char *topic, const char *members){ struct yahoo_packet *pkt; char **memarr = NULL; int i; if (members) memarr = g_strsplit(members, "\n", 0); pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, "sss", 1, dn, 3, dn, 57, room); if (memarr) { for(i = 0 ; memarr[i]; i++) { if (!strcmp(memarr[i], "") || !strcmp(memarr[i], dn)) continue; yahoo_packet_hash_str(pkt, 3, memarr[i]); purple_conv_chat_add_user(PURPLE_CONV_CHAT(c), memarr[i], NULL, PURPLE_CBFLAGS_NONE, TRUE); } } yahoo_packet_send_and_free(pkt, yd); if (memarr) g_strfreev(memarr);}static void yahoo_conf_invite(PurpleConnection *gc, PurpleConversation *c, const char *dn, const char *buddy, const char *room, const char *msg){ struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt; GList *members; char *msg2 = NULL; if (msg) msg2 = yahoo_string_encode(gc, msg, NULL); members = purple_conv_chat_get_users(PURPLE_CONV_CHAT(c)); pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, "sssss", 1, dn, 51, buddy, 57, room, 58, msg?msg2:"", 13, "0"); for(; members; members = members->next) { const char *name = purple_conv_chat_cb_get_name(members->data); if (!strcmp(name, dn)) continue; yahoo_packet_hash(pkt, "ss", 52, name, 53, name); } yahoo_packet_send_and_free(pkt, yd); g_free(msg2);}/* * Functions dealing with chats */static void yahoo_chat_leave(PurpleConnection *gc, const char *room, const char *dn, gboolean logout){ struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt; PurpleConversation *c; char *eroom; gboolean utf8 = 1; if (yd->wm) { g_return_if_fail(yd->ycht != NULL); ycht_chat_leave(yd->ycht, room, logout); return; } eroom = yahoo_string_encode(gc, room, &utf8); pkt = yahoo_packet_new(YAHOO_SERVICE_CHATEXIT, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, "sss", 104, eroom, 109, dn, 108, "1"); yahoo_packet_hash_str(pkt, 112, "0"); /* what does this one mean? */ yahoo_packet_send_and_free(pkt, yd); yd->in_chat = 0; if (yd->chat_name) { g_free(yd->chat_name); yd->chat_name = NULL; } if ((c = purple_find_chat(gc, YAHOO_CHAT_ID))) serv_got_chat_left(gc, YAHOO_CHAT_ID); if (!logout) return; pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash_str(pkt, 1, dn); yahoo_packet_send_and_free(pkt, yd); yd->chat_online = 0; g_free(eroom);}/* borrowed from gtkconv.c */static gbooleanmeify(char *message, size_t len){ /* * Read /me-ify: If the message (post-HTML) starts with /me, * remove the "/me " part of it (including that space) and return TRUE. */ char *c; gboolean inside_html = 0; /* Umm.. this would be very bad if this happens. */ g_return_val_if_fail(message != NULL, FALSE); if (len == -1) len = strlen(message); for (c = message; *c != '\0'; c++, len--) { if (inside_html) { if (*c == '>') inside_html = FALSE; } else { if (*c == '<') inside_html = TRUE; else break; } } if (*c != '\0' && !g_ascii_strncasecmp(c, "/me ", 4)) { memmove(c, c + 4, len - 3); return TRUE; } return FALSE;}static int yahoo_chat_send(PurpleConnection *gc, const char *dn, const char *room, const char *what, PurpleMessageFlags flags){ struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt; int me = 0; char *msg1, *msg2, *room2; gboolean utf8 = TRUE; if (yd->wm) { g_return_val_if_fail(yd->ycht != NULL, 1); return ycht_chat_send(yd->ycht, room, what); } msg1 = g_strdup(what); if (meify(msg1, -1)) me = 1; msg2 = yahoo_html_to_codes(msg1); g_free(msg1); msg1 = yahoo_string_encode(gc, msg2, &utf8); g_free(msg2); room2 = yahoo_string_encode(gc, room, NULL); pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, "sss", 1, dn, 104, room2, 117, msg1); if (me) yahoo_packet_hash_str(pkt, 124, "2"); else yahoo_packet_hash_str(pkt, 124, "1"); /* fixme: what about /think? (124=3) */ if (utf8) yahoo_packet_hash_str(pkt, 97, "1"); yahoo_packet_send_and_free(pkt, yd); g_free(msg1); g_free(room2); return 0;}static void yahoo_chat_join(PurpleConnection *gc, const char *dn, const char *room, const char *topic){ struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt; char *room2; gboolean utf8 = TRUE; if (yd->wm) { g_return_if_fail(yd->ycht != NULL); ycht_chat_join(yd->ycht, room); return; } /* apparently room names are always utf8, or else always not utf8, * so we don't have to actually pass the flag in the packet. Or something. */ room2 = yahoo_string_encode(gc, room, &utf8); pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, "ssss", 1, purple_connection_get_display_name(gc), 62, "2", 104, room2, 129, "0"); yahoo_packet_send_and_free(pkt, yd); g_free(room2);}static void yahoo_chat_invite(PurpleConnection *gc, const char *dn, const char *buddy, const char *room, const char *msg){ struct yahoo_data *yd = gc->proto_data; struct yahoo_packet *pkt; char *room2, *msg2 = NULL; gboolean utf8 = TRUE; if (yd->wm) { g_return_if_fail(yd->ycht != NULL); ycht_chat_send_invite(yd->ycht, room, buddy, msg); return; } room2 = yahoo_string_encode(gc, room, &utf8); if (msg) msg2 = yahoo_string_encode(gc, msg, NULL); pkt = yahoo_packet_new(YAHOO_SERVICE_CHATADDINVITE, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, "sssss", 1, dn, 118, buddy, 104, room2, 117, (msg2?msg2:""), 129, "0"); yahoo_packet_send_and_free(pkt, yd); g_free(room2); g_free(msg2);}void yahoo_chat_goto(PurpleConnection *gc, const char *name){ struct yahoo_data *yd; struct yahoo_packet *pkt; yd = gc->proto_data; if (yd->wm) { g_return_if_fail(yd->ycht != NULL); ycht_chat_goto_user(yd->ycht, name); return; } if (!yd->chat_online) yahoo_chat_online(gc); pkt = yahoo_packet_new(YAHOO_SERVICE_CHATGOTO, YAHOO_STATUS_AVAILABLE, 0); yahoo_packet_hash(pkt, "sss", 109, name, 1, purple_connection_get_display_name(gc), 62, "2"); yahoo_packet_send_and_free(pkt, yd);}/* * These are the functions registered with the core * which get called for both chats and conferences. */void yahoo_c_leave(PurpleConnection *gc, int id){ struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; PurpleConversation *c; if (!yd) return; c = purple_find_chat(gc, id); if (!c) return; if (id != YAHOO_CHAT_ID) { yahoo_conf_leave(yd, purple_conversation_get_name(c), purple_connection_get_display_name(gc), purple_conv_chat_get_users(PURPLE_CONV_CHAT(c))); yd->confs = g_slist_remove(yd->confs, c); } else { yahoo_chat_leave(gc, purple_conversation_get_name(c), purple_connection_get_display_name(gc), TRUE); } serv_got_chat_left(gc, id);}int yahoo_c_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFlags flags){ PurpleConversation *c; int ret; struct yahoo_data *yd; yd = (struct yahoo_data *) gc->proto_data; if (!yd) return -1; c = purple_find_chat(gc, id); if (!c) return -1; if (id != YAHOO_CHAT_ID) { ret = yahoo_conf_send(gc, purple_connection_get_display_name(gc), purple_conversation_get_name(c), purple_conv_chat_get_users(PURPLE_CONV_CHAT(c)), what); } else { ret = yahoo_chat_send(gc, purple_connection_get_display_name(gc), purple_conversation_get_name(c), what, flags); if (!ret) serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), purple_connection_get_display_name(gc), 0, what, time(NULL)); } return ret;}GList *yahoo_c_info(PurpleConnection *gc){ GList *m = NULL; struct proto_chat_entry *pce; pce = g_new0(struct proto_chat_entry, 1); pce->label = _("_Room:"); pce->identifier = "room"; pce->required = TRUE; m = g_list_append(m, pce); return m;}GHashTable *yahoo_c_info_defaults(PurpleConnection *gc, const char *chat_name){ GHashTable *defaults; defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); if (chat_name != NULL) g_hash_table_insert(defaults, "room", g_strdup(chat_name)); return defaults;}char *yahoo_get_chat_name(GHashTable *data){ return g_strdup(g_hash_table_lookup(data, "room"));}void yahoo_c_join(PurpleConnection *gc, GHashTable *data)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -