📄 ycht.c
字号:
/** * @file ycht.c The Yahoo! protocol plugin, YCHT protocol stuff. * * purple * * Copyright (C) 2004 Timothy Ringenbach <omarvo@hotmail.com> * Liberal amounts of code borrowed from the rest of the Yahoo! prpl. * * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <string.h>#include "internal.h"#include "prpl.h"#include "notify.h"#include "account.h"#include "proxy.h"#include "debug.h"#include "conversation.h"#include "util.h"#include "yahoo.h"#include "yahoo_packet.h"#include "ycht.h"#include "yahoochat.h"/* * dword: YCHT * dword: 0x000000AE * dword: service * word: status * word: size */#define YAHOO_CHAT_ID (1)/************************************************************************************ * Functions to process various kinds of packets. ************************************************************************************/static void ycht_process_login(YchtConn *ycht, YchtPkt *pkt){ PurpleConnection *gc = ycht->gc; struct yahoo_data *yd = gc->proto_data; if (ycht->logged_in) return; yd->chat_online = TRUE; ycht->logged_in = TRUE; if (ycht->room) ycht_chat_join(ycht, ycht->room);}static void ycht_process_logout(YchtConn *ycht, YchtPkt *pkt){ PurpleConnection *gc = ycht->gc; struct yahoo_data *yd = gc->proto_data; yd->chat_online = FALSE; ycht->logged_in = FALSE;}static void ycht_process_chatjoin(YchtConn *ycht, YchtPkt *pkt){ char *room, *topic; PurpleConnection *gc = ycht->gc; PurpleConversation *c = NULL; gboolean new_room = FALSE; char **members; int i; room = g_list_nth_data(pkt->data, 0); topic = g_list_nth_data(pkt->data, 1); if (!g_list_nth_data(pkt->data, 4)) return; if (!room) return; members = g_strsplit(g_list_nth_data(pkt->data, 4), "\001", 0); for (i = 0; members[i]; i++) { char *tmp = strchr(members[i], '\002'); if (tmp) *tmp = '\0'; } if (g_list_length(pkt->data) > 5) new_room = TRUE; if (new_room && ycht->changing_rooms) { serv_got_chat_left(gc, YAHOO_CHAT_ID); ycht->changing_rooms = FALSE; c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room); } else { c = purple_find_chat(gc, YAHOO_CHAT_ID); } if (topic) purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic); for (i = 0; members[i]; i++) { if (new_room) { /*if (!strcmp(members[i], purple_connection_get_display_name(ycht->gc))) continue;*/ purple_conv_chat_add_user(PURPLE_CONV_CHAT(c), members[i], NULL, PURPLE_CBFLAGS_NONE, TRUE); } else { yahoo_chat_add_user(PURPLE_CONV_CHAT(c), members[i], NULL); } } g_strfreev(members);}static void ycht_process_chatpart(YchtConn *ycht, YchtPkt *pkt){ char *room, *who; room = g_list_nth_data(pkt->data, 0); who = g_list_nth_data(pkt->data, 1); if (who && room) { PurpleConversation *c = purple_find_chat(ycht->gc, YAHOO_CHAT_ID); if (c && !purple_utf8_strcasecmp(purple_conversation_get_name(c), room)) purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), who, NULL); }}static void ycht_progress_chatmsg(YchtConn *ycht, YchtPkt *pkt){ char *who, *what, *msg; PurpleConversation *c; PurpleConnection *gc = ycht->gc; who = g_list_nth_data(pkt->data, 1); what = g_list_nth_data(pkt->data, 2); if (!who || !what) return; c = purple_find_chat(gc, YAHOO_CHAT_ID); if (!c) return; msg = yahoo_string_decode(gc, what, 1); what = yahoo_codes_to_html(msg); g_free(msg); if (pkt->service == YCHT_SERVICE_CHATMSG_EMOTE) { char *tmp = g_strdup_printf("/me %s", what); g_free(what); what = tmp; } serv_got_chat_in(gc, YAHOO_CHAT_ID, who, 0, what, time(NULL)); g_free(what);}static void ycht_progress_online_friends(YchtConn *ycht, YchtPkt *pkt){#if 0 PurpleConnection *gc = ycht->gc; struct yahoo_data *yd = gc->proto_data; if (ycht->logged_in) return; yd->chat_online = TRUE; ycht->logged_in = TRUE; if (ycht->room) ycht_chat_join(ycht, ycht->room);#endif}/***************************************************************************** * Functions dealing with YCHT packets and their contents directly. *****************************************************************************/static void ycht_packet_dump(const guchar *data, int len){#ifdef YAHOO_YCHT_DEBUG int i; purple_debug(PURPLE_DEBUG_MISC, "yahoo", ""); for (i = 0; i + 1 < len; i += 2) { if ((i % 16 == 0) && i) { purple_debug(PURPLE_DEBUG_MISC, NULL, "\n"); purple_debug(PURPLE_DEBUG_MISC, "yahoo", ""); } purple_debug(PURPLE_DEBUG_MISC, NULL, "%02hhx%02hhx ", data[i], data[i + 1]); } if (i < len) purple_debug(PURPLE_DEBUG_MISC, NULL, "%02hhx", data[i]); purple_debug(PURPLE_DEBUG_MISC, NULL, "\n"); purple_debug(PURPLE_DEBUG_MISC, "yahoo", ""); for (i = 0; i < len; i++) { if ((i % 16 == 0) && i) { purple_debug(PURPLE_DEBUG_MISC, NULL, "\n"); purple_debug(PURPLE_DEBUG_MISC, "yahoo", ""); } if (g_ascii_isprint(data[i])) purple_debug(PURPLE_DEBUG_MISC, NULL, "%c ", data[i]); else purple_debug(PURPLE_DEBUG_MISC, NULL, ". "); } purple_debug(PURPLE_DEBUG_MISC, NULL, "\n");#endif}static YchtPkt *ycht_packet_new(guint version, guint service, int status){ YchtPkt *ret; ret = g_new0(YchtPkt, 1); ret->version = version; ret->service = service; ret->status = status; return ret;}static void ycht_packet_append(YchtPkt *pkt, const char *str){ g_return_if_fail(pkt != NULL); g_return_if_fail(str != NULL); pkt->data = g_list_append(pkt->data, g_strdup(str));}static int ycht_packet_length(YchtPkt *pkt){ int ret; GList *l; ret = YCHT_HEADER_LEN; for (l = pkt->data; l; l = l->next) { ret += strlen(l->data); if (l->next) ret += strlen(YCHT_SEP); } return ret;}static void ycht_packet_send_write_cb(gpointer data, gint source, PurpleInputCondition cond){ YchtConn *ycht = data; int ret, writelen; writelen = purple_circ_buffer_get_max_read(ycht->txbuf); if (writelen == 0) { purple_input_remove(ycht->tx_handler); ycht->tx_handler = 0; return; } ret = write(ycht->fd, ycht->txbuf->outptr, writelen); if (ret < 0 && errno == EAGAIN) return; else if (ret <= 0) { /* TODO: error handling *//* purple_connection_error(purple_account_get_connection(irc->account), _("Server has disconnected"));*/ return; } purple_circ_buffer_mark_read(ycht->txbuf, ret);}static void ycht_packet_send(YchtConn *ycht, YchtPkt *pkt){ int len, pos, written; char *buf; GList *l; g_return_if_fail(ycht != NULL); g_return_if_fail(pkt != NULL); g_return_if_fail(ycht->fd != -1); pos = 0; len = ycht_packet_length(pkt); buf = g_malloc(len); memcpy(buf + pos, "YCHT", 4); pos += 4; pos += yahoo_put32(buf + pos, pkt->version); pos += yahoo_put32(buf + pos, pkt->service); pos += yahoo_put16(buf + pos, pkt->status); pos += yahoo_put16(buf + pos, len - YCHT_HEADER_LEN); for (l = pkt->data; l; l = l->next) { int slen = strlen(l->data); memcpy(buf + pos, l->data, slen); pos += slen; if (l->next) { memcpy(buf + pos, YCHT_SEP, strlen(YCHT_SEP)); pos += strlen(YCHT_SEP); } } if (!ycht->tx_handler) written = write(ycht->fd, buf, len); else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -