Archive

Posts Tagged ‘Scripting’

Status Press Widget

December 23rd, 2009 No comments

I’ve been playing around a bit with Status Press Widget by Brian D. Goad.

I found that the data it fetched also showed the nick-/username which I think is kinda redundant so I modified the plugin a bit to let me manage it from the admin interface. While at it I also modified so URL’s are made clickable and cleaned up the code a bit.

Here’s the modified status-press-widget.php file:

<?php
/*
Plugin Name: Status Press Widget
Plugin URI: http://www.briandgoad.com/blog/status-press-widget/
Description: Adds a Widget to display your Facebook/Twitter/Last.FM/Pownce status in your sidebar.
Version: 1.14
Author: Brian D. Goad
Author URI: http://www.briandgoad.com/blog
*/

/*
    Copyright 2008  Brian D. Goad  (email : bdgoad@gmail.com)
            & Adam Walker Cleaveland &  C. Scott Andreas,
            Authors of the original Status Press Plugin

    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
*/

if (!function_exists("htmlspecialchars_decode")) {
    function htmlspecialchars_decode($string,$style=ENT_COMPAT){
        $translation = array_flip(get_html_translation_table(HTML_SPECIALCHARS,$style));
        if ($style === ENT_QUOTES) {
            $translation['&#039;'] = '\'';
        }
        return strtr($string,$translation);
    }
}

class SPWidget {
    //Set Defaults
    var $default_options = array(
        'title' => "",
        'social' => "",
        'url' => "",
        'num' => "1",
        'status_mods' => "",
        'show_time' => 1,
        'time_mods' => ""
    );

    var $o;

    function SPWidget() {}

    //Begin By Checking to See if Widget Can Exist
    function init() {
        if (!function_exists('register_sidebar_widget')) {
            return;
        }
        if (!$options = get_option('widget_status_press')) {
            $options = array();
        }
        $widget_ops = array('classname' => 'widget_status_press', 'description' => 'Add a Social Status to your sidebar');
        $control_ops = array('width' => 200, 'height' => 350, 'id_base' => 'status_press');
        $name = 'Status Press';
        $registered = false;

        //Register Widgets
        foreach (array_keys($options) as $o) {
            if (!isset($options[$o]['title'])) {
                continue;
            }
            $id = "status_press-$o";
            $registered = true;
            wp_register_sidebar_widget($id, $name, array(&$this, 'widget'), $widget_ops, array( 'number' => $o ) );
            wp_register_widget_control($id, $name, array(&$this, 'control'), $control_ops, array( 'number' => $o ) );
        }
        if (!$registered) {
            wp_register_sidebar_widget('status_press-1', $name, array(&$this, 'widget'), $widget_ops, array( 'number' => -1 ) );
            wp_register_widget_control('status_press-1', $name, array(&$this, 'control'), $control_ops, array( 'number' => -1 ) );
        }
    }

    function widget($args, $widget_args = 1) {
        //Retrieve Any Arguments
        extract($args);

        if (is_numeric($widget_args)) {
            $widget_args = array('number' => $widget_args);
        }

        $widget_args = wp_parse_args($widget_args, array( 'number' => -1 ));
        extract($widget_args, EXTR_SKIP);

        //Get Options Saved in Control
        $options_all = get_option('widget_status_press');

        if (!isset($options_all[$number])) {
            return;
        }

        $this->o = $options_all[$number];
        //Set Temp Values (in case they have changed)
        $title = htmlspecialchars($this->o['title'], ENT_QUOTES);
        $url = $this->o['url'];
        $num = htmlspecialchars($this->o['num'], ENT_NOQUOTES);
        $status_mods = htmlspecialchars_decode($this->o['status_mods'], ENT_QUOTES);
        $show_time = $this->o['show_time'];
        $show_nick = $this->o['show_nick'];
        $time_mods = htmlspecialchars_decode($this->o['time_mods'], ENT_QUOTES);
        //Begin Status Press Functions

        require_once (ABSPATH . WPINC . '/rss.php');

        if ($url == '' ) {
            if ($title == '') {
                $title = 'Status Press';
            }
            $disp .= '<p>You Must Supply the URL to your Facebook Status RSS Feed </p>';
        } else {
            //Adjust cache setting
            if ( !defined('MAGPIE_CACHE_AGE') ) {
                define('MAGPIE_CACHE_AGE', 5*60); // five minutes
            }
            $rss = fetch_rss($url);
            if($rss) {
                if ($title == '') {
                    $title = $rss->channel[title];
                }
                if ($num > 0) {
                    $rss->items = array_slice($rss->items, 0, $num);
                }
                foreach($rss->items as $item) {
                    //Get Status Text
                    $status = $item[title];
                    if ($status != '') {
                        // Removes the nick in front of status text and makes any URL's into clickable links.
                        if (!$show_nick) {
                            $status = trim(substr($status, stripos($status, ':')+1));
                        }
                        $status = make_clickable($status);
                        $disp .= "\t<p " . $status_mods . ">" . $status;
                        if ($show_time) {
                            // Get the date + time of the last update from the RSS feed.
                            $pubdate = $item[pubdate];
                            // Convert this string to a time.
                            $pubdate = strtotime($pubdate);
                            // Calculate how long it's been since the status was updated.
                            $today = time();
                            $difference = $today - $pubdate;
                            // Display how long it's been since the last update.
                            $disp .= "</p><p ". $time_mods . ">(Updated ";
                            // Show days if it's been more than a day.
                            if (floor($difference / 86400) > 0) {
                                $disp .= floor($difference / 86400);
                                if (floor($difference / 86400) == 1) {
                                    $disp .= ' day, ';
                                } else {
                                    $disp .= ' days, ';
                                }
                                $difference -= 86400 * floor($difference / 86400);
                            }
                            // Show hours if it's been more than an hour.
                            if (floor($difference / 3600) > 0) {
                                $disp .= floor($difference / 3600);
                                if (floor($difference / 3600) == 1) {
                                    $disp .= ' hour, ';
                                } else {
                                    $disp .= ' hours, ';
                                }
                                $difference -= 3600 * floor($difference / 3600);
                            }
                            // Show minutes if it's been more than a minute.
                            $disp .= floor($difference / 60);
                            $difference -= 60 * floor($difference / 60);
                            if (floor($difference / 60) == 1) {
                                $disp .= ' minute, ';
                            } else {
                                $disp .= ' minutes ago)';
                            }
                        }
                        $disp .= "</p>\n";
                    }
                }
            } else {
                if ($title == '') {
                    $title = "Status Press";
                }
                $disp .= "\t<p>Status Press Error: Something bad happened! <br /> Here are the variables you entered: <ul><li> Title:".$title."</li><li>URL:".$url."</li><li>Number:".$num."</li><li>RSS: ".$rss."\t</li></ul></p>\n";
            }
        }
        //Call Widget
?>
                <?php echo $before_widget; ?>
                <?php echo $before_title . $title . $after_title; ?>

                <div>
                    <?php echo $disp; // Display Widget Content ?>
                </div>

                <?php echo $after_widget; ?>
<?php
    }
    function control($widget_args = 1) {
        global $wp_registered_widgets;
        static $updated = false;
        if (is_numeric($widget_args)) {
            $widget_args = array('number' => $widget_args);
        }
        $widget_args = wp_parse_args($widget_args, array('number' => -1));
        extract($widget_args, EXTR_SKIP);
        $options_all = get_option('widget_status_press');
        if (!is_array($options_all)) {
            $options_all = array();
        }
        if (!$updated && !empty($_POST['sidebar'])) {
            $sidebar = (string)$_POST['sidebar'];
            $sidebars_widgets = wp_get_sidebars_widgets();
            if (isset($sidebars_widgets[$sidebar])) {
                $this_sidebar =& $sidebars_widgets[$sidebar];
            } else {
                $this_sidebar = array();
            }
            foreach ($this_sidebar as $_widget_id) {
                if ('widget_status_press' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number'])) {
                    $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number'];
                    if (!in_array("status_press-$widget_number", $_POST['widget-id'])) {
                        unset($options_all[$widget_number]);
                    }
                }
            }
            foreach ((array)$_POST['status_press'] as $widget_number => $posted) {
                if (!isset($posted['title']) && isset($options_all[$widget_number])) {
                    continue;
                }
                $options = array();
                $options['title'] = strip_tags(stripslashes($posted['title']));
                $options['social'] = $posted['social'];
                $options['url'] = sanitize_url(strip_tags($posted['url']));
                $options['show_nick'] = $posted['show_nick'];
                $options['num'] = intval($posted['num']);
                $options['status_mods'] = strip_tags(stripslashes($posted['status_mods']));
                $options['show_time'] = isset($posted['show_time']);
                $options['time_mods'] = strip_tags(stripslashes($posted['time_mods']));
                $options_all[$widget_number] = $options;
            }
            update_option('widget_status_press', $options_all);
            $updated = true;
        }
        if (-1 == $number) {
            $wpnm = '%i%';
            $values = $this->default_options;
        } else {
            update_option('widget_status_press', $options_all);
            $wpnm = $number;
            $values = $options_all[$number];
        }

        //Show Admin Screen
?>
        <p style="text-align:left;">
            <label for="status_press-title"><?php _e('Title (Leave Blank to Pull Title From Feed):', 'status-press-widget'); ?></label><br />
            <input style="width: 200px;" id="status_press-title" name="status_press[<?php echo $wpnm; ?>][title]" type="text" value="<?php echo htmlspecialchars($values['title'], ENT_QUOTES); ?>" />
        </p>
        <script language="javascript">
            function rss(social) {
                actSocial = social.value;
                var txtUrl = document.getElementById("status_press-url[<?php echo $wpnm; ?>]")
                function getUserName(actSocial) {
                    do {
                        var name = prompt("Please input your " + actSocial + " username here:", "");
                    } while (name == "");
                    if (name!=null && name!="") {
                        return name;
                    } else {
                        social.selectedIndex = 0;
                    }
                }
                switch (actSocial) {
                    case "Facebook":
                        okFB = confirm('Please ensure that you are already logged in to Facebook.');
                        if (okFB) {
                            alert('On the following page, please find the My Status RSS feed and copy it into the box below.');
                            window.open("http://www.facebook.com/minifeed.php?filter=11");
                        }
                    break;
                    case "Twitter":
                        name = getUserName(actSocial);
                        if (name != null) {
                            txtUrl.value = "http://twitter.com/statuses/user_timeline/" + name + ".rss";
                        }
                    break;
                    case "Last.FM":
                        name = getUserName(actSocial);
                        if (name != null) {
                            txtUrl.value = "http://ws.audioscrobbler.com/1.0/user/" + name + "/recenttracks.rss";
                        }
                    break;
                }
            }
            function showHide(that, element) {
                e = document.getElementById(element);
                if (that.checked) {
                    e.style.visibility = "visible";
                } else {
                    e.style.visibility = "hidden";
                }
            }
            //showHide(document.getElementById("status_press-show_time[<? echo $wpnm; ?>]"), "status_press-time_mods[<? echo $wpnm; ?>]");
        </script>

        <p style="text-align:left;">
            <span style="vertical-align: bottom;"><?php _e('Social Status Network:  ', 'status-press-widget'); ?></span>
            <select name="status_press[<?php echo $wpnm; ?>][social]" id="status_press-social" onchange="rss(this)">
                <option value=""<?php if($values['social'] == '') echo ' selected="selected"'; ?>></option>
                <option value="Facebook"<?php if($values['social'] == "Facebook") echo ' selected="selected"'; ?>><?php _e('Facebook', 'status-press-widget'); ?></option>
                <option value="Twitter"<?php if($values['social'] == "Twitter") echo ' selected="selected"'; ?>><?php _e('Twitter', 'status-press-widget'); ?></option>
                <option value="Last.FM"<?php if($values['social'] == "Last.FM") echo ' selected="selected"'; ?>><?php _e('Last.FM', 'status-press-widget'); ?></option>
            </select>
        </p>
        <p>
            <label for="status_press-url[<?php echo $wpnm; ?>]"><?php _e('Status URL Feed:', 'status-press-widget'); ?></label><br />
            <input style="width: 230px;" id="status_press-url[<?php echo $wpnm; ?>]" name="status_press[<?php echo $wpnm; ?>][url]" type="text" value="<?php echo $values['url']; ?>" />
        </p>
        <p><?php if($values['show_nick']) $values['show_nick'] = ' checked="checked"';?>
            <label for="status_press-show_nick"><?php _e( 'Show nick-/username: ', 'status-press-widget'); ?></label>
            <input type="checkbox" class="checkbox" id="status_press-show_nick[<?php echo $wpnm; ?>]" name="status_press[<?php echo $wpnm; ?>][show_nick]"<?php echo $values['show_nick']; ?> />
        </p>
        <p style="text-align:left;">
            <label for="status_press-num"><?php _e('Number of Status Feeds to Display <br/>(Use "0" to display All):', 'status-press-widget'); ?></label><br />
            <input style="width: 20px;" id="status_press-num" name="status_press[<?php echo $wpnm; ?>][num]" type="text" value="<?php echo htmlspecialchars($values['num'], ENT_NOQUOTES); ?>" />
        </p>
        <p style="text-align:left;">
            <label for="status_press-status_mods"><?php _e('Stylizing Modifications for Status Tags<br/>(i.e. id="status_press", etc):', 'status-press-widget'); ?></label><br />
            <input style="width: 230px;" id="status_press-status_mods" name="status_press[<?php echo $wpnm; ?>][status_mods]" type="text" value="<?php echo htmlspecialchars($values['status_mods'], ENT_QUOTES); ?>" />
        </p>
        <p><?php if($values['show_time']) $values['show_time'] = ' checked="checked"'; ?>
            <label for="status_press-show_time"><?php _e( 'Show Time Since Status Update: ', 'status-press-widget'); ?></label>
            <input type="checkbox" class="checkbox" id="status_press-show_time[<?php echo $wpnm; ?>]" name="status_press[<?php echo $wpnm; ?>][show_time]" onClick="showHide(this, \'status_press-time_mods[<?php echo $wpnm; ?>]\')"<?php echo $values['show_time']; ?> />
        </p>
        <p style="text-align:left;" id="status_press-time_mods[<?php echo $wpnm; ?>]">
            <label for="status_press-time_mods[<?php echo $wpnm; ?>]"><?php _e('Stylizing Modifications for Time Since Tags <br/>(i.e. id="status-time", etc):', 'status-press-widget'); ?></label><br />
            <input style="width: 230px;" id="status_press-time_mods[<?php echo $wpnm; ?>]" name="status_press[<?php echo $wpnm; ?>][time_mods]" type="text" value="<?php echo htmlspecialchars($values['time_mods'], ENT_QUOTES); ?>" />
        </p>
        <input type="hidden" id="status_press-submit" name="status_press[<?php echo $wpnm; ?>][submit]" value="1" />
<?php
    }
}
$spw = new SPWidget();
//Initialize Widget on Run
add_action('widgets_init', array($spw, 'init'));

?>
Categories: Blog, PHP Tags: , , ,

mirc.php for GeSHi

December 12th, 2007 1 comment

Seems there were a minor issue with the mirc.php file from GeSHi causing all code entries set to be parsed as mIRC scripts to stop with an error. Fixed (or rather made a dirty hack) it so my mIRC scripts once again could be highlighted :)

<?php
/*************************************************************************************
* mirc.php
* -----
* Author: Alberto 'Birckin' de Areba (Birckin@hotmail.com)
* Copyright: (c) 2006 Alberto de Areba
* Release Version: 1.0.7.20
* Date Started: 2006/05/29
*
* mIRC Scripting language file for GeSHi.
*
* CHANGES
* -------
* 2006/05/29 (1.0.0)
*   -  First Release
*
* 2007/12/12 (1.0.1) - Brian Schmidt Pedersen
*   -  Removed the forward slash from all mIRC keywords, since in actual
*       mIRC scripts, they're often written without the slash.
*   -  Entry 6 (timer parsing) under REGEXPS caused GeSHi to halt with an error
*       simple solution was to remove the slash(es)
*
*************************************************************************************
*
*     This file is part of GeSHi.
*
*   GeSHi 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.
*
*   GeSHi 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 GeSHi; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
************************************************************************************/


$language_data = array (
    'LANG_NAME' => 'mIRC Scripting',
    'COMMENT_SINGLE' => array(
        1 => ';'
    ),
    'COMMENT_MULTI' => array(),
    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
    'QUOTEMARKS' => array(),
    'ESCAPE_CHAR' => '',
    'KEYWORDS' => array(
        1 => array(
            'alias', 'menu', 'dialog'
        ),
        2 => array(
            'if', 'elseif', 'else', 'while', 'return', 'goto'
        ),
        3 => array(
            'action', 'ajinvite', 'alias', 'aline', 'amsg', 'ame', 'anick',
            'aop','auser', 'avoice', 'auto', 'autojoin', 'away', 'background',
            'ban', 'beep', 'channel', 'clear', 'clearall', 'clipboard',
            'close', 'closemsg', 'color', 'copy', 'creq', 'ctcp', 'ctcpreply',
            'ctcps', 'dcc', 'dde', 'ddeserver', 'debug', 'describe', 'disable',
            'disconnect', 'dlevel', 'dll', 'dns', 'dqwindow', 'ebeeps', 'echo',
            'editbox', 'emailaddr', 'enable', 'events', 'exit', 'filter',
            'findtext', 'finger', 'flash', 'flood', 'flush', 'flushini',
            'font', 'fsend', 'fserve', 'fullname', 'ghide', 'gload', 'gmove',
            'gopts', 'gplay', 'gpoint', 'gqreq', 'groups', 'gshow', 'gsize',
            'gstop', 'gtalk', 'gunload', 'guser', 'halt', 'haltdef', 'help',
            'hop', 'ignore', 'inc', 'invite', 'join', 'kick', 'linesep',
            'links', 'list', 'load', 'loadbuf', 'localinfo', 'log', 'me',
            'mdi', 'mkdir', 'mnick', 'mode', 'msg', 'names', 'nick', 'noop',
            'notice', 'notify', 'omsg', 'onotice', 'part', 'partall', 'pdcc',
            'perform', 'ping', 'play', 'pop', 'protect', 'pvoice', 'qmsg',
            'qme', 'query', 'queryrn', 'quit', 'raw', 'remini', 'remote',
            'remove', 'rename', 'renwin', 'resetidle', 'rlevel', 'rmdir',
            'run', 'ruser', 'save', 'savebuf', 'save', 'saveini', 'say',
            'server', 'set', 'showmirc', 'sline', 'sound', 'speak', 'splay',
            'sreq', 'strip', 'time', 'timers', 'timestamp', 'titlebar',
            'tnick', 'tokenize', 'topic', 'ulist', 'unload', 'updatenl', 'url',
            'uwho', 'var', 'window', 'winhelp', 'write', 'writeini', 'who',
            'whois', 'whowas'
        )
    ),
    'SYMBOLS' => array(
        '(', ')', '{', '}', '[', ']', '|'
    ),
    'CASE_SENSITIVE' => array(
        GESHI_COMMENTS => true,
        1 => false,
        2 => false
    ),
    'STYLES' => array(
        'KEYWORDS' => array(
            1 => 'color: #994444;',
            2 => 'color: #000000; font-weight: bold;',
            3 => 'color: #990000; font-weight: bold;'
        ),
        'COMMENTS' => array(
            1 => 'color: #808080; font-style: italic;'
        ),
        'ESCAPE_CHAR' => array(),
        'BRACKETS' => array(
            0 => 'color: #FF0000;'
        ),
        'STRINGS' => array(),
        'NUMBERS' => array(
            0 => ''
        ),
        'METHODS' => array(),
        'SYMBOLS' => array(
            0 => 'color: #FF0000;'
        ),
        'REGEXPS' => array(
            0 => 'color: #000099;',
            1 => 'color: #990000;',
            2 => 'color: #888800;',
            3 => 'color: #888800;',
            4 => 'color: #000099;',
            5 => 'color: #000099;',
            6 => 'color: #990000; font-weight: bold;'
        ),
        'SCRIPT' => array()
    ),
    'URLS' => array(
        1 => '',
        2 => '',
        3 => '',
        4 => ''
    ),
    'OOLANG' => false,
    'OBJECT_SPLITTERS' => array(),
    'REGEXPS' => array(
        0 => '\$[^$][^ ,\(\)]*',
        1 => '(%|&).+?[^ ,\)]*',
        2 => '(#|@).+?[^ ,\)]*',
        3 => '-[a-z\d]+',
        4 => '(on|ctcp) (!|@|&)?(\d|\*):[a-zA-Z]+:',
        /*
        4 => array(
        GESHI_SEARCH => '((on|ctcp) (!|@|&)?(\d|\*):(Action|Active|Agent|AppActive|Ban|Chat|Close|Connect|Ctcp|CtcpReply|DccServer|DeHelp|DeOp|DeVoice|Dialog|Dns|Error|Exit|FileRcvd|FileSent|GetFail|Help|Hotlink|Input|Invite|Join|KeyDown|KeyUp|Kick|Load|Logon|MidiEnd|Mode|Mp3End|Nick|NoSound|Notice|Notify|Op|Open|Part|Ping|Pong|PlayEnd|Quit|Raw|RawMode|SendFail|Serv|ServerMode|ServerOp|Signal|Snotice|Start|Text|Topic|UnBan|Unload|Unotify|User|Mode|Voice|Wallops|WaveEnd):)',
        GESHI_REPLACE => '\\1',
        GESHI_MODIFIERS => 'i',
        GESHI_BEFORE => '',
        GESHI_AFTER => ''
        ),
        */

        5 => 'raw (\d|\*):',
        6 => 'timer(?!s\b)[0-9a-zA-Z_]+'
    ),
    'STRICT_MODE_APPLIES' => GESHI_NEVER,
    'SCRIPT_DELIMITERS' => array(),
    'HIGHLIGHT_STRICT_BLOCK' => array()
);
?>
Categories: Code, mIRC, PHP Tags: , , , ,

calc.tcl

#### calc.tcl v1.0.1 ###########################################################
################################################################################
## Written by:                                                                ##
##   KuNgFo0  (http://www.eggfaq.com/).              ##
##                                                                            ##
## Modified by:                                                               ##
##   Brian Schmidt aka. brianMan.                                             ##
################################################################################

#### Readme / Help #############################################################
################################################################################
## This script is ripped from KuNgFoO's ib.tcl v3.19 (infobot) script.        ##
##                                                                            ##
## Script that can calculate just about anything ;)                           ##
##                                                                            ##
## Usage:                                                                     ##
##   To have the .calc[ulate] commands available on a channel you need to set ##
##   the channel flag +calculator from the console/partyline .                ##
##   ``.chanset #channel +calculator´´                                        ##
##                                                                            ##
## Channel Commands (available only if channel is +convert):                  ##
##   .calc[ulate]                                                 ##
## Example:                                                                   ##
##   ``.calc 15*20+3´´                                                        ##
################################################################################

#### Changelog #################################################################
################################################################################
## v1.0.1                                                                     ##
## * Minor code cleanup                                                       ##
##                                                                            ##
## v1.0.0                                                                     ##
## + Initial release.                                                         ##
## * Changed the default trigger ``botname, calc[ulate]´´ to ``.calc[ulate]´´ ##
## + Added the possibility to control which channels could use the commands   ##
##   with the channel flag ``+/-calculator´´                                  ##
################################################################################

bind pub - .calc pub_calc
bind pub - .calculate pub_calc
bind msg - calc msg_calc
bind msg - calculate msg_calc

setudef flag calculator

# You shouldn't change these, however you may add additional variables
# These are used via %varname in the 'calculate' command
# Example: Mybot, calculate %pi / 2
set calc_const(pi) 3.14159265358979323846 ; # PI
set calc_const(e)  2.7182818284590452354  ; # E
set calc_const(n)  6.0221367e23           ; # Avogadro's number [1/mol]
set calc_const(R)  8.314510               ; # Universal gas constant [J/(mol*K)]
set calc_const(k)  1.380658e-23           ; # Boltzmann's constant [J/K]
set calc_const(G)  6.67259e-11            ; # Universal gravitational constant [N*m^2/kg^2]
set calc_const(h)  6.62606891e-34         ; # Planck's constant [J*s]
set calc_const(c)  2.99792458e8           ; # Speed of light [m/s]

# No more editing required

proc xrange {xr xr1 xr2} {
    return [join [lrange [split $xr] $xr1 $xr2]]
}

proc xindex {xr xr1} {
    return [join [lrange [split $xr] $xr1 $xr1]]
}

proc calc_fixdata {arg output} {
    global botnick
    if {[string index $output 0] != "#"} {
        regsub -all -nocase {$output's} $arg "your" arg
    }
    regsub -all -nocase {$botnick'
s} $arg "my" arg
    return $arg
}

proc calc_msg {targets arg} {
    foreach target $targets { puthelp "PRIVMSG $target :[calc_fixdata $arg $target]" }
}

proc calc_fixtopic {arg} {
    regsub -all {[\\\{\}\[\]\"]} $arg {}   arg ; # Bad characters
    regsub -all {(\s)+}          $arg {\1} arg ; # Double whitespace
    regsub -all {^\s*|\s*$}      $arg {}   arg ; # Whitespace at ends
    return $arg
}

# Begin 'calc' code
proc calc_fixexpr {exp} {
    global calc_const
    set exp [calc_fixtopic $exp]
    foreach i [array names calc_const] {
        regsub -all "
\%$i" $exp $calc_const($i) exp
    }
    return $exp
}
# End 'calc' code

# Begin Public binds code
proc msg_calc {nick uhost hand arg} {
    global botnick
    pub_calc $nick $uhost $hand "
" $arg
}

proc pub_calc {nick uhost hand chan arg} {
    global botnick calc_flag
    if {(![isbotnick $nick]) && (![matchattr $hand +b])} {
        if {(![string match "
$chan" ""]) && (![channel get $chan calculator])} {
            return 0 ; # If command comes from a channel, and that channel doesn't have +calculator then ignore
        }
        set isuser [expr {[matchattr $hand - $chan] || [matchattr $hand -]}] ; # Note that $chan might be "
", so we must handle both cases
        if {([validchan $chan]) && ($isuser)} {
            set output1 $chan ; # The bot sends the text to the channel for users
        } else {
            set output1 $nick ; # Non-users get privmsg'd
        }
        if {[set i [string last "
>" $arg]] == -1} {
            set output2 $output1 ; # By default, output2 (~stdout~) goes to output1 (~stderr~)
        } else {
            # Output has been redirected
            if {(!$isuser) || ([set output2 [string trim [string range $arg [expr $i + 1] end] "
"]] == "")} {
                set output2 $output1 ; # Error (User doesn't have access, or output was "
"), so we go back to the default
            }
            set arg [string trim [string range $arg 0 [expr $i - 1]] "
"]
        }
        set remainder [xrange $arg 0 end]

        if {$remainder == "
"} {
            calc_msg $output1 "
error parsing sentence"
        } elseif {[catch {expr [calc_fixexpr $remainder]} output]} {
            calc_msg $output1 "
error calculating '$remainder' ($output)"
        } else {
            calc_msg $output2 "
$remainder = $output"
        }
    }
}
# End Public binds code

# Init stuff
if {[catch {package require Tcl 8.2} error]} {
    putlog "
error TCL v8.2 or higher is required to run this script"
    return 0
}

putlog "
*** LOADED: calc.tcl"
Categories: Code, TCL Tags: , , , ,

convert.tcl

#### convert.tcl v1.0.1 ########################################################
################################################################################
## Written by:                                                                ##
##   KuNgFo0  (http://www.eggfaq.com/).              ##
##                                                                            ##
## Modified by:                                                               ##
##   Brian Schmidt aka. brianMan.                                             ##
################################################################################

#### Readme / Help #############################################################
################################################################################
## This script is ripped from KuNgFoO's ib.tcl v3.19 (infobot) script.        ##
##                                                                            ##
## The script converts between a number of various units, for more speficic   ##
## information on which untis you should please refer to the source of this   ##
## script.                                                                    ##
##                                                                            ##
## Usage:                                                                     ##
##   To have the .conv[ert] commands available on a channel you need to set   ##
##   the channel flag +convert from the console/partyline .                   ##
##   ``.chanset #channel +convert´´                                           ##
##                                                                            ##
## Channel Commands (available only if channel is +convert):                  ##
##   .conv[ert]   to                               ##
## Example:                                                                   ##
##   ``.conv 20 C to F´´                                                      ##
##   Converts 20 degrees Celcius to it's Fahrenheit equivilant.               ##
################################################################################

#### Changelog #################################################################
################################################################################
## v1.0.1                                                                     ##
## * Minor code cleanup                                                       ##
##                                                                            ##
## v1.0.0                                                                     ##
## + Initial release.                                                         ##
## * Changed the default trigger ``botname, conv[ert]´´ to ``.con[vert]´´     ##
## + Added the possibility to control which channels could use the commands   ##
##   with the channel flag ``+/-convert´´                                     ##
################################################################################

bind pub - .conv pub_conv
bind pub - .convert pub_conv
bind msg - conv msg_conv
bind msg - convert msg_conv

# Set the name of the channelflag used to tell whether the convert command is
# enabled or not for that specific channel.
set conv_channel_flag "convert"

setudef flag $conv_channel_flag

# Set the next line as the exec command to run the 'units' command from the shell
# Note: Not all systems will have this installed
# Set to "" to disable
set conv_units_exec "units -v"

# Conversion formulas - each array is for its own dimension (length, volume, etc).
# Each unit is converted to a standard type by multiplying the value by the factors
# below.  It is then converted from the standard type to any other unit by
# dividing the factors.  The standard unit used must be the same for everything in
# each dimension, and can be anything as long as they are the same.  I used the root
# metric units for most things (meters, liters, grams, etc).
# Note: All strings are matched as regular expressions
# * Prefix with (?c) for units that should be case sensitive
# * Prefix with (.*?) for metric units
# * Append (?:s) for units with an optional plural ending, etc
# * Only use multiplication and division in the formulas, no addition or subtraction
# * It's a very good idea to have all the formulas return values in decimal form
#   ("1" doesn't matter, though)
# Syntax:
#  name abbreviation factor
set conv_unit(length) {
    (.*?)meter(?:s)? (.*?)m 1
    inch(?:es)?      in     {2.54 / 100}
    foot|feet        ft     {2.54 / 100 * 12}
    mile(?:s)?       mi     {2.54 / 100 * 12 * 5280}
}
set conv_unit(volume) {
    (.*?)liter(?:s)? (.*?)L 1
    pint(?:s)?       pt     {3.785 / 8}
    quart(?:s)?      qt     {3.785 / 4}
    gallon(?:s)?     gal    3.785
}
set conv_unit(weight) {
    (.*?)gram(?:s)? (.*?)g 1
    ounce(?:s)?     oz     28.35
    pound(?:s)?     lbs    453.59
    ton(?:s)?       T      {453.59 * 2000}
}
set conv_unit(work) {
    (.*?)joule(?:s)?         (.*?)J      1
    (.*?)watt-?second(?:s)?  (.*?)w-?s   1
    (.*?)watt-?hour(?:s)?    (.*?)w-?hrs 3600.0
    britishthermalunit(?:s)? btu         1055.056
    calorie(?:s)?            cal         4.1868
    foot-?pound(?:s)?        ft-?lbs     1.356
    electron-?volt(?:s)?     eV          1.6021917E-19
}
set conv_unit(power) {
    (.*?)watt(?:s)? (.*?)w 1
    volt-?amp(?:s)? va     1
    horsepower      hp     746
}
set conv_unit(time) {
    (.*?)second(?:s)? (.*?)s(?:ec(?:s)?)? 1
    minute(?:s)?      min(?:s)?           60.0
    hour(?:s)?        h(?:r(?:s)?)?       {60.0 * 60}
    day(?:s)?         {}                  {60.0 * 60 * 24}
    week(?:s)?        wk(?:s)?            {60.0 * 60 * 24 * 7}
    year(?:s)?        yr(?:s)?            {60.0 * 60 * 24 * 365}
    decade(?:s)?      {}                  {60.0 * 60 * 24 * 365 * 10}
    century|centuries {}                  {60.0 * 60 * 24 * 365 * 100}
}
set conv_unit(binary) {
    option metric 2
    (.*?)byte(?:s)? (.*?)b 1
    (.*?)bit(?:s)?  {}     {1.0 / 8}
}

# Misc conversion formulas - these are types that cannot
# be converted by regular multiplication/division of factors.
# The principle is the same as the formulas above, however
# the arrays are broken down into *_from and *_to variables.
# Note: $value is used as the value being converted.
set conv_misc_from(num) {
    option metric 0
    integer|int              {} {[scan $value "%d"]}
    long                     {} {[scan $value "%u"]}
    decimal|dec|float|double {} {[scan $value "%f"]}
    octal|oct                {} {[scan $value "%o"]}
    hexadecimal|hex          {} {[scan $value "%x"]}
    binary|bin               {} {[bin2int $value]}
    ip                       {} {[ip2long $value]}
    rgb                      {} {[rgb2int $value]}
}
set conv_misc_to(num) {
    option metric 0
    integer|int              {} {[format "%d" [conv_int $value]]}
    long                     {} {[format "%u" [conv_int $value]]}
    decimal|dec|float|double {} {[format "%f" $value]}
    octal|oct                {} {[format "%o" [conv_int $value]]}
    hexadecimal|hex          {} {[format "%X" [conv_int $value]]}
    binary|bin               {} {[int2bin [conv_int $value]]}
    ip                       {} {[long2ip [conv_int $value]]}
    rgb                      {} {[int2rgb [conv_int $value]]}
}
set conv_misc_from(temperature) {
    option metric 0
    fahrenheit         F {($value - 32) * 5 / 9.0}
    kelvin             K {$value - 273.15}
    celsius|centigrade C {$value}
}
set conv_misc_to(temperature) {
    option metric 0
    fahrenheit         F {(9 / 5.0 * $value) + 32}
    kelvin             K {$value + 273.15}
    celsius|centigrade C {$value}
}

# Conversion strings to specificially ignore (that conflict with expr)
set conv_ignore {
    e abs acos asin
    atan atan2 ceil
    cos cosh double
    exp floor fmod
    hypot int log
    log10 pow rand
    round sin sinh
    sqrt srand tan
    tanh
}

# Metric conversion factors
# Note: Abbreviations are case sensitive here
# Syntax:
#  mame abbreviation factor
set conv_metric {
    Yotta Y  24
    Zetta Z  21
    Exa   E  18
    Peta  P  15
    Tera  T  12
    Giga  G  9
    Mega  M  6
    Kilo  k  3
    Hecto h  2
    Deca  dk 1

    Deci  d  -1
    Centi c  -2
    Milli m  -3
    Micro µ  -6
    Nano  n  -9
    Pico  p  -12
    Femto f  -15
    Atto  a  -18
    Zepto z  -21
    Yocto y  -24
}

proc xrange {xr xr1 xr2} {
    return [join [lrange [split $xr] $xr1 $xr2]]
}

proc anymatch {string1 string2} {
    foreach string $string2 {
        if {[lsearch -exact [string tolower $string1] [string tolower $string]] != -1} {
            return 1
        }
    }
    return 0
}

proc conv_fixtopic {arg} {
    regsub -all {[\\\{\}\[\]\"]} $arg {}   arg ; # Bad characters
    regsub -all {(\s)+}          $arg {\1} arg ; # Double whitespace
    regsub -all {^\s*|\s*$}      $arg {}   arg ; # Whitespace at ends
    return $arg
}

proc conv_fixdata {arg output} {
    global botnick
    if {[string index $output 0] != "
#"} {
        regsub -all -nocase {$output's} $arg "your" arg
    }
    regsub -all -nocase {$botnick'
s} $arg "my" arg
    return $arg
}

proc conv_msg {targets arg} {
    foreach target $targets {
        puthelp "PRIVMSG $target :[conv_fixdata $arg $target]"
    }
}

proc conv_fixexpr {exp} {
    global ib_const
    set exp [conv_fixtopic $exp]
    foreach i [array names ib_const] {
        regsub -all "\%$i" $exp $ib_const($i) exp
    }
    return $exp
}

# Begin conversion code
proc int2bin {int} {
    return [format "%s.%s.%s.%s" \
    [byte2bin [expr ($int >> 24) & 0xff]] \
    [byte2bin [expr ($int >> 16) & 0xff]] \
    [byte2bin [expr ($int >> 8)  & 0xff]] \
    [byte2bin [expr $int         & 0xff]]]
}

proc byte2bin {byte} {
    set result ""
    for {set i 0} {$i < 8} {incr i} {
        append result [expr ($byte & 128) >> 7]
        set byte [expr $byte << 1]
    }
    return $result
}

proc bin2int {bin} {
    set result 0
    for {set i 0} {$i < [string length $bin]} {incr i} {
        if {([set digit [string index $bin $i]] == 0) || ($digit == 1)} {
            set result [expr $result << 1 | $digit]
        } elseif {$digit == "."} {
            #ignore
        } else {
            set result ""
        }
    }
    return $result
}

proc ip2long {ip} {
    if {[scan $ip "%d.%d.%d.%d" a b c d] == 4} {
        foreach i "$a $b $c $d" {
            if {($i > 255) || ($i < 0)} {
                return ""
            }
        }
        set long [expr $a << 24 | $b << 16 | $c << 8 | $d]
        if {$long < 0} {
            set long [expr pow(2, 32) + $long]
        }
        return $long
    } else {
        return ""
    }
}

proc long2ip {long} {
    return [format "%d.%d.%d.%d" \
    [expr ($long >> 24) & 0xff] \
    [expr ($long >> 16) & 0xff] \
    [expr ($long >> 8)  & 0xff] \
    [expr $long         & 0xff]]
}

proc rgb2int {rgb} {
    if {[scan $rgb "%d.%d.%d" red green blue] == 3} { return [expr $red << 16 | $green << 8 | $blue << 0] } \
    else { return "" }
}

proc int2rgb {long} {
    return [format "%d.%d.%d" \
    [expr ($long >> 16) & 0xff] \
    [expr ($long >> 8)  & 0xff] \
    [expr $long         & 0xff]]
}

# expr's abs() and int() can't handle large unsigned integers,
# these functions are just to get around this
proc conv_int {value} {
    return [lindex [split $value "."] 0]
}

proc conv_abs {value} {
    return [string trimleft $value "-"]
}

proc conv_absint {value} {
    return [conv_int [conv_abs $value]]
}

proc conv_units {value type1 type2} {
    global conv_units_exec
    regsub -all {'} [conv_fixtopic $type1] {} type1
    regsub -all {'
} [conv_fixtopic $type2] {} type2
    if {[catch {exec bash -c "$conv_units_exec '$value $type1' '$type2'"} output]} {
        error $output
    }
    foreach line [split $output \n] {
        if {[regexp -- {^\s*([^=]+=.+)$} $line tmp result]} {
            return $result
        }
    }
    error "unknown response from units command"
}

proc conv_scan {var_formula var_unit index} {
    global conv_ignore conv_unit
    upvar 1 $var_formula formula $var_unit unit
    set string {([a-z]+(-[a-z]+)?)}
    if {[regexp -nocase -start $index -- $string $formula a unit]} {
        if {[lsearch -exact $conv_ignore $unit] != -1} {
            # Ignore this unit and search for the next unit
            regexp -nocase -start $index -indices $string -- $formula a index
            return [conv_scan "formula" "unit" [expr [lindex $index 1] + 1]]
        } else {
            # Found unit, return ok
            return 1
        }
    }
    # No more units found
    return 0
}

# $var will be either unit, misc_from, or misc_to
proc conv {value unit var lists} {
    global conv_$var
    upvar 1 list uplist
    if {![info exists uplist]} {
        set uplist ""
    }
    set type [expr {($var == "unit") || ($var == "misc_from") ? "*" : "/"}]
    # First we check full names, then abbreviations
    foreach method {name abbv} {
        foreach list $lists {
            # Default options
            set option_absint 0
            set option_metric 1
            foreach {name abbv formula} [set conv_$var\($list)] {
                if {$name == "option"} {
                    set option_$abbv $formula
                } elseif {[regexp -nocase -- "^([set $method])\$" $unit a b prefix]} {
                    set uplist $list
                    if {([catch {expr $formula} value]) || ($value == "")} {
                        error "evaluating expression for '$unit'"
                    }
                    if {$option_absint} {
                        set value [conv_absint $value]
                    }
                    if {($option_metric) && ($prefix != "") && ([catch {expr [conv_metric $prefix $method $option_metric] $type $value} value])} {
                        error "evaluating metric conversion for '$unit'"
                    }
                    return $value
                }
            }
        }
    }
    error "unknown conversion type '$unit'"
}

# $method will be either "name" or "abbv"
# $option will be either 1 or 2
proc conv_metric {prefix method option} {
    global conv_metric
    foreach {name abbv factor} $conv_metric {
        if {(($method == "name") && ([string equal -nocase $name $prefix])) || (($method == "abbv") && ([string equal $abbv $prefix]))} {
            if {$option == 1} {
                return [expr pow(10, $factor)] ; # Regular metric
            } elseif {$option == 2} {
                return [expr pow(2, ($factor / 3 * 10))] ; # Binary conversion
            }
        }
    }
    error "unknown metric prefix"
}
# End conversion code

# Begin Public binds code
proc msg_conv {nick uhost hand arg} {
    global botnick
    pub_conv $nick $uhost $hand "" $arg
}

proc pub_conv {nick uhost hand chan arg} {
    global botnick value global conv_channel_flag
    global conv_units_exec conv_unit conv_misc_from conv_misc_to
    if {(![isbotnick $nick]) && (![matchattr $hand +b])} {
        if {(![string match "$chan" ""]) && (![channel get $chan $conv_channel_flag])} {
            return 0 ; # If command comes from a channel, and that channel doesn't have +convert then ignore
        }
        set isuser [expr {[matchattr $hand - $chan] || [matchattr $hand -]}] ; # Note that $chan might be "", so we must handle both cases
        if {([validchan $chan]) && ($isuser)} {
            set output1 $chan ; # The bot sends the text to the channel for users
        } else {
            set output1 $nick ; # Non-users get privmsg'd
        }
        if {[set i [string last ">" $arg]] == -1} {
            set output2 $output1 ; # By default, output2 (~stdout~) goes to output1 (~stderr~)
        } else {
            # Output has been redirected
            if {(!$isuser) || ([set output2 [string trim [string range $arg [expr $i + 1] end] " "]] == "")} {
                set output2 $output1 ; # Error (User doesn't have access, or output was ""), so we go back to the default
            }
            set arg [string trim [string range $arg 0 [expr $i - 1]] " "]
        }
        set remainder [xrange $arg 0 end]
        if {(([scan $remainder "%s from %s to %s" value type1 type2] != 3) || ([anymatch [list $value $type1 $type2] {from to}])) && \
            (([scan $remainder "%s from %s %s"    value type1 type2] != 3) || ([anymatch [list $value $type1 $type2] {from to}])) && \
            (([scan $remainder "%s %s to %s"      value type1 type2] != 3) || ([anymatch [list $value $type1 $type2] {from to}])) && \
            (([scan $remainder "%s %s %s"         value type1 type2] != 3) || ([anymatch [list $value $type1 $type2] {from to}])) && \
            ((([info exists value]) && ([unset value] == "")) || 1) && \
            (([scan $remainder "from %s to %s"    type1 type2] != 2) || ([anymatch [list $type1 $type2] {from to}])) && \
            (([scan $remainder "from %s %s"       type1 type2] != 2) || ([anymatch [list $type1 $type2] {from to}])) && \
            (([scan $remainder "%s to %s"         type1 type2] != 2) || ([anymatch [list $type1 $type2] {from to}])) && \
            (([scan $remainder "%s %s"            type1 type2] != 2) || ([anymatch [list $type1 $type2] {from to}]))} {
            conv_msg $output1 "error parsing sentence"
        } else {
            if {![info exists value]} {
                set value 1
            }
            if {![catch {conv $value       $type1 "misc_from" [array names conv_misc_from]} type1_value]} {
                if {[catch {conv $type1_value $type2 "misc_to"   $list} type2_value]} {
                    conv_msg $output1 "error $type2_value"
                } else {
                    conv_msg $output2 "$value $type1 = $type2_value $type2"
                }
            } elseif {($conv_units_exec != "") && (![catch {conv_units $value $type1 $type2} output])} {
                conv_msg $output2 $output
            } else {
                set type1_formula $type1
                set type2_formula $type2
                set found 0
                while 1 {
                    if {[conv_scan "type1_formula" "type1_unit" 0]} {
                        if {![conv_scan "type2_formula" "type2_unit" 0]} {
                            conv_msg $output1 "error unmatched type '$type1_unit'"
                        } elseif {[catch {conv 1 $type1_unit "unit" [array names conv_unit]} type1_value]} {
                            conv_msg $output1 "error $type1_value"
                        } elseif {![regsub -nocase $type1_unit $type1_formula $type1_value type1_formula]} {
                            conv_msg $output1 "error decompiling expression '$type1_unit'"
                        } elseif {[catch {conv 1 $type2_unit "unit" $list} type2_value]} {
                            conv_msg $output1 "error $type2_value"
                        } elseif {![regsub -nocase $type2_unit $type2_formula $type2_value type2_formula]} {
                            conv_msg $output1 "error decompiling expression '$type2_unit'"
                        } else {
                            incr found
                            continue
                        }
                    } elseif {[conv_scan "type2_formula" "type2_unit" 0]} {
                        conv_msg $output1 "error unmatched type '$type2_unit'"
                    } else {
                        break
                    } ; # At the end, so stop
                    return ; # We got an error somewhere, bail out
                }
                if {!$found} {
                    conv_msg $output1 "error no conversion types found"
                } elseif {[catch {expr [conv_fixexpr "($value) * ($type1_formula) / ($type2_formula)"]} value2]} {
                    conv_msg $output1 "error evaluating expression"
                } else {
                    conv_msg $output2 "$value $type1 = $value2 $type2"
                }
            }
        }
    }
}
# End Public binds code

# Init stuff
if {[catch {package require Tcl 8.3} error]} {
    putlog "error TCL v8.3 or higher is required to run this script"
    return 0
}

putlog "*** LOADED: convert.tcl"
Categories: Code, TCL Tags: , , ,

faq.tcl

#### faq.tcl v1.0.0 ############################################################
################################################################################
## Written by:                                                                ##
##   KuNgFo0  (http://www.eggfaq.com/).                                       ##
##                                                                            ##
## Modified by:                                                               ##
##   Brian Schmidt aka. brianMan.                                             ##
################################################################################

#### Readme / Help #############################################################
################################################################################
## This script is ripped from KuNgFoO's ib.tcl v3.19 (infobot) script.        ##
################################################################################

#### Changelog #################################################################
################################################################################
## v1.0.0                                                                     ##
## + Initial release.                                                         ##
## + Added the possibility to control which channels could use the commands   ##
##   with a channel flag.                                                     ##
## * Applied a dirty hack to solve a minor redirection bug, which caused all  ##
##   add/append/remove commands that contained a > to break the script.       ##
################################################################################

# Set next line as the directory where the database files are
# located (no other files should be in the same dir)
set faq_dir "data/"

# Set the next line as the default database to save changes to
set faq_database "FooBot.dat"

# What should the channel flag be, to enable the FAQ for that channel?
set faq_channel_flag "faq"

# The default value should be ok for the next two:
# Set the next line as the format to display time in (without timezone)
set faq_format_notz "%H:%M:%S - %A, %B %d, %Y"

# Set the next line as the format to display time in (with timezone)
set faq_format "$faq_format_notz %Z"

# Set the next line as the maxinum number of matches to
# return on searches
set faq_max 5

# Set the next line as the maxinum number of lines to
# return publicly
set faq_max_lines 3

# Set the next line as the flag required to add/remove
# questions and etc
set faq_flag "+f"

# Set the next line as how often to save changes to the database
# (in minutes)
set faq_time 10

proc xrange {xr xr1 xr2} {
    return [join [lrange [split $xr] $xr1 $xr2]]
}

proc xindex {xr xr1} {
    return [join [lrange [split $xr] $xr1 $xr1]]
}

proc validnum {num} {
    return [expr [scan $num "%f%s" a b] == 1]
}

proc anymatch {string1 string2} {
    foreach string $string2 {
        if {[lsearch -exact [string tolower $string1] [string tolower $string]] != -1} {
            return 1
        }
    }
    return 0
}

proc parseurl {url} {
    foreach var {protocol user pass server port path cgiargs anchor} { upvar 1 $var $var }
    if {[regexp {(([^:]+)://)?(([^:]+):([^@]+)@)?([^:/\?#]+)(:([0-9]+))?(/([^\?#]+))?(\?([^#]+))?(#(.*))?} $url a b protocol c user pass server d port e path f cgiargs g anchor]} {
        if {$protocol == ""} {
            set protocol "http"
        }
        if {![validnum $port]} {
            set port 80
        }
        return 1
    } else {
        return 0
    }
}

# Begin Database code
proc faq_fixtopic {arg} {
    regsub -all {[\\\{\}\[\]\"]} $arg {}   arg ; # Bad characters
    regsub -all {(\s)+}          $arg {\1} arg ; # Double whitespace
    regsub -all {^\s*|\s*$}      $arg {}   arg ; # Whitespace at ends
    return $arg
}

proc faq_fixdb {arg} {
    global faq_databases
    if {[set i [lsearch -exact [string tolower $faq_databases] [string tolower $arg]]] == -1} {
        return "
error no such database '$arg' loaded"
    } else {
        return [lindex $faq_databases $i]
    }
}

proc faq_fixdata {arg output} {
    global botnick
    if {[string index $output 0] != "
#"} {
        regsub -all -nocase {$output's} $arg "your" arg
    }
    regsub -all -nocase {$botnick'
s} $arg "my" arg
    return $arg
}

proc faq_msg {targets arg} {
    foreach target $targets {
        puthelp "PRIVMSG $target :[faq_fixdata $arg $target]"
    }
}

proc faq_check {} {
    global faq_dir
    if {![file exists $faq_dir]} {
        return "error $faq_dir does not exist"
    } elseif {![file isdirectory $faq_dir]} {
        return "error $faq_dir is not a directory"
    } elseif {![file readable $faq_dir]} {
        return "error $faq_dir is unreadable"
    } elseif {![file writable $faq_dir]} {
        return "error $faq_dir is unwritable"
    }
    return ""
}

proc faq_loadall {output1 output2} {
    global faq_dir faq_databases
    # Unset current databases first
    faq_unloadall
    if {[set error [faq_check]] != ""} {
        if {$output1 == ""} {
            putlog $error
        } else {
            faq_msg $output1 $error
        }
    } else {
        foreach file [glob -nocomplain [file join $faq_dir *]] {
            if {[file isfile $file]} {
                if {[xindex [set output [faq_load [file tail $file]]] 0] == "error"} {
                    if {$output1 == ""} {
                        putlog $output
                    } else {
                        faq_msg $output1 $output
                    }
                } else {
                    if {$output2 == ""} {
                        putlog $output
                    } else {
                        faq_msg $output2 $output
                    }
                }
            }
        }
    }
}

proc faq_load {database} {
    global faq_dir faq_databases faq_data_$database
    set file [file join $faq_dir $database]
    faq_unload $database
    if {([string match *..* $database]) || ([string index $database 0] == "/")} {
        return "error invalid database name '$database'"
    } elseif {![file exists $file]} {
        return "error database '$database' does not exist"
    } elseif {![file isfile $file]} {
        return "error database '$database' is not a valid file"
    } elseif {[catch {open $file r} fileid]} {
        return "error could not read database '$database'"
    } else {
        if {[catch {array set faq_data_$database [read $fileid]}]} {
            return "error could not parse database '$database'"
        }
        close $fileid
        lappend faq_databases $database
        return "read database '$database'"
    }
}

proc faq_unloadall {} {
    global faq_databases
    if {[info exists faq_databases]} {
        foreach database $faq_databases {
            faq_unload $database
        }
    }
    set faq_databases ""
}

proc faq_unload {database} {
    global faq_databases faq_data_$database
    if {[array exists faq_data_$database]} {
        array unset faq_data_$database
    }
    if {[set i [lsearch -exact $faq_databases $database]] != -1} {
        set faq_databases [lreplace $faq_databases $i $i]
    }
}

proc faq_saveall {output1 output2} {
    global faq_databases faq_save
    set error 0
    if {[set output [faq_check]] != ""} {
        if {$output1 == ""} {
            putlog $error
        } else {
            faq_msg $output1 $output
        }
        set error 1
    } else {
        foreach database $faq_databases {
            if {[xindex [set output [faq_save $database]] 0] == "error"} {
                if {$output1 == ""} {
                    putlog $output
                } else {
                    faq_msg $output1 $output
                }
                set error 1
            } else {
                if {$output2 == ""} {
                    putlog $output
                } else {
                    faq_msg $output2 $output
                }
            }
        }
    }
    set faq_save $error
}

proc faq_save {database} {
    global faq_dir faq_databases faq_data_$database
    if {[catch {open [file join $faq_dir $database] w} fileid]} {
        return "error could not write database 'database'"
    } else {
        puts $fileid [array get faq_data_$database]
        close $fileid
        return "wrote database '$database'"
    }
}

proc faq_needsave {} {
    global faq_save
    set faq_save 1
}

proc time_faq {} {
    global faq_time faq_save
    if {$faq_save} {
        faq_saveall "" ""
    }
    if {![string match *time_faq* [timers]]} {
        timer $faq_time time_faq
    }
}

proc faq_topics {arg} {
    set topics ""
    set arg    [string trimright $arg "?! "]
    set length [llength $arg]
    for {set l $length} {$l > 0} {incr l -1} {
        for {set i [expr $length - $l]} {$i >= 0} {incr i -1} {
            if {[lsearch -exact [string tolower $topics] [string tolower [set topic [lrange $arg $i [expr $i + $l - 1]]]]] == -1} {
                lappend topics $topic
            }
        }
    }
    return $topics
}

# {"topic 1" "topic 2" ...} -> faq_find -> {"database" "first topic found"}
# note: databases are not checked for validity
proc faq_find {topics} {
    global faq_databases
    foreach topic $topics {
        set topic [faq_fixtopic $topic]
        foreach database $faq_databases {
            if {[xindex [set topic2 [faq_exists $topic $database 1]] 0] != "error"} {
                return [list $database $topic2]
            }
        }
    }
}

# "*topic string*" -> faq_find2 -> { {"database" "topic found 1"} {"database" "topic found 2"} ... }
proc faq_find2 {topic} {
    global faq_databases
    set topic  [faq_fixtopic $topic]
    set topics ""
    foreach database $faq_databases {
        global faq_data_$database
        # [array names faq_data_$database -glob *topic*] would be really nice here, but it has no -nocase option!
        foreach topic2 [array names faq_data_$database] {
            if {[string match -nocase *$topic* $topic2]} {
                lappend topics [list $database $topic2]
            }
        }
    }
    return $topics
}

proc faq_parsetopic {arg var1 var2} {
    global $var1 $var2
    set i     [string first "=" $arg]
    set $var1 [string trim [string range $arg 0 [expr $i - 1]] " "]
    set $var2 [string trim [string range $arg [expr $i + 1] end] " "]
    for {set i 1} {$i <= 2} {incr i} {
        if {[string match "topic*" [set topic_var [set var$i]]]} {
            # if this is a topic, we look for a database too
            set database_var "database[string range $topic_var 5 end]"
            if {[xindex [set error [faq_parsedb [set $topic_var] $topic_var $database_var]] 0] == "error"} {
                return $error
            } ; # we got an error parsing the db
        }
    }
    if {([set $var1] == "") || ([set $var2] == "") || ($i == -1)} {
        return "error parsing sentence"
    }
}

proc faq_parsedb {arg var1 var2} {
    global faq_database $var1 $var2
    if {[set i [string last "|" $arg]] != -1} {
        set $var1 [string trim [string range $arg 0 [expr $i - 1]] " "]
        set $var2 [string trim [string range $arg [expr $i + 1] end] " "]
    } else {
        if {[set tmp [faq_find [list $arg]]] != ""} {
            set $var2 [lindex $tmp 0] ; # we go with the db that this topic is already stored in
        } else {
            set $var2 $faq_database ; # we go w/ default db
        }
    }
    if {([set $var1 [faq_fixtopic [set $var1]]] == "") || ([set $var2] == "")} {
        return "error parsing sentence"
    }
    return [set $var2 [faq_fixdb [set $var2]]] ; # this may return an error
}

# type = 0, returns 1/0 ; type = 1, returns proper case (or error), for use with existing topics ;
# type = 2, returns proper case (or original topic), for use with creating new topics
proc faq_exists {topic database type} {
    global faq_data_$database
    if {[set i [lsearch [string tolower [array names faq_data_$database]] [string tolower $topic]]] != -1} {
        if {$type == 0} {
            return 1
        } else {
            return [lindex [array names faq_data_$database] $i]
        }
    } else {
        if {$type == 0} {
            return 0
        } elseif {$type == 1} {
            return "error topic '$topic' does not exist in database '$database'"
        } else {
            return $topic
        }
    }
}

proc faq_write {topic database type arg host} {
    global faq_data_$database
    set topic [faq_exists $topic $database 2]
    if {$type == "w"} {
        set faq_data_${database}($topic) [list $arg]
    } elseif {$type == "a"} {
        lappend faq_data_${database}($topic) $arg
    }
    lappend faq_data_${database}($topic) "#WHOSET $host [clock seconds]"
}

proc faq_read {topic database} {
    global faq_data_$database
    if {[xindex [set database [faq_fixdb $database]] 0] == "error"} {
        return $database
    } elseif {[xindex [set topic [faq_exists $topic $database 1]] 0] == "error"} {
        return $topic
    } else {
        return [set faq_data_${database}($topic)]
    }
}

proc faq_copy {topic1 database1 topic2 database2} {
    global faq_data_$database1 faq_data_$database2
    if {[faq_exists $topic2 $database2 0]} {
        return "error topic '$topic2' already exists in database '$database2'"
    } elseif {[xindex [set output [faq_read $topic1 $database1]] 0] == "error"} {
        return $output
    } else {
        set faq_data_${database2}($topic2) $output
    }
}

proc faq_remove {topic database} {
    global faq_data_$database
    if {[xindex [set topic [faq_exists $topic $database 1]] 0] == "error"} {
        return $topic
    } else {
        unset faq_data_${database}($topic)
    }
}

proc faq_disp {arg database output1 output2 depth num option nick} {
    global faq_max_lines
    if {$depth >= 3} {
        faq_msg $output1 "error recursion too deep"
        return -1
    }
    set found 0
    if {$database != ""} {
        set list [list [list $database $arg]] ; # we have an exact topic/db to display
    } else {
        set list [list [faq_find [faq_topics $arg]]]; # find topic/db (s)
    }
    # note: the $list vars above needed to be padded with { } - hence the [list] 's
    foreach tmp $list {
        if {$tmp == ""} {
            continue
        }
        if {!$depth} {
            set num 0
        }
        if {[xindex [set output [faq_read [set topic [lindex $tmp 1]] [set database [lindex $tmp 0]]]] 0] == "error"} {
            faq_msg $output1 $output
        } else {
            foreach line $output {
                if {($line == "") || ([xindex $line 0] == "#WHOSET")} {
                    #ignore
                } elseif {[xindex $line 0] == "#LINK"} {
                    if {[set temp [faq_disp [lindex $line 1] [lindex $line 2] $output1 $output2 [expr $depth + 1] $num 0 $nick]] > 0} {
                        incr num $temp
                    }
                } elseif {[xindex $line 0] == "."} {
                    faq_msg $output2 [xrange $line 1 end]
                    incr num
                } elseif {!$num} {
                    faq_msg $output2 "$topic - $line"
                    incr num
                } else {
                    faq_msg $output2 "... $line"
                    incr num
                }
            }
            if {!$num} {
                faq_msg $output1 "error '$topic' exists, but is empty"
            } elseif {(![string equal -nocase $output2 $output1]) && (!$depth)} {
                faq_msg $output2 "(sent by $output1)"
                faq_msg $output1 "sent '$topic' to $output2"
            }
            incr found
        }
    }
    if {!$found} {
        if {$depth > 0} {
            faq_msg $output1 "error invalid link to '$arg'"
        }
    }
    return $num
}
# End Database code

# Begin 'calc' code
proc faq_fixexpr {exp} {
    global faq_const
    set exp [faq_fixtopic $exp]
    foreach i [array names faq_const] {
        regsub -all "\%$i" $exp $faq_const($i) exp
    }
    return $exp
}
# End 'calc' code

# expr's abs() and int() can't handle large unsigned integers,
# these functions are just to get around this
proc faq_int {value} {
    return [lindex [split $value "."] 0]
}

proc faq_abs {value} {
    return [string trimleft $value "-"]
}

proc faq_absint {value} {
    return [faq_int [faq_abs $value]]
}

# Begin Public binds code
proc msg_faq {nick uhost hand arg} {
    pub_faq $nick $uhost $hand "" $arg
}

proc pub_faq {nick uhost hand chan arg} {
    global botnick faq_dir faq_format faq_max faq_flag faq_database faq_databases faq_channel_flag
    global topic topic1 topic2 database database1 database2 value
    if {(![isbotnick $nick]) && (![matchattr $hand +b]) && ((($chan != "") && ([channel get $chan $faq_channel_flag])) || ($chan == ""))} {
        if {[string match -nocase $botnick* $arg]} {
            set arg [xrange $arg 1 end] ; # Only answer channel messages that begin with the bot's nick
        } elseif {$chan == ""} {
            # Answer all privmsgs
        } else {
            return ; # Msg isn't for us, bail out
        }

        set isuser [expr {[matchattr $hand $faq_flag|$faq_flag $chan] || [matchattr $hand $faq_flag]}] ; # Note that $chan might be "", so we must handle both cases
        if {([validchan $chan]) && ($isuser)} {
            set output1 $chan ; # The bot sends the text to the channel for users
        } else {
            set output1 $nick ; # Non-users get privmsg'd
        }

        set output2 $output1 ; # By default, output2 (~stdout~) goes to output1 (~stderr~)

        if {([lsearch -exact [split "shutup stop sh database db set learn add unset forget delete del remove rem rm erase append addon link join copy cp move mv rename ren"] [string tolower [xindex $arg 0]]] == -1) && ([set i [string last ">" $arg]] != -1)} {
            # Output has been redirected
            if {(!$isuser) || ([set output2 [string trim [string range $arg [expr $i + 1] end] " "]] == "")} {
                set output2 $output1 ; # Error (User doesn't have access, or output was ""), so we go back to the default
            }
            set arg [string trim [string range $arg 0 [expr $i - 1]] " "]
        }

        set command   [string tolower [xindex $arg 0]]
        set remainder [xrange $arg 1 end]
        switch -- $command {
            "shutup" - "stop" - "sh" {
                if {$isuser} {
                    if {[clearqueue help]} {
                        faq_msg $output2 "OK, sorry"
                    } else {
                        faq_msg $output2 "But I'm not saying anything!"
                    }
                }
            }
            "database" - "db" {
                if {$isuser} {
                    switch -- [string tolower [xindex $remainder 0]] {
                        "reload" {
                            faq_loadall $output1 $output2
                        }
                        "save" {
                            faq_saveall $output1 $output2
                        }
                        "list" {
                            set i 1
                            faq_msg $output2 "Loaded database(s):"
                            foreach database $faq_databases {
                                global faq_data_$database
                                faq_msg $output2 [format "%s %-15s %s" $i. $database #[array size faq_data_$database]]
                                incr i
                            }
                            faq_msg $output2 "end"
                        }
                        default {
                            faq_msg $output1 "error must be one of 'reload', 'save' , or 'list'"
                        }
                    }
                }
            }
            "set" - "learn" - "add" {
                if {$isuser} {
                    if {([xindex [set error [faq_parsetopic $remainder topic value]] 0] == "error") || \
                        ([xindex [set error [faq_write $topic $database "w" $value $nick!$uhost]] 0] == "error")} {
                        faq_msg $output1 $error
                    } else {
                        faq_msg $output2 "Set '$topic' in database '$database'"
                        faq_needsave
                    }
                }
            }
            "unset" - "forget" - "delete" - "del" - "remove" - "rem" - "rm" - "erase" {
                if {$isuser} {
                    if {([xindex [set error [faq_parsetopic "$remainder = null" topic value]] 0] == "error") || \
                        ([xindex [set error [faq_remove $topic $database]] 0] == "error")} {
                        faq_msg $output1 $error
                    } else {
                        faq_msg $output2 "Unset '$topic' in database '$database'"
                        faq_needsave
                    }
                }
            }
            "append" - "addon" {
                if {$isuser} {
                    if {([xindex [set error [faq_parsetopic $remainder topic value]] 0] == "error") || \
                        ([xindex [set error [faq_write $topic $database "a" $value $nick!$uhost]] 0] == "error")} {
                        faq_msg $output1 $error
                    } else {
                        faq_msg $output2 "Appended to '$topic' in database '$database'"
                        faq_needsave
                    }
                }
            }
            "link" - "join" {
                if {$isuser} {
                    if {[xindex [set error [faq_parsetopic $remainder topic1 topic2]] 0] == "error"} {
                        faq_msg $output1 $error
                    } elseif {[xindex [set topic2 [faq_exists $topic2 $database2 1]] 0] == "error"} {
                        faq_msg $output1 $topic2 ; # check if 2nd topic exists, get proper casing too (so $topic2 not $error is used)
                    } elseif {[xindex [set error [faq_write $topic1 $database1 "a" [list #LINK $topic2 $database2] $nick!$uhost]] 0] == "error"} {
                        faq_msg $output1 $error
                    } else {
                        faq_msg $output2 "Linked '$topic1' ($database1) to '$topic2' ($database2)"
                        faq_needsave
                    }
                }
            }
            "copy" - "cp" {
                if {$isuser} {
                    if {([xindex [set error [faq_parsetopic $remainder topic1 topic2]] 0] == "error") || \
                        ([xindex [set error [faq_copy $topic1 $database1 $topic2 $database2]] 0] == "error")} {
                        faq_msg $output1 $error
                    } else {
                        faq_msg $output2 "Copied '$topic1' ($database1) to '$topic2' ($database2)"
                        faq_needsave
                    }
                }
            }
            "move" - "mv" - "rename" - "ren" {
                if {$isuser} {
                    if {([xindex [set error [faq_parsetopic $remainder topic1 topic2]] 0] == "error") || \
                        ([xindex [set error [faq_copy $topic1 $database1 $topic2 $database2]] 0] == "error") || \
                        ([xindex [set error [faq_remove $topic1 $database1]] 0] == "error")} {
                        faq_msg $output1 $error
                    } else {
                        faq_msg $output2 "Renamed '$topic1' ($database1) to '$topic2' ($database2)"
                        faq_needsave
                    }
                }
            }
            "list" - "find" - "search" - "locate" {
                set topics [faq_find2 $remainder]
                switch -- [set found [llength $topics]] {
                    0 {
                        faq_msg $output1 "Found no matches to '$remainder'"
                    }
                    1 {
                        faq_disp [join $topics] "" $output1 $output2 0 0 0 $nick
                    }
                    default {
                        faq_msg $output2 "Found $found matches to '$remainder'"
                        set i 1
                        foreach topic $topics {
                            faq_msg $output2 "$i. [lindex $topic 1]"
                            if {$i >= $faq_max} {
                                break
                            }
                            incr i
                        }
                        faq_msg $output2 "end"
                    }
                }
            }
            "whoset" {
                if {[xindex [set error [faq_parsetopic "$remainder = null" topic value]] 0] == "error"} {
                    faq_msg $output1 $error
                } elseif {[xindex [set output [faq_read $topic $database]] 0] == "error"} {
                    faq_msg $output1 $output
                } else {
                    set found 0
                    foreach line $output {
                        if {[xindex $line 0] == "#WHOSET"} {
                            if {!$found} {
                                faq_msg $output2 "'$topic' (database $database) set by [xindex $line 1] on [clock format [xindex $line 2] -format $faq_format]"
                                incr found
                            } else {
                                faq_msg $output2 "... modified by [xindex $line 1] on [clock format [xindex $line 2] -format $faq_format]"
                            }
                        }
                    }
                    if {!$found} {
                        faq_msg $output1 "error could not find who set topic '$topic'"
                    }
                }
            }
            default {
            faq_disp $arg "" $output1 $output2 0 0 1 $nick
            }
        }
    }
}
# End Public binds code

# Init stuff
if {[catch {package require Tcl 8.3} error]} {
    putlog "error TCL v8.3 or higher is required to run this script"
    return 0
}
putlog "*** LOADED: faq.tcl"

bind pubm - * pub_faq
bind msgm - * msg_faq
setudef flag $faq_channel_flag

if {![info exists faq_load]} {
    faq_loadall "" ""
    set faq_load 1
}
if {![info exists faq_save]} {
    set faq_save 0
}
if {![string match *time_faq* [timers]]} {
    timer $faq_time time_faq
}
Categories: Code, TCL Tags: , , ,

nslookup.tcl

#### nslookup.tcl v1.0.1 #######################################################
################################################################################
## Written by:                                                                ##
##   KuNgFo0  (http://www.eggfaq.com/).                                       ##
##                                                                            ##
## Modified by:                                                               ##
##   Brian Schmidt aka. brianMan.                                             ##
################################################################################

#### Readme / Help #############################################################
################################################################################
## This is a slightly modified version of KuNgFoO's nslookup.tcl v0.5 script. ##
##                                                                            ##
## Script that can do nslookups.                                              ##
##                                                                            ##
## Usage:                                                                     ##
##   To have the .dns command available on a channel you need to set the      ##
##   channel flag +nslookups from the console/partyline .                     ##
##   ``.chanset #channel +nslookups´´                                         ##
##                                                                            ##
## Channel Commands (available only if channel is +nslookups):                ##
##   .dns [ host|ip|nick[ host|ip|nick][ ...]]                                ##
## Example:                                                                   ##
##   ``.dns www.eggfaq.com´´                                                  ##
################################################################################

#### Changelog #################################################################
################################################################################
## v1.0.1                                                                     ##
## * Minor code cleanup                                                       ##
##                                                                            ##
## v1.0.0                                                                     ##
## + Initial release.                                                         ##
## + Added the possibility to control which channels could use the commands   ##
##   with the channel flag ``+/-nslookup´´                                    ##
################################################################################

# Set then next line as the command you want to initate the nslookup
set nslookup_command ".dns"

# Set the flagname used for enabling the channel command
set nslookup_channel_flag "nslookup"

# Set the next line as the flag required to use the command
set nslookup_flag "-"

# Set the next line as the exec command to run
# (Only if you're running an older eggdrop or not using the nslookup module)
set nslookup_exec "nslookup -silent"

bind pub $nslookup_flag|$nslookup_flag $nslookup_command pub_nslookup

proc pub_nslookup {nick uhost hand chan arg} {
    global nslookup_command nslookup_exec botnick nslookup_channel_flag
    if {([channel get $chan $nslookup_channel_flag]) && (![matchattr $hand b]) && ($nick != $botnick)} {
        if {$arg == ""} {
            putserv "PRIVMSG $chan :Usage: $nslookup_command  \[host/ip/nick #2\] ..."
        } else {
            foreach addr [set addrs [split $arg {,;| }]] {
                if {$addr == ""} {
                    continue ; # ignore
                }
                if {[set tmp [getchanhost $addr]] != ""} {
                    set addr [lindex [split $tmp @] end]
                }
                if {![regexp {^[a-zA-Z0-9\.\-]*$} $addr]} {
                    putserv "PRIVMSG $chan :Error: Hostname '$addr' contains illegal characters" ; # vulnerability
                } elseif {[string index $addr 0] == "-"} {
                    putserv "PRIVMSG $chan :Error: Hostnames cannot begin with a - character ($addr)" ; # vulnerability
                } elseif {[info commands dnslookup] != ""} {
                    dnslookup $addr return_nslookup $chan $addr
                } elseif {[catch {exec bash -c "$nslookup_exec '$addr'"} output]} {
                    putserv "PRIVMSG $chan :Could not resolve $addr"
                } else {
                    foreach line [split $output \n] {
                        if {[lindex $line 0] == "Name:"} {
                            set host [lrange $line 1 end]
                        } elseif {([lindex $line 0] == "Address:") || ([lindex $line 0] == "Addresses:")} {
                            set ip [lrange $line 1 end]
                        }
                    }
                    if {([info exists host]) && ([info exists ip])} {
                        return_nslookup $ip $host 1 $chan $addr
                    } else {
                        return_nslookup "" "" 0 $chan $addr
                    }
                }
            }
        }
    }
}

proc return_nslookup {ip host status chan addr} {
    if {$status} {
        if {[string match *$ip* $addr]} {
            putserv "PRIVMSG $chan :$ip -> $host"
        } else {
            putserv "PRIVMSG $chan :$host -> $ip"
        }
    } else {
        putserv "PRIVMSG $chan :Could not resolve $addr"
    }
}

setudef flag $nslookup_channel_flag
putlog "*** LOADED: nslookup.tcl"
Categories: Code, TCL Tags: , , ,

antispam.mrc – Block spammers

;;;; Anti Spam v1.0.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Written by:                                                                ;;
;;   Brian Schmidt aka. brianMan aka. b|man.                                  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;; Readme / Help ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load this script in mIRC, if you don't know how to do this, then perhaps   ;;
;; you shouldn't be using this script.                                        ;;
;;                                                                            ;;
;; Very simple spamblocking script, blocks private message if they contain a  ;;
;; word (usually urls) that are stored in it's dbfile.                        ;;
;;                                                                            ;;
;; Right click in a query window, or click the custom menu in the menubar to  ;;
;; configure it/enable it.                                                    ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;; Changelog ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; v1.0.0                                                                     ;;
;; + Initial release.                                                         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Make sure the variable, with the file containing the list of blocked strings
;; are set at script start.
on *:START:{
    set %_antispam_dbfile spamdb.txt
    echo -tc info *** Anti-Spam by Brian Schmidt loaded..
}

alias antispam {
    if ($1 == add || $1 == a) {
        if (!$read(%_antispam_dbfile,w,$$2)) {
            write %_antispam_dbfile $encode($$2)
            echo -tac info *** Adding $$2 to %_antispam_dbfile
        }
        else {
            echo -tac info *** $$2 allready in %_antispam_dbfile
        }
    }
    elseif ($1 == remove || $1 == rem || $1 == r || $1 == delete || $1 == del || $1 == d) {
        if ($read(%_antispam_dbfile,w,$encode($$2))) {
            write -dw $encode($$2) %_antispam_dbfile
            echo -tac info *** Removed $$2 from %_antispam_dbfile
        }
        else {
            echo -tac info *** $$2 not in %_antispam_dbfile
        }
    }
    elseif ($1 == check || $1 == c) {
        if (%_antispam_status != $null && %_antispam_status != 0 && %_antispam_status != off) {
            var %i 1
            while (%i <= $numtok($2-,32)) {
                if ($read(%_antispam_dbfile,w,$encode($gettok($2-,%i,32)))) {
                    if ($line($nick,0) == 0) {
                        window -c $window($nick)
                    }
                    halt
                }
                inc %i
            }
        }
    }
    elseif ($1 == status) {
        if ($2 == 1 || $2 == on) {
            set %_antispam_status 1
            echo -tac info *** Anti-Spam enabled.
        }
        elseif ($2 == 0 || $2 == off) {
            set %_antispam_status 0
            echo -tac info *** Anti-Spam disabled.
        }
    }
    elseif ($1 == list || $1 == l) {
        window -dClk0 @Anti-Spam
        var %c = $lines(%_antispam_dbfile)
        if (%c > 0) {
            var %i = 1
            while (%i <= %c) {
                aline -p @Anti-Spam $decode($read(%_antispam_dbfile,t,%i))
                inc %i
            }
        }
    }
}

;; The popup menus.
menu query,menubar {
    -
    Anti-Spam
    .$iif(%_antispam_status == 0 || %_antispam_status == $null,Enable):antispam status on
    .$iif(%_antispam_status == 1,Disable):antispam status off
    .Configure:antispam list
    -
}
menu @Anti-Spam {
    dclick:if ($input(Delete $line(@Anti-Spam,$1),y,Confirm delete)) { antispam rem $line(@Anti-Spam,$1) | dline @Anti-Spam $1 }
    Add..:var %antispam_tmp_add $input(Add spamline,e) | antispam add %antispam_tmp_add | aline @Anti-Spam %antispam_tmp_add
}

;; Catch all (private) text and check it for spam.
on ^&*:TEXT:*:?:{
    antispam check $1-
}
on ^&*:ACTION:*:?:{
    antispam check $1-
}
Categories: Code, mIRC Tags: , ,

age.mrc – Calculate Your Age

;;;; My Age v1.1.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Written by:                                                                ;;
;;   Brian Schmidt aka. brianMan.                                             ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;; Readme / Help ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load this script in mIRC, if you don't know how to do this, then perhaps   ;;
;; you shouldn't be using this script.                                        ;;
;;                                                                            ;;
;; Simple script to tell how old you are in seconds, or minutes etc.          ;;
;;                                                                            ;;
;; Commands available:                                                        ;;
;;   /myage                                                                   ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;; Changelog ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; v1.1.0                                                                     ;;
;; + Added possibility to only say your age in one format (hour/sec etc.).    ;;
;; * Changed the actual trigger alias from /age to /myage. The age alias is   ;;
;;   only used as an identifier that returns the value to the calling script. ;;
;; + Will now ask for your birthdate when run, if it isn't set. Then store it ;;
;;   in a variable for later use.                                             ;;
;;                                                                            ;;
;; v1.0.0                                                                     ;;
;; + Initial release.                                                         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

alias age {
    var %unix = $ctime($$1-)
    var %now = $ctime
    var %seconds = $calc( %now - %unix )
    var %minutes = $calc( %seconds / 60 )
    var %hours = $calc( %minutes / 60 )
    var %days = $calc( %hours / 24 )
    var %weeks = $calc( %days / 7 )
    var %years = $calc( %days / 365.22222222222 )
    var %months = $calc( %years * 12 )

    if ($prop == seconds) return %seconds
    elseif ($prop == minutes) return %minutes
    elseif ($prop == hours) return %hours
    elseif ($prop == days) return %days
    elseif ($prop == weeks) return %weeks
    elseif ($prop == months) return %months
    elseif ($prop == years) return %years
    else return %years
}

alias myage {
    if (%myage.birthday == $null || $1 == set) {
        set %myage.birthday $$input(What is your birth date? $+ $crlf $+ Example: $+ $crlf 13.12.1976 23:59:59,e,Birth date?)
    }
    if ($1 == sec) msg $active I am $age(%myage.birthday).seconds seconds old.
    elseif ($1 == min || $1 == minute || $1 == minutes) msg $active I am $age(%myage.birthday).minutes minutes old.
    elseif ($1 == hrs || $1 == hour || $1 == hours) msg $active I am $age(%myage.birthday).hours hours old.
    elseif ($1 == day || $1 == days) msg $active I am $age(%myage.birthday).days days old.
    elseif ($1 == wek || $1 == week || $1 == weeks) msg $active I am $age(%myage.birthday).weeks weeks old.
    elseif ($1 == mth || $1 == month || $1 == months) msg $active I am $age(%myage.birthday).months months old.
    elseif ($1 == yrs || $1 == year || $1 == years) msg $active I am $age(%myage.birthday).years years old.
    else msg $active My age in: Seconds: $age(%myage.birthday).seconds $+ . Minutes: $age(%myage.birthday).minutes $+ . Hours: $age(%myage.birthday).hours $+ . Days: $age(%myage.birthday).days $+ . Weeks: $age(%myage.birthday).weeks $+ . Months: $age(%myage.birthday).months $+ . Years: $age(%myage.birthday).years $+ .
}
Categories: Code, mIRC Tags: , ,

csize.mrc – Convert Size

;;;; Convert Size v1.1.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Written by:                                                                ;;
;;   Brian Schmidt aka. brianMan.                                             ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;; Readme / Help ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load this script in mIRC, if you don't know how to do this, then perhaps   ;;
;; you shouldn't be using this script.                                        ;;
;;                                                                            ;;
;; This script is used to convert size in bytes to a nice to KB/MB/GB etc.    ;;
;;                                                                            ;;
;; There are 2 ways to use this scripts:                                      ;;
;; 1. Message to active window with /csize:                                   ;;
;;      "/csize /csize 54653875238"                                           ;;
;;    Will output:                                                            ;;
;;      "50.9 GB"                                                             ;;
;; 2. Can also be used for in-line reverse with $rev in scripts etc.          ;;
;;      "//echo -a Converting 54653875238 bytes to $csize(54653875238).ext    ;;
;;       gives $csize(54653875238) $csize(54653875238).ext"                   ;;
;;    Will output:                                                            ;;
;;      "Converting 54653875238 bytes to GB gives 50.900388 GB"               ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;; Changelog ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; v1.1.1                                                                     ;;
;; * Fixed $csize().ext always returning YiB                                  ;;
;;                                                                            ;;
;; v1.1.0                                                                     ;;
;; + Added posiblitiy to convert to a specific type with identifiers.         ;;
;;   $csize(50000000) returns 47.683716 (MiB)                                 ;;
;;   $csize(50000000).gib returns 0.046566 (GiB)                              ;;
;;   This can't be done with the "b" property, wich is also irrelevant, since ;;
;;   the Bytes is allready what you have.                                     ;;
;;                                                                            ;;
;; v1.0.0                                                                     ;;
;; + Initial release.                                                         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

alias csize {
    if ($len($$1) <= 3) {
        var %csize $$1
        var %csize.ext B
    }
    if ($len($$1) > 3 || ($prop != $null && $prop == kib)) {
        var %csize $calc( $$1 / 1024 )
        var %csize.ext KiB
        if ($prop == kib) return %csize
    }
    if ($len($$1) > 6 || ($prop != $null && $prop == mib)) {
        var %csize $calc( %csize / 1024 )
        var %csize.ext MiB
        if ($prop == mib) return %csize
    }
    if ($len($$1) > 9 || ($prop != $null && $prop == gib)) {
        var %csize $calc( %csize / 1024 )
        var %csize.ext GiB
        if ($prop == gib) return %csize
    }
    if ($len($$1) > 12 || ($prop != $null && $prop == tib)) {
        var %csize $calc( %csize / 1024 )
        var %csize.ext TiB
        if ($prop == tib) return %csize
    }
    if ($len($$1) > 15 || ($prop != $null && $prop == pib)) {
        var %csize $calc( %csize / 1024 )
        var %csize.ext PiB
        if ($prop == pib) return %csize
    }
    if ($len($$1) > 18 || ($prop != $null && $prop == eib)) {
        var %csize $calc( %csize / 1024 )
        var %csize.ext EiB
        if ($prop == eib) return %csize
    }
    if ($len($$1) > 21 || ($prop != $null && $prop == zib)) {
        var %csize $calc( %csize / 1024 )
        var %csize.ext ZiB
        if ($prop == zib) return %csize
    }
    if ($len($$1) > 24 || ($prop != $null && $prop == yib)) {
        var %csize $calc( %csize / 1024 )
        var %csize.ext YiB
        if ($prop == yib) return %csize
    }
    if ($isid == $true) {
        if ($prop == ext) {
            return %csize.ext
        }
        return %csize
    }
    else {
        msg $active $round(%csize,2) %csize.ext
    }
}
Categories: Code, mIRC Tags: , ,

everyone.mrc – Greet everyone in a channel

;;;; Everyone v1.0.0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Written by:                                                                ;;
;;   Brian Schmidt aka. brianMan.                                             ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;; Readme / Help ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load this script in mIRC, if you don't know how to do this, then perhaps   ;;
;; you shouldn't be using this script.                                        ;;
;;                                                                            ;;
;; Return all nicks (except your own) for use in fun/annoying scripts.        ;;
;;                                                                            ;;
;; Identifiers available:                                                     ;;
;;   $everyone                                                                ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;; Changelog ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; v1.0.0                                                                     ;;
;; + Initial release.                                                         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

alias everyone {
    var %i = 1
    var %c = 0
    var %total = $nick($chan,0)
    while (%i <= %total) {
        if (%i < %total) var %seperator = , $chr(32)
        else var %seperator = $chr(32) and $chr(32)
        if ($nick($chan,%i) != $me) {
            if (%c == 0) var %out = $nick($chan,%i)
            else var %out = %out $+ %seperator $+ $nick($chan,%i)
            inc %c
        }
        inc %i
    }
    return %out
}
Categories: Code, mIRC Tags: , ,