grim/purple-plugin-pack
* @file irc-more.c A couple of additional IRC features. * Copyright (C) 2007-2008 Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> * Copyright (C) 2007-2008 John Bailey <rekkanoryo@rekkanoryo.org> * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA /* If you can't figure out what this line is for, DON'T TOUCH IT. */ #include "../common/pp_internal.h" #include <conversation.h> #define CTCP_REPLY purple_account_get_string(account, "ctcp-message", "Purple IRC") #define PART_MESSAGE purple_account_get_string(account, "part-message", "Leaving.") #define QUIT_MESSAGE purple_account_get_string(account, "quit-message", "Leaving.") #define SET_UMODES purple_account_get_string(account, "umodes", "i") #define UNSET_UMODES purple_account_get_string(account, "umodes", NULL) #define PLUGIN_ID "core-plugin_pack-irc-more" #define PREF_PREFIX "/plugins/core/" PLUGIN_ID #define PREF_DELAY PREF_PREFIX "/delay" #define MATCHES(string) !strncmp(*msg, string, sizeof(string) - 1) static PurpleCmdId notice_cmd_id = 0; static PurplePluginProtocolInfo *irc_info = NULL; /* So you think you can kick me? I'll show you! */ PurpleConversation *conv = data; char *conv_name = NULL, *command = NULL, *markup = NULL, *error = NULL; command = g_strdup_printf("join %s", conv_name); markup = g_markup_escape_text(command, -1); purple_cmd_do_command(conv, command, markup, &error); /* Do anything with the return value? */ irc_receiving_text(PurpleConnection *gc, const char **incoming, gpointer null) if (!incoming || !*incoming || !**incoming) /* oh the fun .. I can do this all day! */ splits = g_strsplit(*incoming, " ", -1); PurpleAccount *account = purple_connection_get_account(gc); char *str = g_ascii_strdown(splits[1], -1); if (strcmp(str, "kick") == 0 && splits[2] && splits[3]) { GList *chats = purple_get_chats(); PurpleConversation *conv = chats->data; if (purple_conversation_get_account(conv) == account && strcmp(purple_conversation_get_name(conv), name) == 0) { g_timeout_add(1000 * MAX(10, purple_prefs_get_int(PREF_DELAY)), show_them, conv); signed_on_cb(PurpleConnection *gc) /* should this be done on a timeout? */ PurpleAccount *account = NULL; const gchar *nick = NULL, *setmodes = NULL, *unsetmodes = NULL; gchar *msg = NULL, *msg2 = NULL; account = purple_connection_get_account(gc); /* hopefully prevent crashes related to non-IRC accounts signing on */ if(strcmp("prpl-irc", purple_account_get_protocol_id(account))) nick = purple_connection_get_display_name(gc); unsetmodes = UNSET_UMODES; msg = g_strdup_printf("MODE %s +%s\r\n", nick, setmodes); irc_info->send_raw(gc, msg, strlen(msg)); if(unsetmodes && *unsetmodes) { msg2 = g_strdup_printf("MODE %s -%s\r\n", nick, unsetmodes); irc_info->send_raw(gc, msg2, strlen(msg2)); #if !PURPLE_VERSION_CHECK(2,4,0) notice_cmd_cb(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data) gchar *tmp = NULL, *msg = NULL; gint len = 0, arg0len = 0, arg1len = 0, maxlen = 0; PurpleConnection *gc = NULL; if(!args && !args[0] && !args[1]) return PURPLE_CMD_RET_FAILED; gc = purple_conversation_get_gc(conv); /* convenience to make the next comparison make more sense */ arg0len = strlen(args[0]); arg1len = strlen(args[1]); /* IRC messages are limited to 512 bytes. 2 are reserved for CRLF, 2 for * the spaces needed after the command and target, 1 for the colon needed * before the notice text starts, and 6 for NOTICE. Result is the length * of the message needs to be limited to 501 bytes. We need to account * for the length of the nick or channel name that is the target, too. */ tmp = g_strndup(args[1], maxlen); /* if tmp is not NULL, the notice the user wants to send is too long so we * truncated it. If tmp is NULL the notice is fine as-is. Either way, * assign msg as appropriate. */ msg = g_strdup_printf("NOTICE %s :%s\r\n", args[0], msg); irc_info->send_raw(gc, msg, len); /* avoid a possible double-free crash */ return PURPLE_CMD_RET_OK; irc_sending_text(PurpleConnection *gc, char **msg, gpointer null) PurpleAccount *account = purple_connection_get_account(gc); char *message = strchr(*msg, ':'); if (!message || !strcmp(message + 1, "Leaving.\r\n")) { *msg = g_strdup_printf("QUIT :%s\r\n", QUIT_MESSAGE); } else if (MATCHES("PART ")) { char *message = strchr(*msg, ':'); return; /* The user did give some part message. Do not use the default one. */ message = strchr(*msg, '\r'); *msg = g_strdup_printf("%s :%s\r\n", *msg, PART_MESSAGE); } else if (MATCHES("NOTICE ")) { char *version = strstr(*msg, ":\001VERSION "); *msg = g_strdup_printf("%s:\001VERSION %s\001\r\n", *msg, CTCP_REPLY); plugin_load(PurplePlugin *plugin) PurplePlugin *prpl = NULL; PurpleAccountOption *option; gchar *notice_help = NULL; prpl = purple_find_prpl("prpl-irc"); /* if we didn't find the prpl, bail */ /* specify our help string and register our command */ notice_help = _("notice target message: Send a notice to the specified target."); #if !PURPLE_VERSION_CHECK(2,4,0) notice_cmd_id = purple_cmd_register("notice", "ws", PURPLE_CMD_P_PLUGIN, PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY, "prpl-irc", notice_cmd_cb, notice_help, NULL); /* we need this handle for the signed-on signal */ gc_handle = purple_connections_get_handle(); /* list signals in alphabetical order for consistency */ purple_signal_connect(prpl, "irc-sending-text", plugin, G_CALLBACK(irc_sending_text), NULL); purple_signal_connect(prpl, "irc-receiving-text", plugin, G_CALLBACK(irc_receiving_text), NULL); purple_signal_connect(gc_handle, "signed-on", plugin, G_CALLBACK(signed_on_cb), NULL); irc_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); /* Alphabetize the option label strings */ option = purple_account_option_string_new(_("CTCP Version reply"), "ctcp-message", "Purple IRC"); irc_info->protocol_options = g_list_append(irc_info->protocol_options, option); option = purple_account_option_string_new(_("Default Quit Message"), "quit-message", "Leaving."); irc_info->protocol_options = g_list_append(irc_info->protocol_options, option); option = purple_account_option_string_new(_("Default Part Message"), "part-message", "Leaving."); irc_info->protocol_options = g_list_append(irc_info->protocol_options, option); option = purple_account_option_string_new(_("Set User Modes On Connect"), "setumodes", "i"); irc_info->protocol_options = g_list_append(irc_info->protocol_options, option); option = purple_account_option_string_new(_("Unset User Modes On Connect"), "unsetumodes", ""); irc_info->protocol_options = g_list_append(irc_info->protocol_options, option); plugin_unload(PurplePlugin *plugin) purple_cmd_unregister(notice_cmd_id); static PurplePluginPrefFrame * get_plugin_pref_frame(PurplePlugin *plugin) PurplePluginPrefFrame *frame; frame = purple_plugin_pref_frame_new(); pref = purple_plugin_pref_new_with_name_and_label(PREF_DELAY, _("Seconds to wait before rejoining")); purple_plugin_pref_set_bounds(pref, 3, 3600); purple_plugin_pref_frame_add(frame, pref); static PurplePluginUiInfo prefs_info = { static PurplePluginInfo info = "Sadrul H Chowdhury <sadrul@users.sourceforge.net>", init_plugin(PurplePlugin *plugin) bindtextdomain(GETTEXT_PACKAGE, PP_LOCALEDIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); info.name = _("IRC More"); info.summary = _("Adds additional IRC features."); info.description = _("Adds additional IRC features, including a " "customizable quit message, a customizable CTCP VERSION reply, " "and the /notice command for notices."); purple_prefs_add_none(PREF_PREFIX); purple_prefs_add_int(PREF_DELAY, 30); PURPLE_INIT_PLUGIN(irc_more, init_plugin, info)