Loading CHANGELOG.txt +2 −0 Changes for CHANGELOG.txt: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ Bot 7.x-1.3, 2011-xx-xx ----------------------- * All incoming messages are forced to UTF-8 (thanks bellHead, nick_vh!). * #918966: Rewrote/moved Net_SmartIRC wrapper; hook_irc_access added. * All forgotten strlens()s have been changed to drupal_strlen(). * All forgotten substr()s have been changed to drupal_substr(). * First release for Drupal 7.x; based on 6.x-1.2 release. Loading bot.smartirc.inc 0 → 100644 +103 −0 Changes for bot.smartirc.inc: 103 added lines, 0 removed lines. Original line number Diff line number Diff line <?php // $Id$ /** * @file * Classes and functions that wrap Drupal up for Net_SmartIRC. */ /** * A Drupal wrapper for the various Net_SmartIRC handlers. */ class bot_smartirc_wrapper { /** * Handle all Net_SmartIRC callbacks. * * @param &$irc * The Net_SmartIRC $irc object. * @param &$data * The Net_SmartIRC data object for this message. */ function invoke(&$irc, &$data = NULL) { if (isset($data)) { // Net_SmartIRC passes data through in the encoding received from the // IRC server. The IRC server, in turn, passes it through as received // from the remote client. If the remote client is using a single byte // encoding (ISO-8559-1 aka Latin-1), this will result in mangled // characters or may raise errors for 8-bit characters. Under Drupal 7 // and PHP 5.3, this caused an "invalid multibyte sequence" warning // from htmlspecialchars() and a PDOException that crashed the bot. // (To reproduce: use XChat to connect to a server as latin1, but then // send an 8-bit Latin-1 character like a Euro [€]). Since we cannot // control the encoding of IRC messages like we can control the encoding // of web form submissions, we need to force UTF-8 for all messages. if (function_exists('mb_detect_encoding')) { $encoding = mb_detect_encoding($data->message, 'UTF-8, ISO-8859-1'); if ($encoding != 'UTF-8') { // no point of converting it already. // we only convert over message related elements and leave the // existing parses (nick, ident, host, type, channel, etc.) alone. $data->message = mb_convert_encoding($data->message, 'UTF-8', $encoding); $data->rawmessage = mb_convert_encoding($data->rawmessage, 'UTF-8', $encoding); $data->messageex = explode(' ', $data->message); $data->rawmessageex = explode(' ', $data->rawmessage); watchdog('bot', 'Converted @encoding to UTF-8: @message.', array('@encoding' => $encoding, '@message' => $data->message), WATCHDOG_INFO); } } } // The name of the hook is a substring of the class name. $hook = drupal_substr(get_class($this), drupal_strlen('bot_')); // Give modules an opportunity to stop message processing. foreach (module_implements('irc_access') as $module) { $function = "{$module}_irc_access"; $result = $function($hook, $data); // Stop handling this request if FALSE. if (isset($result) && $result === FALSE) { return; } } // Proceed normally. module_invoke_all($hook, $data); } } // Bot cron sub-classes. class bot_irc_bot_cron extends bot_smartirc_wrapper {} class bot_irc_bot_cron_faster extends bot_smartirc_wrapper {} class bot_irc_bot_cron_fastest extends bot_smartirc_wrapper {} // IRC message sub-classes. class bot_irc_msg_unknown extends bot_smartirc_wrapper {} class bot_irc_msg_channel extends bot_smartirc_wrapper {} class bot_irc_msg_query extends bot_smartirc_wrapper {} class bot_irc_msg_ctcp extends bot_smartirc_wrapper {} class bot_irc_msg_notice extends bot_smartirc_wrapper {} class bot_irc_msg_who extends bot_smartirc_wrapper {} class bot_irc_msg_join extends bot_smartirc_wrapper {} class bot_irc_msg_invite extends bot_smartirc_wrapper {} class bot_irc_msg_action extends bot_smartirc_wrapper {} class bot_irc_msg_topicchange extends bot_smartirc_wrapper {} class bot_irc_msg_nickchange extends bot_smartirc_wrapper {} class bot_irc_msg_kick extends bot_smartirc_wrapper {} class bot_irc_msg_quit extends bot_smartirc_wrapper {} class bot_irc_msg_login extends bot_smartirc_wrapper {} class bot_irc_msg_info extends bot_smartirc_wrapper {} class bot_irc_msg_list extends bot_smartirc_wrapper {} class bot_irc_msg_name extends bot_smartirc_wrapper {} class bot_irc_msg_motd extends bot_smartirc_wrapper {} class bot_irc_msg_modechange extends bot_smartirc_wrapper {} class bot_irc_msg_part extends bot_smartirc_wrapper {} class bot_irc_msg_error extends bot_smartirc_wrapper {} class bot_irc_msg_banlist extends bot_smartirc_wrapper {} class bot_irc_msg_topic extends bot_smartirc_wrapper {} class bot_irc_msg_nonrelevant extends bot_smartirc_wrapper {} class bot_irc_msg_whois extends bot_smartirc_wrapper {} class bot_irc_msg_whowas extends bot_smartirc_wrapper {} class bot_irc_msg_usermode extends bot_smartirc_wrapper {} class bot_irc_msg_channelmode extends bot_smartirc_wrapper {} class bot_irc_msg_ctcp_request extends bot_smartirc_wrapper {} class bot_irc_msg_ctcp_reply extends bot_smartirc_wrapper {} bot_start.php +10 −47 Changes for bot_start.php: 10 added lines, 47 removed lines. Original line number Diff line number Diff line Loading @@ -36,17 +36,17 @@ while ($param = array_shift($_SERVER['argv'])) { } } // load in our required libraries. require_once './includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); require_once('Net/SmartIRC.php'); // load in required libraries. require_once 'Net/SmartIRC.php'; require_once DRUPAL_ROOT . '/includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); // gotta bootstrap everything in before d_g_p. require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'bot') . '/bot.smartirc.inc'; // prevent MySQL timeouts on slow channels. db_query('SET SESSION wait_timeout = 86400'); // initialize the bot with some sane defaults. global $irc; // allow it to be slurped by Drupal modules if need be. $bot = new drupal_wrapper(); // wrapper that integrates with Drupal hooks. $irc = new Net_SmartIRC(); // MmmmmmM. The IRC object itself. Magick happens here. $irc->setDebug( variable_get('bot_debugging', 0) ? SMARTIRC_DEBUG_ALL : SMARTIRC_DEBUG_NONE ); // the (boolean) here is required, as Net_SmartIRC doesn't respect a FAPI checkbox value of 1, only TRUE. Loading @@ -67,14 +67,15 @@ $irc_message_types = array( ); foreach ($irc_message_types as $irc_message_type) { $irc->registerActionhandler(constant('SMARTIRC_TYPE_' . $irc_message_type), '.*', $bot, 'invoke_irc_msg_' . strtolower($irc_message_type)); $class = 'bot_irc_msg_' . drupal_strtolower($irc_message_type); $irc->registerActionhandler(constant('SMARTIRC_TYPE_' . $irc_message_type), '.*', new $class(), 'invoke'); } // set up a timers similar to Drupal's hook_cron(), multiple types. I would have // liked to just pass a parameter to a single function, but SmartIRC can't do that. $irc->registerTimehandler(300000, $bot, 'invoke_irc_bot_cron'); // 5 minutes. $irc->registerTimehandler(60000, $bot, 'invoke_irc_bot_cron_faster'); // 1 minute. $irc->registerTimehandler(15000, $bot, 'invoke_irc_bot_cron_fastest'); // 15 seconds. $irc->registerTimehandler(300000, new bot_irc_bot_cron(), 'invoke'); // 5 minutes. $irc->registerTimehandler(60000, new bot_irc_bot_cron_faster(), 'invoke'); // 1 minute. $irc->registerTimehandler(15000, new bot_irc_bot_cron_fastest(), 'invoke'); // 15 seconds. // connect and begin listening. $irc->connect(variable_get('bot_server', 'irc.freenode.net'), variable_get('bot_server_port', 6667)); Loading @@ -85,41 +86,3 @@ $irc->login(variable_get('bot_nickname', 'bot_module'), variable_get('bot_nickna $irc->listen(); // go into the forever loop - no code after this is run. $irc->disconnect(); // if we stop listening, disconnect properly. // pass off IRC messages to our modules via Drupal's hook system. class drupal_wrapper { function invoke_irc_bot_cron(&$irc) { module_invoke_all('irc_bot_cron'); } function invoke_irc_bot_cron_faster(&$irc) { module_invoke_all('irc_bot_cron_faster'); } function invoke_irc_bot_cron_fastest(&$irc) { module_invoke_all('irc_bot_cron_fastest'); } function invoke_irc_msg_unknown(&$irc, &$data) { module_invoke_all('irc_msg_unknown', $data); } function invoke_irc_msg_channel(&$irc, &$data) { module_invoke_all('irc_msg_channel', $data); } function invoke_irc_msg_query(&$irc, &$data) { module_invoke_all('irc_msg_query', $data); } function invoke_irc_msg_ctcp(&$irc, &$data) { module_invoke_all('irc_msg_ctcp', $data); } function invoke_irc_msg_notice(&$irc, &$data) { module_invoke_all('irc_msg_notice', $data); } function invoke_irc_msg_who(&$irc, &$data) { module_invoke_all('irc_msg_who', $data); } function invoke_irc_msg_join(&$irc, &$data) { module_invoke_all('irc_msg_join', $data); } function invoke_irc_msg_invite(&$irc, &$data) { module_invoke_all('irc_msg_invite', $data); } function invoke_irc_msg_action(&$irc, &$data) { module_invoke_all('irc_msg_action', $data); } function invoke_irc_msg_topicchange(&$irc, &$data) { module_invoke_all('irc_msg_topicchange', $data); } function invoke_irc_msg_nickchange(&$irc, &$data) { module_invoke_all('irc_msg_nickchange', $data); } function invoke_irc_msg_kick(&$irc, &$data) { module_invoke_all('irc_msg_kick', $data); } function invoke_irc_msg_quit(&$irc, &$data) { module_invoke_all('irc_msg_quit', $data); } function invoke_irc_msg_login(&$irc, &$data) { module_invoke_all('irc_msg_login', $data); } function invoke_irc_msg_info(&$irc, &$data) { module_invoke_all('irc_msg_info', $data); } function invoke_irc_msg_list(&$irc, &$data) { module_invoke_all('irc_msg_list', $data); } function invoke_irc_msg_name(&$irc, &$data) { module_invoke_all('irc_msg_name', $data); } function invoke_irc_msg_motd(&$irc, &$data) { module_invoke_all('irc_msg_motd', $data); } function invoke_irc_msg_modechange(&$irc, &$data) { module_invoke_all('irc_msg_modechange', $data); } function invoke_irc_msg_part(&$irc, &$data) { module_invoke_all('irc_msg_part', $data); } function invoke_irc_msg_error(&$irc, &$data) { module_invoke_all('irc_msg_error', $data); } function invoke_irc_msg_banlist(&$irc, &$data) { module_invoke_all('irc_msg_banlist', $data); } function invoke_irc_msg_topic(&$irc, &$data) { module_invoke_all('irc_msg_topic', $data); } function invoke_irc_msg_nonrelevant(&$irc, &$data) { module_invoke_all('irc_msg_nonrelevant', $data); } function invoke_irc_msg_whois(&$irc, &$data) { module_invoke_all('irc_msg_whois', $data); } function invoke_irc_msg_whowas(&$irc, &$data) { module_invoke_all('irc_msg_whowas', $data); } function invoke_irc_msg_usermode(&$irc, &$data) { module_invoke_all('irc_msg_usermode', $data); } function invoke_irc_msg_channelmode(&$irc, &$data) { module_invoke_all('irc_msg_channelmode', $data); } function invoke_irc_msg_ctcp_request(&$irc, &$data) { module_invoke_all('irc_msg_ctcp_request', $data); } function invoke_irc_msg_ctcp_reply(&$irc, &$data) { module_invoke_all('irc_msg_ctcp_reply', $data); } } Loading
CHANGELOG.txt +2 −0 Changes for CHANGELOG.txt: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ Bot 7.x-1.3, 2011-xx-xx ----------------------- * All incoming messages are forced to UTF-8 (thanks bellHead, nick_vh!). * #918966: Rewrote/moved Net_SmartIRC wrapper; hook_irc_access added. * All forgotten strlens()s have been changed to drupal_strlen(). * All forgotten substr()s have been changed to drupal_substr(). * First release for Drupal 7.x; based on 6.x-1.2 release. Loading
bot.smartirc.inc 0 → 100644 +103 −0 Changes for bot.smartirc.inc: 103 added lines, 0 removed lines. Original line number Diff line number Diff line <?php // $Id$ /** * @file * Classes and functions that wrap Drupal up for Net_SmartIRC. */ /** * A Drupal wrapper for the various Net_SmartIRC handlers. */ class bot_smartirc_wrapper { /** * Handle all Net_SmartIRC callbacks. * * @param &$irc * The Net_SmartIRC $irc object. * @param &$data * The Net_SmartIRC data object for this message. */ function invoke(&$irc, &$data = NULL) { if (isset($data)) { // Net_SmartIRC passes data through in the encoding received from the // IRC server. The IRC server, in turn, passes it through as received // from the remote client. If the remote client is using a single byte // encoding (ISO-8559-1 aka Latin-1), this will result in mangled // characters or may raise errors for 8-bit characters. Under Drupal 7 // and PHP 5.3, this caused an "invalid multibyte sequence" warning // from htmlspecialchars() and a PDOException that crashed the bot. // (To reproduce: use XChat to connect to a server as latin1, but then // send an 8-bit Latin-1 character like a Euro [€]). Since we cannot // control the encoding of IRC messages like we can control the encoding // of web form submissions, we need to force UTF-8 for all messages. if (function_exists('mb_detect_encoding')) { $encoding = mb_detect_encoding($data->message, 'UTF-8, ISO-8859-1'); if ($encoding != 'UTF-8') { // no point of converting it already. // we only convert over message related elements and leave the // existing parses (nick, ident, host, type, channel, etc.) alone. $data->message = mb_convert_encoding($data->message, 'UTF-8', $encoding); $data->rawmessage = mb_convert_encoding($data->rawmessage, 'UTF-8', $encoding); $data->messageex = explode(' ', $data->message); $data->rawmessageex = explode(' ', $data->rawmessage); watchdog('bot', 'Converted @encoding to UTF-8: @message.', array('@encoding' => $encoding, '@message' => $data->message), WATCHDOG_INFO); } } } // The name of the hook is a substring of the class name. $hook = drupal_substr(get_class($this), drupal_strlen('bot_')); // Give modules an opportunity to stop message processing. foreach (module_implements('irc_access') as $module) { $function = "{$module}_irc_access"; $result = $function($hook, $data); // Stop handling this request if FALSE. if (isset($result) && $result === FALSE) { return; } } // Proceed normally. module_invoke_all($hook, $data); } } // Bot cron sub-classes. class bot_irc_bot_cron extends bot_smartirc_wrapper {} class bot_irc_bot_cron_faster extends bot_smartirc_wrapper {} class bot_irc_bot_cron_fastest extends bot_smartirc_wrapper {} // IRC message sub-classes. class bot_irc_msg_unknown extends bot_smartirc_wrapper {} class bot_irc_msg_channel extends bot_smartirc_wrapper {} class bot_irc_msg_query extends bot_smartirc_wrapper {} class bot_irc_msg_ctcp extends bot_smartirc_wrapper {} class bot_irc_msg_notice extends bot_smartirc_wrapper {} class bot_irc_msg_who extends bot_smartirc_wrapper {} class bot_irc_msg_join extends bot_smartirc_wrapper {} class bot_irc_msg_invite extends bot_smartirc_wrapper {} class bot_irc_msg_action extends bot_smartirc_wrapper {} class bot_irc_msg_topicchange extends bot_smartirc_wrapper {} class bot_irc_msg_nickchange extends bot_smartirc_wrapper {} class bot_irc_msg_kick extends bot_smartirc_wrapper {} class bot_irc_msg_quit extends bot_smartirc_wrapper {} class bot_irc_msg_login extends bot_smartirc_wrapper {} class bot_irc_msg_info extends bot_smartirc_wrapper {} class bot_irc_msg_list extends bot_smartirc_wrapper {} class bot_irc_msg_name extends bot_smartirc_wrapper {} class bot_irc_msg_motd extends bot_smartirc_wrapper {} class bot_irc_msg_modechange extends bot_smartirc_wrapper {} class bot_irc_msg_part extends bot_smartirc_wrapper {} class bot_irc_msg_error extends bot_smartirc_wrapper {} class bot_irc_msg_banlist extends bot_smartirc_wrapper {} class bot_irc_msg_topic extends bot_smartirc_wrapper {} class bot_irc_msg_nonrelevant extends bot_smartirc_wrapper {} class bot_irc_msg_whois extends bot_smartirc_wrapper {} class bot_irc_msg_whowas extends bot_smartirc_wrapper {} class bot_irc_msg_usermode extends bot_smartirc_wrapper {} class bot_irc_msg_channelmode extends bot_smartirc_wrapper {} class bot_irc_msg_ctcp_request extends bot_smartirc_wrapper {} class bot_irc_msg_ctcp_reply extends bot_smartirc_wrapper {}
bot_start.php +10 −47 Changes for bot_start.php: 10 added lines, 47 removed lines. Original line number Diff line number Diff line Loading @@ -36,17 +36,17 @@ while ($param = array_shift($_SERVER['argv'])) { } } // load in our required libraries. require_once './includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); require_once('Net/SmartIRC.php'); // load in required libraries. require_once 'Net/SmartIRC.php'; require_once DRUPAL_ROOT . '/includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); // gotta bootstrap everything in before d_g_p. require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'bot') . '/bot.smartirc.inc'; // prevent MySQL timeouts on slow channels. db_query('SET SESSION wait_timeout = 86400'); // initialize the bot with some sane defaults. global $irc; // allow it to be slurped by Drupal modules if need be. $bot = new drupal_wrapper(); // wrapper that integrates with Drupal hooks. $irc = new Net_SmartIRC(); // MmmmmmM. The IRC object itself. Magick happens here. $irc->setDebug( variable_get('bot_debugging', 0) ? SMARTIRC_DEBUG_ALL : SMARTIRC_DEBUG_NONE ); // the (boolean) here is required, as Net_SmartIRC doesn't respect a FAPI checkbox value of 1, only TRUE. Loading @@ -67,14 +67,15 @@ $irc_message_types = array( ); foreach ($irc_message_types as $irc_message_type) { $irc->registerActionhandler(constant('SMARTIRC_TYPE_' . $irc_message_type), '.*', $bot, 'invoke_irc_msg_' . strtolower($irc_message_type)); $class = 'bot_irc_msg_' . drupal_strtolower($irc_message_type); $irc->registerActionhandler(constant('SMARTIRC_TYPE_' . $irc_message_type), '.*', new $class(), 'invoke'); } // set up a timers similar to Drupal's hook_cron(), multiple types. I would have // liked to just pass a parameter to a single function, but SmartIRC can't do that. $irc->registerTimehandler(300000, $bot, 'invoke_irc_bot_cron'); // 5 minutes. $irc->registerTimehandler(60000, $bot, 'invoke_irc_bot_cron_faster'); // 1 minute. $irc->registerTimehandler(15000, $bot, 'invoke_irc_bot_cron_fastest'); // 15 seconds. $irc->registerTimehandler(300000, new bot_irc_bot_cron(), 'invoke'); // 5 minutes. $irc->registerTimehandler(60000, new bot_irc_bot_cron_faster(), 'invoke'); // 1 minute. $irc->registerTimehandler(15000, new bot_irc_bot_cron_fastest(), 'invoke'); // 15 seconds. // connect and begin listening. $irc->connect(variable_get('bot_server', 'irc.freenode.net'), variable_get('bot_server_port', 6667)); Loading @@ -85,41 +86,3 @@ $irc->login(variable_get('bot_nickname', 'bot_module'), variable_get('bot_nickna $irc->listen(); // go into the forever loop - no code after this is run. $irc->disconnect(); // if we stop listening, disconnect properly. // pass off IRC messages to our modules via Drupal's hook system. class drupal_wrapper { function invoke_irc_bot_cron(&$irc) { module_invoke_all('irc_bot_cron'); } function invoke_irc_bot_cron_faster(&$irc) { module_invoke_all('irc_bot_cron_faster'); } function invoke_irc_bot_cron_fastest(&$irc) { module_invoke_all('irc_bot_cron_fastest'); } function invoke_irc_msg_unknown(&$irc, &$data) { module_invoke_all('irc_msg_unknown', $data); } function invoke_irc_msg_channel(&$irc, &$data) { module_invoke_all('irc_msg_channel', $data); } function invoke_irc_msg_query(&$irc, &$data) { module_invoke_all('irc_msg_query', $data); } function invoke_irc_msg_ctcp(&$irc, &$data) { module_invoke_all('irc_msg_ctcp', $data); } function invoke_irc_msg_notice(&$irc, &$data) { module_invoke_all('irc_msg_notice', $data); } function invoke_irc_msg_who(&$irc, &$data) { module_invoke_all('irc_msg_who', $data); } function invoke_irc_msg_join(&$irc, &$data) { module_invoke_all('irc_msg_join', $data); } function invoke_irc_msg_invite(&$irc, &$data) { module_invoke_all('irc_msg_invite', $data); } function invoke_irc_msg_action(&$irc, &$data) { module_invoke_all('irc_msg_action', $data); } function invoke_irc_msg_topicchange(&$irc, &$data) { module_invoke_all('irc_msg_topicchange', $data); } function invoke_irc_msg_nickchange(&$irc, &$data) { module_invoke_all('irc_msg_nickchange', $data); } function invoke_irc_msg_kick(&$irc, &$data) { module_invoke_all('irc_msg_kick', $data); } function invoke_irc_msg_quit(&$irc, &$data) { module_invoke_all('irc_msg_quit', $data); } function invoke_irc_msg_login(&$irc, &$data) { module_invoke_all('irc_msg_login', $data); } function invoke_irc_msg_info(&$irc, &$data) { module_invoke_all('irc_msg_info', $data); } function invoke_irc_msg_list(&$irc, &$data) { module_invoke_all('irc_msg_list', $data); } function invoke_irc_msg_name(&$irc, &$data) { module_invoke_all('irc_msg_name', $data); } function invoke_irc_msg_motd(&$irc, &$data) { module_invoke_all('irc_msg_motd', $data); } function invoke_irc_msg_modechange(&$irc, &$data) { module_invoke_all('irc_msg_modechange', $data); } function invoke_irc_msg_part(&$irc, &$data) { module_invoke_all('irc_msg_part', $data); } function invoke_irc_msg_error(&$irc, &$data) { module_invoke_all('irc_msg_error', $data); } function invoke_irc_msg_banlist(&$irc, &$data) { module_invoke_all('irc_msg_banlist', $data); } function invoke_irc_msg_topic(&$irc, &$data) { module_invoke_all('irc_msg_topic', $data); } function invoke_irc_msg_nonrelevant(&$irc, &$data) { module_invoke_all('irc_msg_nonrelevant', $data); } function invoke_irc_msg_whois(&$irc, &$data) { module_invoke_all('irc_msg_whois', $data); } function invoke_irc_msg_whowas(&$irc, &$data) { module_invoke_all('irc_msg_whowas', $data); } function invoke_irc_msg_usermode(&$irc, &$data) { module_invoke_all('irc_msg_usermode', $data); } function invoke_irc_msg_channelmode(&$irc, &$data) { module_invoke_all('irc_msg_channelmode', $data); } function invoke_irc_msg_ctcp_request(&$irc, &$data) { module_invoke_all('irc_msg_ctcp_request', $data); } function invoke_irc_msg_ctcp_reply(&$irc, &$data) { module_invoke_all('irc_msg_ctcp_reply', $data); } }