📄 irc.c
字号:
const char *args[2]; if (strchr(status_chars, *who) != NULL) args[0] = who + 1; else args[0] = who; purple_markup_html_to_xhtml(what, NULL, &plain); args[1] = plain; irc_cmd_privmsg(irc, "msg", NULL, args); g_free(plain); return 1;}static void irc_get_info(PurpleConnection *gc, const char *who){ struct irc_conn *irc = gc->proto_data; const char *args[2]; args[0] = who; args[1] = NULL; irc_cmd_whois(irc, "whois", NULL, args);}static void irc_set_status(PurpleAccount *account, PurpleStatus *status){ PurpleConnection *gc = purple_account_get_connection(account); struct irc_conn *irc; const char *args[1]; const char *status_id = purple_status_get_id(status); g_return_if_fail(gc != NULL); irc = gc->proto_data; if (!purple_status_is_active(status)) return; args[0] = NULL; if (!strcmp(status_id, "away")) { args[0] = purple_status_get_attr_string(status, "message"); if ((args[0] == NULL) || (*args[0] == '\0')) args[0] = _("Away"); irc_cmd_away(irc, "away", NULL, args); } else if (!strcmp(status_id, "available")) { irc_cmd_away(irc, "back", NULL, args); }}static void irc_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group){ struct irc_conn *irc = (struct irc_conn *)gc->proto_data; struct irc_buddy *ib = g_new0(struct irc_buddy, 1); ib->name = g_strdup(buddy->name); g_hash_table_insert(irc->buddies, ib->name, ib); /* if the timer isn't set, this is during signon, so we don't want to flood * ourself off with ISON's, so we don't, but after that we want to know when * someone's online asap */ if (irc->timer) irc_ison_one(irc, ib);}static void irc_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group){ struct irc_conn *irc = (struct irc_conn *)gc->proto_data; g_hash_table_remove(irc->buddies, buddy->name);}static void read_input(struct irc_conn *irc, int len){ char *cur, *end; irc->inbufused += len; irc->inbuf[irc->inbufused] = '\0'; cur = irc->inbuf; /* This is a hack to work around the fact that marv gets messages * with null bytes in them while using some weird irc server at work */ while ((cur < (irc->inbuf + irc->inbufused)) && !*cur) cur++; while (cur < irc->inbuf + irc->inbufused && ((end = strstr(cur, "\r\n")) || (end = strstr(cur, "\n")))) { int step = (*end == '\r' ? 2 : 1); *end = '\0'; irc_parse_msg(irc, cur); cur = end + step; } if (cur != irc->inbuf + irc->inbufused) { /* leftover */ irc->inbufused -= (cur - irc->inbuf); memmove(irc->inbuf, cur, irc->inbufused); } else { irc->inbufused = 0; }}static void irc_input_cb_ssl(gpointer data, PurpleSslConnection *gsc, PurpleInputCondition cond){ PurpleConnection *gc = data; struct irc_conn *irc = gc->proto_data; int len; if(!g_list_find(purple_connections_get_all(), gc)) { purple_ssl_close(gsc); return; } if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { irc->inbuflen += IRC_INITIAL_BUFSIZE; irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); } len = purple_ssl_read(gsc, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1); if (len < 0 && errno == EAGAIN) { /* Try again later */ return; } else if (len < 0) { purple_connection_error(gc, _("Read error")); return; } else if (len == 0) { purple_connection_error(gc, _("Server has disconnected")); return; } read_input(irc, len);}static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond){ PurpleConnection *gc = data; struct irc_conn *irc = gc->proto_data; int len; if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { irc->inbuflen += IRC_INITIAL_BUFSIZE; irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); } len = read(irc->fd, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1); if (len < 0 && errno == EAGAIN) { return; } else if (len < 0) { purple_connection_error(gc, _("Read error")); return; } else if (len == 0) { purple_connection_error(gc, _("Server has disconnected")); return; } read_input(irc, len);}static void irc_chat_join (PurpleConnection *gc, GHashTable *data){ struct irc_conn *irc = gc->proto_data; const char *args[2]; args[0] = g_hash_table_lookup(data, "channel"); args[1] = g_hash_table_lookup(data, "password"); irc_cmd_join(irc, "join", NULL, args);}static char *irc_get_chat_name(GHashTable *data) { return g_strdup(g_hash_table_lookup(data, "channel"));}static void irc_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name){ struct irc_conn *irc = gc->proto_data; PurpleConversation *convo = purple_find_chat(gc, id); const char *args[2]; if (!convo) { purple_debug(PURPLE_DEBUG_ERROR, "irc", "Got chat invite request for bogus chat\n"); return; } args[0] = name; args[1] = purple_conversation_get_name(convo); irc_cmd_invite(irc, "invite", purple_conversation_get_name(convo), args);}static void irc_chat_leave (PurpleConnection *gc, int id){ struct irc_conn *irc = gc->proto_data; PurpleConversation *convo = purple_find_chat(gc, id); const char *args[2]; if (!convo) return; args[0] = purple_conversation_get_name(convo); args[1] = NULL; irc_cmd_part(irc, "part", purple_conversation_get_name(convo), args); serv_got_chat_left(gc, id);}static int irc_chat_send(PurpleConnection *gc, int id, const char *what, PurpleMessageFlags flags){ struct irc_conn *irc = gc->proto_data; PurpleConversation *convo = purple_find_chat(gc, id); const char *args[2]; char *tmp; if (!convo) { purple_debug(PURPLE_DEBUG_ERROR, "irc", "chat send on nonexistent chat\n"); return -EINVAL; }#if 0 if (*what == '/') { return irc_parse_cmd(irc, convo->name, what + 1); }#endif purple_markup_html_to_xhtml(what, NULL, &tmp); args[0] = convo->name; args[1] = tmp; irc_cmd_privmsg(irc, "msg", NULL, args); serv_got_chat_in(gc, id, purple_connection_get_display_name(gc), 0, what, time(NULL)); g_free(tmp); return 0;}static guint irc_nick_hash(const char *nick){ char *lc; guint bucket; lc = g_utf8_strdown(nick, -1); bucket = g_str_hash(lc); g_free(lc); return bucket;}static gboolean irc_nick_equal(const char *nick1, const char *nick2){ return (purple_utf8_strcasecmp(nick1, nick2) == 0);}static void irc_buddy_free(struct irc_buddy *ib){ g_free(ib->name); g_free(ib);}static void irc_chat_set_topic(PurpleConnection *gc, int id, const char *topic){ char *buf; const char *name = NULL; struct irc_conn *irc; irc = gc->proto_data; name = purple_conversation_get_name(purple_find_chat(gc, id)); if (name == NULL) return; buf = irc_format(irc, "vt:", "TOPIC", name, topic); irc_send(irc, buf); g_free(buf);}static PurpleRoomlist *irc_roomlist_get_list(PurpleConnection *gc){ struct irc_conn *irc; GList *fields = NULL; PurpleRoomlistField *f; char *buf; irc = gc->proto_data; if (irc->roomlist) purple_roomlist_unref(irc->roomlist); irc->roomlist = purple_roomlist_new(purple_connection_get_account(gc)); f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "", "channel", TRUE); fields = g_list_append(fields, f); f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_INT, _("Users"), "users", FALSE); fields = g_list_append(fields, f); f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE); fields = g_list_append(fields, f); purple_roomlist_set_fields(irc->roomlist, fields); buf = irc_format(irc, "v", "LIST"); irc_send(irc, buf); g_free(buf); return irc->roomlist;}static void irc_roomlist_cancel(PurpleRoomlist *list){ PurpleConnection *gc = purple_account_get_connection(list->account); struct irc_conn *irc; if (gc == NULL) return; irc = gc->proto_data; purple_roomlist_set_in_progress(list, FALSE); if (irc->roomlist == list) { irc->roomlist = NULL; purple_roomlist_unref(list); }}static void irc_keepalive(PurpleConnection *gc){ struct irc_conn *irc = gc->proto_data; if ((time(NULL) - irc->recv_time) > PING_TIMEOUT) irc_cmd_ping(irc, NULL, NULL, NULL);}static PurplePluginProtocolInfo prpl_info ={ OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL, NULL, /* user_splits */ NULL, /* protocol_options */ NO_BUDDY_ICONS, /* icon_spec */ irc_blist_icon, /* list_icon */ NULL, /* list_emblems */ NULL, /* status_text */ NULL, /* tooltip_text */ irc_status_types, /* away_states */ NULL, /* blist_node_menu */ irc_chat_join_info, /* chat_info */ irc_chat_info_defaults, /* chat_info_defaults */ irc_login, /* login */ irc_close, /* close */ irc_im_send, /* send_im */ NULL, /* set_info */ NULL, /* send_typing */ irc_get_info, /* get_info */ irc_set_status, /* set_status */ NULL, /* set_idle */ NULL, /* change_passwd */ irc_add_buddy, /* add_buddy */ NULL, /* add_buddies */ irc_remove_buddy, /* remove_buddy */ NULL, /* remove_buddies */ NULL, /* add_permit */ NULL, /* add_deny */ NULL, /* rem_permit */ NULL, /* rem_deny */ NULL, /* set_permit_deny */ irc_chat_join, /* join_chat */ NULL, /* reject_chat */ irc_get_chat_name, /* get_chat_name */ irc_chat_invite, /* chat_invite */ irc_chat_leave, /* chat_leave */ NULL, /* chat_whisper */ irc_chat_send, /* chat_send */ irc_keepalive, /* keepalive */ NULL, /* register_user */ NULL, /* get_cb_info */ NULL, /* get_cb_away */ NULL, /* alias_buddy */ NULL, /* group_buddy */ NULL, /* rename_group */ NULL, /* buddy_free */ NULL, /* convo_closed */ purple_normalize_nocase, /* normalize */ NULL, /* set_buddy_icon */ NULL, /* remove_group */ NULL, /* get_cb_real_name */ irc_chat_set_topic, /* set_chat_topic */ NULL, /* find_blist_chat */ irc_roomlist_get_list, /* roomlist_get_list */ irc_roomlist_cancel, /* roomlist_cancel */ NULL, /* roomlist_expand_category */ NULL, /* can_receive_file */ irc_dccsend_send_file, /* send_file */ irc_dccsend_new_xfer, /* new_xfer */ NULL, /* offline_message */ NULL, /* whiteboard_prpl_ops */ irc_send_raw, /* send_raw */ NULL, /* roomlist_room_serialize */ /* padding */ NULL, NULL, NULL, NULL};static gboolean load_plugin (PurplePlugin *plugin) { purple_signal_register(plugin, "irc-sending-text", purple_marshal_VOID__POINTER_POINTER, NULL, 2, purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION), purple_value_new_outgoing(PURPLE_TYPE_STRING)); purple_signal_register(plugin, "irc-receiving-text", purple_marshal_VOID__POINTER_POINTER, NULL, 2, purple_value_new(PURPLE_TYPE_SUBTYPE, PURPLE_SUBTYPE_CONNECTION), purple_value_new_outgoing(PURPLE_TYPE_STRING)); return TRUE;}static PurplePluginInfo info ={ PURPLE_PLUGIN_MAGIC, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_PLUGIN_PROTOCOL, /**< type */ NULL, /**< ui_requirement */ 0, /**< flags */ NULL, /**< dependencies */ PURPLE_PRIORITY_DEFAULT, /**< priority */ "prpl-irc", /**< id */ "IRC", /**< name */ VERSION, /**< version */ N_("IRC Protocol Plugin"), /** summary */ N_("The IRC Protocol Plugin that Sucks Less"), /** description */ NULL, /**< author */ PURPLE_WEBSITE, /**< homepage */ load_plugin, /**< load */ NULL, /**< unload */ NULL, /**< destroy */ NULL, /**< ui_info */ &prpl_info, /**< extra_info */ NULL, /**< prefs_info */ irc_actions, /* padding */ NULL, NULL, NULL, NULL};static void _init_plugin(PurplePlugin *plugin){ PurpleAccountUserSplit *split; PurpleAccountOption *option; split = purple_account_user_split_new(_("Server"), IRC_DEFAULT_SERVER, '@'); prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); option = purple_account_option_int_new(_("Port"), "port", IRC_DEFAULT_PORT); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); option = purple_account_option_string_new(_("Encodings"), "encoding", IRC_DEFAULT_CHARSET); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); option = purple_account_option_string_new(_("Username"), "username", ""); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); option = purple_account_option_string_new(_("Real name"), "realname", ""); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); /* option = purple_account_option_string_new(_("Quit message"), "quitmsg", IRC_DEFAULT_QUIT); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); */ option = purple_account_option_bool_new(_("Use SSL"), "ssl", FALSE); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); _irc_plugin = plugin; purple_prefs_remove("/plugins/prpl/irc/quitmsg"); purple_prefs_remove("/plugins/prpl/irc"); irc_register_commands();}PURPLE_INIT_PLUGIN(irc, _init_plugin, info);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -