Source code

From Insomnia 24/7 Wiki
Revision as of 13:12, 25 February 2011 by imported>Wikiadmin (Created page with '== Source code listing for nanobot == <code> # Copyright (c) 2011, Insomnia 24/7 All rights reserved. # Redistribution and use in source and binary forms, with or without # modi…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Source code listing for nanobot

  1. Copyright (c) 2011, Insomnia 24/7 All rights reserved.
  2. Redistribution and use in source and binary forms, with or without
  3. modification, are permitted provided that the following conditions are met:
  1. Redistributions of source code must retain the above copyright notice, this
  2. list of conditions and the following disclaimer. Redistributions in binary
  3. form must reproduce the above copyright notice, this list of conditions and
  4. the following disclaimer in the documentation and/or other materials
  5. provided with the distribution. Neither the name of Insomnia 24/7 nor
  6. the names of its contributors may be used to endorse or promote products
  7. derived from this software without specific prior written permission.
  1. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  2. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  3. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  4. ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
  5. ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  6. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  7. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  8. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  9. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  10. OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  11. DAMAGE.
  1. !/usr/local/bin/perl

package nanobot;

use IO::Socket::INET6; use Module::Load;

$version = "Nanobot 3.0 beta 5"; $server = 'irc.insomnia247.nl'; # Hostname, IPv4 or IPv6 address. $port = 6667; $sslport = 6669; $botnick = 'nanobot'; # Bots nickname $botuser = 'nanobot'; # Bots username $nsp = ; # NickServ pasword (if not registered, leave empty) @channels = ("#bots", "#yourchannel"); @opers = ("insomnia247.nl", "rootedker.nl", "fbi.gov", "eye.spy"); # Oper(s) hostmask(s) $modchan = '#yourchannel'; $datadir = 'botdata'; $moddir = 'modules'; @autoload = (); # List modules to load on startup. Example: @autoload("mymodule", "kickban"); $wisecrack_seen_botnick = "I'm right here. I mean ... really, how did you miss that one?"; $wisecrack_seen_self = "I can see you! You're right there! That's right, I can see."; $wait_for_ping = 0; # Set to 1 if your network requires a ping reply before allowing to join channels. $connect_timeout = 120; # Seconds to wait before giving up connnecting to the IRC server. $ping_timeout = 300; # Seconds to wait before assuming timeout and attempting reconnect.

  1. These are set by the bot itself, do not modify

$logging = 1; $debug = 0; $op_all = 0; $hop_all = 0; $voice_all = 0; $botstatus = 1; $startup = time; %seenlog = (); %seentime = (); $public_modules = 0; @modules = ();

          1. Process commandline options #####

foreach $arg (@ARGV) { if ($arg eq "-h" or $arg eq "--help") { print "options:\n"; print " -h or --help Print this help.\n"; print " -v or --version Print version number and exit.\n"; print " -q or --quiet Activate silent mode (Nothing is printed to the screen.)\n"; print " -d or --debug Enable debugging output. (Use twice for greater effect.\n"; print " -s or --ssl Use ssl.\n"; print " -6 or --ipv6 Use IPv6 over IPv4.\n"; &shutd; }

if ($arg eq "-v" or $arg eq "--version") { print "version: $version\n"; &shutd;} if ($arg eq "-q" or $arg eq "--quiet") {$logging = 0;} if ($arg eq "-d" or $arg eq "--debug") {$debug++;} if ($arg eq "-s" or $arg eq "--ssl") { $ssl = 1; $port = $sslport; use IO::Socket::SSL; } }

          1. Kick things off ######

logts("Nanobot is starting...\n"); &directories; while(1) { &connct; sleep(2); }

          1. Check for data and module directories ######

sub directories { logts("Data folder .......... "); if (-d $datadir) { logts("[OK]\n"); } else { if (mkdir $datadir) { logts("[CREATED]\n"); } else { logts("[FAILED]\n"); } }

logts("Modules folder ....... "); if (-d $moddir) { logts("[OK]\n"); } else { if (mkdir $moddir) { logts("[CREATED]\n"); } else { logts("[FAILED]\n"); } } }

          1. Screen output subroutine #####

sub logts { if ($logging == 1){ print STDOUT "$_[0]"; } }

          1. Debug output subroutine #####

sub debug { if ($debug >= 1){ print STDOUT "$_[0]"; } } sub debug_extra { if ($debug == 2){ ($s,$m,$h,$d,$mo) = gmtime( time ); print STDOUT "[$h:$m:$s] $_[0]"; } }

          1. Connect to server ######

sub connct { debug("Attempting connect.\n");

# Connect to server logts("Connecting ........... "); $sock = IO::Socket::INET6->new( PeerAddr => $server, PeerPort => $port, Proto => 'tcp', Domain => AF_UNSPEC, Timeout => $connect_timeout) or die "Connect error: $!\n";

logts("[OK]\n");

if($ssl) { logts("Starting SSL ......... "); IO::Socket::SSL->start_SSL( $sock, SSL_verify_mode => 0, # Do not verify certificate ) or die "SSL handshake failed: $SSL_ERROR"; logts("[OK]\n"); }

debug("Connected to server: $server\non port: $port\n");

# Set nick and username logts("Sending user info .... "); snd("NICK $botnick"); snd("USER $botuser 8 *  :$version"); logts("[OK]\n");

# Catch SIGALRM from the OS when timeout expired. local $SIG{ALRM} = sub {$sock->shutdown(0);};

# Send all incomming data to the parser while (<$sock>) { eval { alarm 0; &parse($_); alarm $ping_timeout; }; }

debug("Closing socket.\n"); close $sock; logts("Error: Lost connection, reconnecting...\n"); $login = undef; }

          1. Subroutine for sending data to the IRC server #####

sub snd { print $sock "$_[0]\n"; debug_extra("<== $_[0]\n"); }

          1. Subroutine for sending messages to the IRC server #####

sub msg { snd("PRIVMSG $_[0] :$_[1]"); }

          1. Subroutine for sending notices to the IRC server #####

sub ntc { snd("NOTICE $_[0] :$_[1]"); }

          1. Socket input parser #####

sub parse { debug_extra("==> $_");

# Remove /r and /n chop($_); chop($_);

# Do nickserv auth and channel join if(!$login && ($wait_for_ping == 0)) { &login; }

# Handle PING and rejoin on kick if (/^PING \:(.+)/) { debug("Received PING request.\n"); snd("PONG :$1");

if(!$login && ($wait_for_ping == 1)) { &login; }

debug("Sent PONG reply.\n"); return; } elsif (/^\:(.+?)!(.+?)@(.+?) KICK #(.+?) \Q$botnick\E \:(.+?)/) { snd("JOIN #$4"); debug("Rejoined channel $4 after kick.\n"); return; }

# Hook for modules that want raw data foreach $module (@modules) { if( $module->can('raw') ) { $module->raw($_); } }

# Process generic NOTICE if (/^\:(.+?)!(.+?)@(.+?) NOTICE (.+?) \:(.+)/) { # Hook for modules that want all messages foreach $module (@modules) { if( $module->can('notice') ) { $module->notice($1, $2, $3, $4, $modchan, $botnick, $5); } } return; }

# Process generic JOIN actions if (/^\:(.+?)!(.+?)@(.+?) JOIN \:(.+)/) {

# Parse regex results $join{from} = $1; $join{user} = $2; $join{host} = $3; $join{rcpt} = $4; $join{text} = $5; $args = $join{text};

$from = $join{from}; $uname = $join{user}; $host = $join{host}; $from_chan = $join{rcpt};

# Hook for modules that want join actions foreach $module (@modules) { if( $module->can('join') ) { $module->join($from, $uname, $host, $from_chan, $modchan, $botnick); } } return; }

# Process autojoin actions for modchan if($botstatus == 1){ if (/^\:(.+?)!(.+?)@(.+?) JOIN \:$modchan/) { $join{from} = $1; $join{user} = $2; $join{host} = $3; $join{rcpt} = $4; $join{text} = $5; $args = $join{text}; $from = $join{from}; $send_host = $join{host};

if ($op_all == 1) { snd("MODE $modchan +o $1"); } else { foreach $aop (@aop) { chomp($aop); if ($aop eq $3) { snd("MODE $modchan +o $1"); logts("AOPped $1\n"); } } }

if ($hop_all == 1) { snd("MODE $modchan +h $1"); } else { foreach $ahop (@ahop) { chomp($ahop); if ($ahop eq $3) { snd("MODE $modchan +h $1"); logts("AHOPped $1\n"); } } }

if ($voice_all == 1) { snd("MODE $modchan +v $1"); } else { foreach $av (@av) { chomp($av); if ($av eq $3) { snd("MODE $modchan +v $1"); logts("AVoiced $1\n"); } } }

foreach $ak (@ak) { chomp($ak); if ($ak eq $3) { snd("KICK $modchan $1"); logts("AKicked $1\n"); } } return; } }

# Process messages if (/^\:(.+?)!(.+?)@(.+?) PRIVMSG (.+?) \:(.+)/) { $privmsg{from} = $1; $privmsg{user} = $2; $privmsg{host} = $3; $privmsg{rcpt} = $4; $privmsg{text} = $5; $args = $privmsg{text};

$from = $privmsg{from}; $uname = $privmsg{user}; $host = $privmsg{host}; $from_chan = $privmsg{rcpt};

# Log data for seen log if($args !~ /\a/) { $seenlog{lc $from} = $args; $seentime{lc $from} = time; debug("$from_chan <$from> $args\n"); } else { debug("Ignored term bell from $from for seen log.\n"); }

# Parse commands if($args =~ /^!version/) { &version; } elsif($args =~ /^!uptime /) { &uptime; } elsif($args =~ /^!seen /) { &seen; } elsif($args =~ /^!help/) { &help; } elsif($args =~ /^!loaded/) { &loaded; } elsif($args =~ /^!available/) { &available; } elsif($args =~ /^!load /) { if($public_modules == 1) { &loadmodule; } } elsif($args =~ /^!unload /) { if($public_modules == 1) { &unloadmodule; } } elsif($args =~ /^!reload /) { if($public_modules == 1) { &unloadmodule; &loadmodule; } } elsif($args =~ /^!\w/) { &pubcmd; } else { # Hook for modules that want all messages foreach $module (@modules) { if( $module->can('mesg') ) { $module->mesg($from, $uname, $host, $from_chan, $modchan, $botnick, $args); } } }

# Operator commands foreach $oper (@opers) { if ($oper eq $host) { if($args =~ /^!load /) { if($public_modules == 0) { &loadmodule; } } elsif($args =~ /^!unload /) { if($public_modules == 0) { &unloadmodule } } elsif($args =~ /^!reload /) { if($public_modules == 0) { &unloadmodule; &loadmodule; } } elsif($args =~ /^!raw /) { &raw; } elsif($args =~ /^!msg /) { &mesg; } elsif($args =~ /^!quit/) { &botquit; } elsif($args =~ /^!join /) { &joinchan; } elsif($args =~ /^!part /) { &partchan; }

				elsif($args =~ /^!nick /) { &nick; }
				elsif($args =~ /^!op/) { &oper; }
				elsif($args =~ /^!deop/) { &deoper; }
				elsif($args =~ /^!hop/) { &halfoper; }	

elsif($args =~ /^!dehop/) { &dehalfoper; } elsif($args =~ /^!voice/) { &voice; }

				elsif($args =~ /^!devoice/) { &devoice; } 

elsif($args =~ /^!kick /) { &kick; }

				elsif($args =~ /^!ban /) { &ban; } 

elsif($args =~ /^!unban /) { &unban; } elsif($args =~ /^!topic /) { &topic; } elsif($args =~ /^!mode /) { &mode; } elsif($args =~ /^!loadlist /) { &loadlists; }

				elsif($args =~ /^!modchan/) { &modchan; } 

elsif($args =~ /^!bot/) { &botswitch; }

				elsif($args =~ /^!pubmods/) { &pubmods; }
				elsif($args =~ /^!admin/) { &admin; } 

elsif($args =~ /^!all /) { &all; }

				elsif($args =~ /^!none /) { &none; }
				elsif($args =~ /^!add /) { &add; }
				elsif($args =~ /^!\w/) { &admincmd; }

} } } }

          1. Meta subroutine for initial join ######

sub login { debug("Entered initial join loop.\n");

# Attempt nickserv login &nickserv;

# Join all listed channels &joinlist;

# We've done login and join, no need to do it again next time $login = 1; }

          1. NickServ AUTH ######

sub nickserv{ if ($nsp) { logts("Identifying nick ..... "); msg("NickServ", "identify $nsp"); logts("[OK]\n"); } }

          1. Join listed channels #####

sub joinlist { logts("Joining channel(s) ... "); foreach $chan (@channels) { snd("JOIN $chan"); } logts("[OK]\n");

# Also call autoload modules now &autoload; }

          1. Attempt to autoload specified modules #####

sub autoload { foreach $loadme (@autoload) { &autoloadmodule($loadme); } }

          1.  !version #####

sub version { debug("Received \"version\"-command.\n"); ntc("$from", "Running version: $version"); my $uptime = &diffString(time - $startup); ntc("$from", "Uptime: $uptime"); logts("Sending version to $from.\n"); }

          1.  !seen #####

sub seen { if($botstatus == 1) { debug("Received \"seen\"-command.\n"); if(!substr($args, 6)) { ntc("$from", "No user was specified!"); } else { $usr = substr($args, 6); $usr =~ s/\s+$//;

if( lc $usr eq lc $botnick ) { msg("$from_chan", "$wisecrack_seen_botnick"); } elsif( lc $usr eq lc $from ) { msg("$from_chan", "$wisecrack_seen_self"); } else { # Check if we have a log for this user my $seen = 0; for my $key (keys(%seenlog)) { if ($key eq lc $usr) { $seen = 1; } }

if ($seen == 1) { my $diff = &diffString(time - $seentime{lc $usr}); msg("$from_chan", "$usr was last seen $diff ago saying: "); msg("$from_chan", "$seenlog{lc $usr}"); logts("Sending seen info for $usr\n"); debug("$seenlog{lc $usr}"); } else { my $uptime = &diffString(time - $startup); ntc("$from", "No log for $usr"); ntc("$from", "Log goes back $uptime"); logts("No log entry for $usr found\n"); } } } } }

          1. Translate difference in seconds to human readable string #####

sub diffString { ($s,$m,$h,$d,$mo) = gmtime( $_[0] );

if( $mo > 0 ) { $returnstring = "$mo months, $d days, $h hours, $m minutes and $s seconds"; } else { $d--; if( $d > 0 ) { $returnstring = "$d days, $h hours, $m minutes and $s seconds"; } else { if( $h > 0 ) { $returnstring = "$h hours, $m minutes and $s seconds"; } else { if( $m > 0 ) { $returnstring = "$m minutes and $s seconds"; } else { $returnstring = "$s seconds"; } } } } }

          1.  !help #####

sub help { if (substr($args, 6) eq "yes") { debug("Received \"help\"-command.\n");

ntc("$from", "Help for $botnick version $version."); ntc("$from", " "); ntc("$from", "�Public commands:�"); ntc("$from", "!help Get this help."); ntc("$from", "!version Get version number."); ntc("$from", "!seen [user] Get the last thing a user said."); ntc("$from", " "); ntc("$from", "�Oper only commands:�"); ntc("$from", "!quit [message] Stop bot."); ntc("$from", "!join [channel] Join channel."); ntc("$from", "!part [channel] Part channel."); ntc("$from", "!topic New topic."); ntc("$from", "!mode [user/chan] +/-mode"); ntc("$from", "!nick [botnick] Change the bots nickname."); ntc("$from", "!loadlist Load auto-lists."); ntc("$from", "!modchan [channel] Set active channel. Returms current active channel when none is given."); ntc("$from", "!bot [on|off] Switch bot on or off."); ntc("$from", "!all [op|hop|voice] Give status to every user to enter the channel."); ntc("$from", "!none [op|hop|voice] Stop the !all command."); ntc("$from", "!add [op|hop|voice|kick] [hostmask] Add hostmask to auto-list."); ntc("$from", "![op|deop|hop|dehop|voice|devoice|kick] [nick] Preform direct action."); ntc("$from", "![ban|unban] [hostmask] Ban hosts from the active channel."); ntc("$from", "!admin [add|del] [hostmask] Control admin access to the bot. (No args returns current list)"); ntc("$from", "!raw [data] Send raw commands to the IRC server."); ntc("$from", " "); ntc("$from", "�Module commands:�"); ntc("$from", "![load|unload|reload] [module] Load / unload / reload a module."); ntc("$from", "!loaded List currently loaded modules."); ntc("$from", "!available List all available modules."); ntc("$from", "!pubmods [on|off] Switch public usage of modules on or off."); ntc("$from", "!module.function Call a loaded modules functions.");

logts("Sent help to $from.\n"); } else { ntc("$from", "This command sends about 30 lines of notices."); ntc("$from", "Use \"!help yes\" if you are sure you want to do this."); } }

          1.  !raw #####

sub raw { debug("Received \"raw\"-command.\n"); my ($cmd,@data) = split(/ /, $args); snd("@data"); logts("Raw command was used by $from.\n"); }

          1.  !msg #####

sub mesg { debug("Received \"msg\"-command.\n"); my ($cmd, $to, @data) = split(/ /, $args); snd("PRIVMSG $to :@data"); logts("Msg command was used by $from.\n"); }

          1.  !join #####

sub joinchan { debug("Received \"join\"-command.\n"); if(!substr($args, 5)) { ntc("$from", "No channel was specified!"); } else { $chan = substr($args, 5); snd("JOIN $chan"); logts("Joining $chan...\n"); } }

          1.  !part #####

sub partchan { debug("Received \"part\"-command.\n"); if(!substr($args, 5)) { ntc("$from", "No channel was specified!"); } else { $chan = substr($args, 5); snd("PART $chan"); logts("Parting $chan...\n"); } }

          1.  !nick #####

sub nick { debug("Received \"nick\"-command.\n"); if(!substr($args, 5)) { ntc("$from", "No new nick was specified!"); } else { $botnick = substr($args, 5); snd("NICK $botnick"); logts("Changed bot nick to $botnick...\n"); } }

          1.  !modchan #####

sub modchan { debug("Received \"modchan\"-command.\n"); if(!substr($args, 9)) { debug("command was blank.\n"); ntc("$from", "Current active channel is: $modchan"); } else { $modchan = substr($args, 9); ntc("$from", "Setting active channel to $modchan..."); logts("Setting active channel to $modchan...\n"); } }

          1.  !bot #####

sub botswitch { debug("Received \"bot\"-command.\n"); if (!substr($args, 5)) { if($botstatus) { ntc("$from", "Bot is enabled."); } else { ntc("$from", "Bot is disabled."); } } else { $mode = substr($args, 5); if ($mode =~ /on/) { $botstatus = 1; msg("$modchan", "Bot enabled."); logts("Bot enabled by $from...\n"); } else { if ($mode =~ /off/) { $botstatus = 0; msg("$modchan", "Bot disabled."); logts("Bot disabled by $from...\n"); } } } }

          1.  !loaded #####

sub loaded { snd("NOTICE $from :Loaded modules: @modules"); }

          1.  !available ######

sub available { @available = <$moddir/*.pm>; my $i = 0; foreach $avail (@available) { my ($dir, $filename) = split(/\//, $avail); my ($modname, $ext) = split(/\./, $filename); $available[$i] = $modname; $i++; } snd("NOTICE $from :Available modules: @available"); }

          1.  !load #####

sub loadmodule { debug("Received \"load\"-command.\n"); my ($cmd,$module,@data) = split(/ /, $args);

$i = 0; $found = 0; while($i <= @modules){ if($modules[$i] eq $module){ $found = 1; } $i++; }

if( (-e "$moddir/$module.pm") && ( $found == 0 ) ) { my $retval = system( "perl -c $moddir/$module.pm" ); if( $retval == 0 ) { load "$moddir/$module.pm"; push(@modules,$module); ntc("$from", "Inserted: $module"); logts("Module $module loaded by $from.\n"); } else { ntc("$from", "Could not load module: $module (Not valid Perl)"); } } else { if( $found == 1 ) { ntc("$from", "Could not load module: $module (Module is already loaded)"); } else { ntc("$from", "Could not load module: $module (Cannot find module)"); } logts("Module $module loaded by $from FAILED.\n"); } }

          1. autoload modules #####

sub autoloadmodule { debug("Attempting to load module $_[0].\n"); logts("Loading module ....... "); $module = $_[0];

$i = 0; $found = 0; while($i <= @modules){ if($modules[$i] eq $module){ $found = 1; } $i++; }

if( (-e "$moddir/$module.pm") && ( $found == 0 ) ) { my $retval = system( "perl -c $moddir/$module.pm 2> $moddir/temp" ); unlink "$moddir/temp"; if( $retval == 0 ) { load "$moddir/$module.pm"; push(@modules,$module); logts("[$module OK]\n"); } else { logts("[$module FAILED] (not valid perl)\n"); } } else { if( $found == 1 ) { logts("[$module FAILED] (already loaded)\n"); } else { logts("[$module FAILED] (not found)\n"); } } }

          1.  !unload #####

sub unloadmodule { debug("Received \"unload\"-command.\n"); my ($cmd,$module,@data) = split(/ /, $args);

$i = 0; $found = 0; while($i <= @modules){ if($modules[$i] eq $module){ $found = 1; delete $INC{"$moddir/$module.pm"}; delete $modules[$i]; splice(@modules, $i ,1); } $i++; }

if( $found == 1 ) { ntc("$from", "Unloaded module: $module"); logts("Module $module unloaded by $from.\n"); } else { ntc("$from", "Could not unload module: $module (Module doesn't appear to be loaded)"); logts("Module $module unload by $from FAILED.\n"); } }

          1.  !pubmods #####

sub pubmods { debug("Received \"pubmods\"-command.\n"); if (!substr($args, 9)) { if($botstatus) { ntc("$from", "Public modules are enabled."); } else { ntc("$from", "Public modules are disabled."); } } else { $mode = substr($args, 5); if ($mode =~ /on/) { $public_modules = 1; msg("$modchan", "Public modules enabled."); logts("Public modules enabled by $from...\n"); } else { if ($mode =~ /off/) { $public_modules = 0; msg("$modchan", "Pulbic modules disabled."); logts("Public modules disabled by $from...\n"); } } } }

          1. Public module commands #####

sub pubcmd { my($command, @data) = split(/ /,$args); $command = substr($command, 1); my($mod, $cmd) = split(/\./,$command);

if(($mod =~ /^.+/) && ($cmd =~ /^.+/)) { $i = 0; while($i <= @modules){ if(($modules[$i] eq $mod) && ( $mod->can($cmd) )){ if( $public_modules == 1) { $mod->$cmd($from, $uname, $host, $from_chan, $modchan, $botnick, @data); } elsif( $mod->can('public') ){ @functions = $mod->public(); foreach $function (@functions) { if( ($function eq $cmd) ) { $mod->$cmd($from, $uname, $host, $from_chan, $modchan, $botnick, @data); } } } } $i++; } } elsif((($mod =~ /^.+/) && ($cmd !~ /^.+/)) && ( $mod->can('help') )) { $mod->help($from, $uname, $host, $from_chan, $modchan, $botnick, @data); } }

          1. Admin module commands #####

sub admincmd { my($command, @data) = split(/ /,$args); $command = substr($command, 1); my($mod, $cmd) = split(/\./,$command);

if(($mod =~ /^.+/) && ($cmd =~ /^.+/)) { $i = 0; while($i <= @modules){ if(($modules[$i] eq $mod) && ( $mod->can($cmd) )){ if( $mod->can('public') ) { @functions = $mod->public(); my $notPublic = 1; foreach $function (@functions) { if( ($function eq $cmd) ) { $notPublic = 0; } } if( $notPublic == 1 && $public_modules == 0 ) { $mod->$cmd($from, $uname, $host, $from_chan, $modchan, $botnick, @data); } } elsif ( $public_modules == 0) { $mod->$cmd($from, $uname, $host, $from_chan, $modchan, $botnick, @data); } } $i++; } } }

          1.  !loadlist #####

sub loadlists { debug("Received \"loadlist\"-command.\n"); debug("Using data directory \"$datadir\".\n");

open AOPLIST, "<$datadir/aop"; @aop = <AOPLIST>; close(AOPLIST); debug("AOP list loaded.\n");

open AHOPLIST, "<$datadir/ahop"; @ahop = <AHOPLIST>; close(AHOPLIST); debug("AHOP list loaded.\n");

open AVLIST, "<$datadir/av"; @av = <AVLIST>; close(AVLIST); debug("AVOICE list loaded.\n");

open AKLIST, "<$datadir/ak"; @ak = <AKLIST>; close(AKLIST); debug("AKICK list loaded.\n");

msg("$modchan", "Lists loaded."); logts("Loaded the lists...\n"); }

          1.  !add #####

sub add { debug("Received \"add\"-command "); my ($msg,$type,$toadd) = split(/ /, $args); debug("of type $type.\n");

if($type =~ /^op/) { open AOPLIST, ">>$datadir/aop"; print AOPLIST "$toadd\n"; close(AOPLIST); msg("$modchan", "$toadd added to auto-op list."); } elsif($type =~ /^hop/) { open AHOPLIST, ">>$datadir/ahop"; print AHOPLIST "$toadd\n"; close(AHOPLIST); msg("$modchan", "$toadd added auto-half-op list.."); } elsif($type =~ /^voice/) { open AVLIST, ">>$datadir/av"; print AVLIST "$toadd\n"; close(AVLIST); ntc("$modchan", "$toadd added auto-voice list."); } elsif($type =~ /^kick/) { open AKLIST, ">>$datadir/ak"; print AKLIST "$toadd\n"; close(AKLIST); ntc("$modchan", "$toadd added auto-kick list."); } }

          1.  !op #####

sub oper { debug("Received \"op\"-command.\n"); if(!substr($args, 4)) { snd("MODE $from_chan +o $from"); logts("Opered $from...\n"); } else { $user = substr($args, 4); snd("MODE $from_chan +o $user"); logts("Opered $user...\n"); } }

          1.  !deop #####

sub deoper { debug("Received \"deop\"-command.\n"); if(!substr($args, 6)) { snd("MODE $from_chan -o $from"); logts("Deopered $from...\n"); } else { $user = substr($args, 6); snd("MODE $from_chan -o $user"); logts("Deopered $user...\n"); } }

          1.  !hop #####

sub halfoper{ debug("Received \"hop\"-command.\n"); if(!substr($args, 5)) { snd("MODE $from_chan +h $from"); logts("Half-opered $from...\n"); } else { $user = substr($args, 5); snd("MODE $from_chan +h $user"); logts("Half-opered $user...\n"); } }

          1.  !dehop #####

sub dehalfoper { debug("Received \"dehop\"-command.\n"); if(!substr($args, 7)) { snd("MODE $from_chan -h $from"); logts("Dehalf-opered $from...\n"); } else { $user = substr($args, 7); snd("MODE $from_chan -h $user"); logts("Dehalf-opered $user...\n"); } }

          1.  !voice #####

sub voice { debug("Received \"voice\"-command.\n"); if(!substr($args, 6)) { snd("MODE $from_chan +v $from"); logts("Voiced $from...\n"); } else { $user = substr($args, 6); snd("MODE $from_chan +v $user"); logts("Voiced $user...\n"); } }

          1.  !devoice #####

sub devoice { debug("Received \"devoice\"-command.\n"); if(!substr($args, 8)) { snd("MODE $from_chan -v $from"); logts("Devoiced $from...\n"); } else { $user = substr($args, 8); snd("MODE $from_chan -v $user"); logts("Devoiced $user...\n"); } }

          1.  !all #####

sub all { debug("Received \"all\"-command "); my ($msg,$type) = split(/ /, $args); debug("of type $type.\n");

if($type =~ /^op/) { msg("$modchan", "Global Oper for $modchan users enabled."); $op_all = 1; logts("Enabled Op all on $modchan by $from.\n"); } elsif($type =~ /^hop/) { msg("$modchan", "Global Half-op for $modchan users enabled."); $hop_all = 1; logts("Enabled Half-Op all on $modchan by $from.\n"); } elsif($type =~ /^voice/) { msg("$modchan", "Global Voice for $modchan users enabled."); $voice_all = 1; logts("Enabled Voice all on $modchan by $from.\n"); } }

          1.  !none #####

sub none { debug("Received \"none\"-command "); my ($msg,$type) = split(/ /, $args); debug("of type $type.\n");

if($type =~ /^op/) { msg("$modchan", "Global Oper for $modchan users disabled."); $op_all = 0; logts("Enabled Op all on $modchan by $from.\n"); } elsif($type =~ /^hop/) { msg("$modchan", "Global Half-op for $modchan users disabled."); $hop_all = 0; logts("Enabled Half-Op all on $modchan by $from.\n"); } elsif($type =~ /^voice/) { msg("$modchan", "Global Voice for $modchan users disabled."); $voice_all = 0; logts("Enabled Voice all on $modchan by $from.\n"); } }

          1.  !kick #####

sub kick { debug("Received \"kick\"-command.\n"); if(!substr($args, 5)) { ntc("$from", "Commmand requires username to kick."); } else { $user = substr($args, 5);

  	 	snd("KICK $from_chan $user (Requested.)");

logts("Kicked $user...\n"); } }

          1.  !ban #####

sub ban { debug("Received \"ban\"-command.\n"); if(!substr($args, 5)) { ntc("$from", "Command requires something to ban."); } else { $hostmask = substr($args, 5); snd("MODE $from_chan +b $hostmask"); logts("Banned $hostmask...\n"); } }

          1.  !unban #####

sub unban { debug("Received \"unban\"-command.\n"); if(!substr($args, 7)) { ntc("$from", "Command requires hostname to unban."); } else { $hostmask = substr($args, 7); snd("MODE $from_chan -b $hostmask"); logts("Unanned $hostmask...\n"); } }

          1.  !topic #####

sub topic { debug("Received \"topic\"-command.\n"); if(!substr($args, 7)) { ntc("$from", "No new topic specified."); } else { $new_topic = substr($args, 7); snd("TOPIC $from_chan :$new_topic"); logts("Set topic for $from_chan set to $new_topic\n"); } }

          1.  !mode #####

sub mode { debug("Received \"mode\"-command.\n"); if(!substr($args, 6)) { ntc("$from", "No arguments specified."); } else { $modes = substr($args, 6); snd("MODE $modes"); logts("Set modes $modes\n"); } }

          1.  !admin #####

sub admin { debug("Received \"admin\"-command.\n"); my ($msg,$type,$hostm) = split(/ /, $args);

if ($type =~ /add/) { push(@opers,$hostm); ntc("$from", "Added $hostm to temp admin list."); logts("Added temp admin $hostm by $from\n"); debug("Oper list: ");

foreach $oper (@opers) { debug("$oper "); }

debug("\n"); } elsif ($type =~ /del/) { $i = 0; while($i <= @opers){ if($opers[$i] eq $hostm){ while($i < @opers){ $opers[$i] = $opers[$i+1]; $i++; } } $i++; } ntc("$from", "Removed $hostm from temp admin list."); logts("Removed temp admin $hostm by $from\n"); debug("Oper list: ");

foreach $oper (@opers) { debug("$oper "); } debug("\n");

} else { snd("NOTICE $from :Current admins: @opers"); } }

          1.  !quit #####

sub botquit { debug("Received \"quit\"-command.\n"); logts("Quit command was issued by $from.\n");

my ($cmd,@msg) = split(/ /, $args);

if($msg[0] eq "") { snd("QUIT $botnick was instructed to quit."); } else { snd("QUIT @msg"); }

close($sock); &shutd; }

          1. Process exit subroutine #####

sub shutd { logts("Shutting down.\n"); debug("Final line of code before exit call.\n"); exit(0); }